SNAP Library 2.0, Developer Reference
2013-05-13 16:33:57
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
|
00001 namespace TSnap { 00002 00004 // Node centrality measures 00005 double GetDegreeCentr(const PUNGraph& Graph, const int& NId) { 00006 if (Graph->GetNodes() > 1) { 00007 return double(Graph->GetNI(NId).GetDeg())/double(Graph->GetNodes()-1); } 00008 else { return 0.0; } 00009 } 00010 00011 double GetFarnessCentr(const PUNGraph& Graph, const int& NId) { 00012 TIntH NDistH(Graph->GetNodes()); 00013 TSnap::GetShortPath<PUNGraph>(Graph, NId, NDistH, true, TInt::Mx); 00014 double sum = 0; 00015 for (TIntH::TIter I = NDistH.BegI(); I < NDistH.EndI(); I++) { 00016 sum += I->Dat(); 00017 } 00018 if (NDistH.Len() > 1) { return sum/double(NDistH.Len()-1); } 00019 else { return 0.0; } 00020 } 00021 00022 double GetClosenessCentr(const PUNGraph& Graph, const int& NId) { 00023 const double Farness = GetFarnessCentr(Graph, NId); 00024 if (Farness != 0.0) { return 1.0/Farness; } 00025 else { return 0.0; } 00026 } 00027 00028 void GetBetweennessCentr(const PUNGraph& Graph, const TIntV& BtwNIdV, TIntFltH& NodeBtwH, const bool& DoNodeCent, TIntPrFltH& EdgeBtwH, const bool& DoEdgeCent) { 00029 if (DoNodeCent) { NodeBtwH.Clr(); } 00030 if (DoEdgeCent) { EdgeBtwH.Clr(); } 00031 const int nodes = Graph->GetNodes(); 00032 TIntS S(nodes); 00033 TIntQ Q(nodes); 00034 TIntIntVH P(nodes); // one vector for every node 00035 TIntFltH delta(nodes); 00036 TIntH sigma(nodes), d(nodes); 00037 // init 00038 for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { 00039 if (DoNodeCent) { 00040 NodeBtwH.AddDat(NI.GetId(), 0); } 00041 if (DoEdgeCent) { 00042 for (int e = 0; e < NI.GetOutDeg(); e++) { 00043 if (NI.GetId() < NI.GetOutNId(e)) { 00044 EdgeBtwH.AddDat(TIntPr(NI.GetId(), NI.GetOutNId(e)), 0); } 00045 } 00046 } 00047 sigma.AddDat(NI.GetId(), 0); 00048 d.AddDat(NI.GetId(), -1); 00049 P.AddDat(NI.GetId(), TIntV()); 00050 delta.AddDat(NI.GetId(), 0); 00051 } 00052 // calc betweeness 00053 for (int k=0; k < BtwNIdV.Len(); k++) { 00054 const TUNGraph::TNodeI NI = Graph->GetNI(BtwNIdV[k]); 00055 // reset 00056 for (int i = 0; i < sigma.Len(); i++) { 00057 sigma[i]=0; d[i]=-1; delta[i]=0; P[i].Clr(false); 00058 } 00059 S.Clr(false); 00060 Q.Clr(false); 00061 sigma.AddDat(NI.GetId(), 1); 00062 d.AddDat(NI.GetId(), 0); 00063 Q.Push(NI.GetId()); 00064 while (! Q.Empty()) { 00065 const int v = Q.Top(); Q.Pop(); 00066 const TUNGraph::TNodeI NI2 = Graph->GetNI(v); 00067 S.Push(v); 00068 const int VDat = d.GetDat(v); 00069 for (int e = 0; e < NI2.GetOutDeg(); e++) { 00070 const int w = NI2.GetOutNId(e); 00071 if (d.GetDat(w) < 0) { // find w for the first time 00072 Q.Push(w); 00073 d.AddDat(w, VDat+1); 00074 } 00075 //shortest path to w via v ? 00076 if (d.GetDat(w) == VDat+1) { 00077 sigma.AddDat(w) += sigma.GetDat(v); 00078 P.GetDat(w).Add(v); 00079 } 00080 } 00081 } 00082 while (! S.Empty()) { 00083 const int w = S.Top(); 00084 const double SigmaW = sigma.GetDat(w); 00085 const double DeltaW = delta.GetDat(w); 00086 const TIntV NIdV = P.GetDat(w); 00087 S.Pop(); 00088 for (int i = 0; i < NIdV.Len(); i++) { 00089 const int nid = NIdV[i]; 00090 const double c = (sigma.GetDat(nid)*1.0/SigmaW) * (1+DeltaW); 00091 delta.AddDat(nid) += c; 00092 if (DoEdgeCent) { 00093 EdgeBtwH.AddDat(TIntPr(TMath::Mn(nid, w), TMath::Mx(nid, w))) += c; } 00094 } 00095 if (DoNodeCent && w != NI.GetId()) { 00096 NodeBtwH.AddDat(w) += delta.GetDat(w)/2.0; } 00097 } 00098 } 00099 } 00100 00101 // Approximate beetweenness centrality scores. The implementation scales to large networks. 00102 // NodeFrac ... calculate Beetweenness Centrality for a fraction of nodes. Gives approximate. 00103 void GetBetweennessCentr(const PUNGraph& Graph, TIntFltH& NodeBtwH, const double& NodeFrac) { 00104 TIntPrFltH EdgeBtwH; 00105 TIntV NIdV; Graph->GetNIdV(NIdV); 00106 if (NodeFrac < 1.0) { // calculate beetweenness centrality for a subset of nodes 00107 NIdV.Shuffle(TInt::Rnd); 00108 for (int i = int((1.0-NodeFrac)*NIdV.Len()); i > 0; i--) { 00109 NIdV.DelLast(); } 00110 } 00111 GetBetweennessCentr(Graph, NIdV, NodeBtwH, true, EdgeBtwH, false); 00112 } 00113 00114 void GetBetweennessCentr(const PUNGraph& Graph, TIntPrFltH& EdgeBtwH, const double& NodeFrac) { 00115 TIntFltH NodeBtwH; 00116 TIntV NIdV; Graph->GetNIdV(NIdV); 00117 if (NodeFrac < 1.0) { // calculate beetweenness centrality for a subset of nodes 00118 NIdV.Shuffle(TInt::Rnd); 00119 for (int i = int((1.0-NodeFrac)*NIdV.Len()); i > 0; i--) { 00120 NIdV.DelLast(); } 00121 } 00122 GetBetweennessCentr(Graph, NIdV, NodeBtwH, false, EdgeBtwH, true); 00123 } 00124 00125 void GetBetweennessCentr(const PUNGraph& Graph, TIntFltH& NodeBtwH, TIntPrFltH& EdgeBtwH, const double& NodeFrac) { 00126 TIntV NIdV; Graph->GetNIdV(NIdV); 00127 if (NodeFrac < 1.0) { // calculate beetweenness centrality for a subset of nodes 00128 NIdV.Shuffle(TInt::Rnd); 00129 for (int i = int((1.0-NodeFrac)*NIdV.Len()); i > 0; i--) { 00130 NIdV.DelLast(); } 00131 } 00132 GetBetweennessCentr(Graph, NIdV, NodeBtwH, true, EdgeBtwH, true); 00133 } 00134 00135 void GetEigenVectorCentr(const PUNGraph& Graph, TIntFltH& NIdEigenH, const double& Eps, const int& MaxIter) { 00136 const int NNodes = Graph->GetNodes(); 00137 NIdEigenH.Gen(NNodes); 00138 // initialize vector values 00139 for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { 00140 NIdEigenH.AddDat(NI.GetId(), 1.0/NNodes); 00141 IAssert(NI.GetId() == NIdEigenH.GetKey(NIdEigenH.Len()-1)); 00142 } 00143 TFltV TmpV(NNodes); 00144 for (int iter = 0; iter < MaxIter; iter++) { 00145 int j = 0; 00146 // add neighbor values 00147 for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++, j++) { 00148 TmpV[j] = 0; 00149 for (int e = 0; e < NI.GetOutDeg(); e++) { 00150 TmpV[j] += NIdEigenH.GetDat(NI.GetOutNId(e)); } 00151 } 00152 00153 // normalize 00154 double sum = 0; 00155 for (int i = 0; i < TmpV.Len(); i++) { 00156 sum += (TmpV[i]*TmpV[i]); 00157 } 00158 sum = sqrt(sum); 00159 for (int i = 0; i < TmpV.Len(); i++) { 00160 TmpV[i] /= sum; 00161 } 00162 00163 // compute difference 00164 double diff = 0.0; 00165 j = 0; 00166 for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++, j++) { 00167 diff += fabs(NIdEigenH.GetDat(NI.GetId())-TmpV[j]); 00168 } 00169 00170 // set new values 00171 j = 0; 00172 for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++, j++) { 00173 NIdEigenH.AddDat(NI.GetId(), TmpV[j]); 00174 } 00175 00176 if (diff < Eps) { 00177 break; 00178 } 00179 } 00180 } 00181 00182 }; // namespace TSnap