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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
centr.cpp
Go to the documentation of this file.
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