-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpdpagerank.cpp
108 lines (92 loc) · 2.9 KB
/
pdpagerank.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Paradoxial Discounted Page Rank
#include "stdafx.h"
int main(int argc, char* argv[]) {
Env = TEnv(argc, argv, TNotify::StdNotify);
Env.PrepArgs(TStr::Fmt("Paradioxial Discounted PageRank. Build: %s, %s. Time: %s", __TIME__, __DATE__, TExeTm::GetCurTm()));
TExeTm ExeTm;
Try
const TStr Iput = Env.GetIfArgPrefixStr("-i:", "Input.txt", "Input File" );
const TStr Oput = Env.GetIfArgPrefixStr("-o:", "Output.txt", "Output File");
FILE* fpI = fopen(Iput.CStr(), "r");
FILE* fpO = fopen(Oput.CStr(), "w");
const double C = 0.85;
const int MaxIter = 50;
const double Eps = 1e-9;
PNGraph Graph = TSnap::LoadEdgeList< PNGraph > (Iput);
fprintf(fpO, "\nNodes: %d, Edges: %d\n\n", Graph->GetNodes(), Graph->GetEdges());
const int NNodes = Graph->GetNodes();
const double OneOver = (double) 1.0 / (double) NNodes;
TIntFltH PRankH, PDiscountH;
PRankH.Gen(NNodes);
PDiscountH.Gen(NNodes); // this will store the paradoxical discount scores
double MaxPD = 0;
// compute paradoxical_discounted for all nodes
for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++)
{
int Id = NI.GetId();
int OutDeg = NI.GetOutDeg();
int InDeg = NI.GetInDeg();
PRankH.AddDat(Id, OneOver);
if (InDeg > OutDeg)
{
double ratio = double(InDeg) / double(OutDeg);
MaxPD = max(ratio, MaxPD);
PDiscountH.AddDat(Id, ratio);
}
else
{
int Rec = 0;
for (int e = 0; e < OutDeg; e++)
{
int OutNId = NI.GetOutNId(e);
if (NI.IsInNId(OutNId))
++Rec;
}
double ratio = double(InDeg - Rec) / double(OutDeg - Rec);
MaxPD = max(ratio, MaxPD);
PDiscountH.AddDat(Id, ratio);
}
}
TFltV TmpV(NNodes);
for (int iter = 1; iter < MaxIter; iter++)
{
int j = 0;
for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++, j++)
{
TmpV[j] = 0;
for (int e = 0; e < NI.GetInDeg(); e++)
{
const int InNId = NI.GetInNId(e);
const int OutDeg = Graph->GetNI(InNId).GetOutDeg();
if (OutDeg > 0)
{
double ratio = (double) PRankH.GetDat(InNId) / (double) OutDeg;
ratio = ratio * PDiscountH.GetDat(InNId) / MaxPD;
TmpV[j] += ratio;
}
}
TmpV[j] = C * TmpV[j];
}
double diff = 0, sum = 0, NewVal;
for (int i = 0; i < TmpV.Len(); i++)
sum += TmpV[i];
const double Leaked = (double) (1.0 - sum) / (double) NNodes;
for (int i = 0; i < PRankH.Len(); i++)
{
NewVal = TmpV[i] + Leaked;
diff += fabs(NewVal - PRankH[i]);
PRankH[i] = NewVal;
}
if (diff < Eps)
break;
} // end for each iteration
fprintf(fpO, "Node ID\t\tParadox PageRank\n");
for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++){
int Id = NI.GetId();
const double pr = PRankH.GetDat(Id);
fprintf(fpO, "%d\t\t\t%.5f\n", Id, pr);
}
Catch
printf("\nRun Time: %s (%s)\n", ExeTm.GetTmStr(), TSecTm::GetCurTm().GetTmStr().CStr());
return 0;
}