SNAP Library, Developer Reference  2012-10-02 12:56:23
SNAP, a general purpose network analysis and graph mining library
 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   for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
00139     NIdEigenH.AddDat(NI.GetId(), 1.0/NNodes);
00140     IAssert(NI.GetId() == NIdEigenH.GetKey(NIdEigenH.Len()-1));
00141   }
00142   TFltV TmpV(NNodes);
00143   double diff = TFlt::Mx;
00144   for (int iter = 0; iter < MaxIter; iter++) {
00145     int j = 0;
00146     for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++, j++) {
00147       TmpV[j] = 0;
00148       for (int e = 0; e < NI.GetOutDeg(); e++) {
00149         TmpV[j] += NIdEigenH.GetDat(NI.GetOutNId(e)); }
00150     }
00151     double sum = 0;
00152     for (int i = 0; i < TmpV.Len(); i++) {
00153       NIdEigenH[i] = TmpV[i];
00154       sum += NIdEigenH[i];
00155     }
00156     for (int i = 0; i < NIdEigenH.Len(); i++) {
00157       NIdEigenH[i] /= sum; }
00158     if (fabs(diff-sum) < Eps) { break; }
00159     //printf("\tdiff:%f\tsum:%f\n", fabs(diff-sum), sum);
00160     diff = sum;
00161   }
00162 }
00163 
00164 }; // namespace TSnap