SNAP Library 2.2, Developer Reference
2014-03-11 19:15:55
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
|
00001 #ifndef yanglib_agmdirected_h 00002 #define yanglib_agmdirected_h 00003 #include "Snap.h" 00004 #include "agm.h" 00005 #include "agmfast.h" 00006 00007 class TCoda { //sparse AGM-fast with coordinate ascent for directed affiliation 00008 private: 00009 PNGraph G; //graph to fit 00010 TVec<TIntFltH> F; // outdegree membership for each user (Size: Nodes * Coms) 00011 TVec<TIntFltH> H; // in-degree membership for each user (Size: Nodes * Coms) A ~ F * H' 00012 TRnd Rnd; // random number generator 00013 TIntV NIDV; // original node ID vector 00014 TFlt RegCoef; //Regularization coefficient when we fit for P_c +: L1, -: L2 00015 TFltV SumFV; // sum_u F_uc for each community c. Needed for efficient calculation 00016 TFltV SumHV; // sum_u H_uc for each community c. Needed for efficient calculation 00017 TBool NodesOk; // Node ID is from 0 ~ N-1 00018 TInt NumComs; // number of communities 00019 TVec<TIntSet> HOVIDSV; //NID pairs to hold out for cross validation 00020 public: 00021 TFlt MinVal; // minimum value of F (0) 00022 TFlt MaxVal; // maximum value of F (for numerical reason) 00023 TFlt NegWgt; // weight of negative example (a pair of nodes without an edge) 00024 TFlt PNoCom; // base probability \varepsilon (edge probability between a pair of nodes sharing no community 00025 TBool DoParallel; // whether to use parallelism for computation 00026 00027 TCoda(const PNGraph& GraphPt, const int& InitComs, const int RndSeed = 0): Rnd(RndSeed), RegCoef(0), 00028 NodesOk(true), MinVal(0.0), MaxVal(1000.0), NegWgt(1.0) { SetGraph(GraphPt); RandomInit(InitComs); } 00029 TCoda() { G = TNGraph::New(); } 00030 void SetGraph(const PNGraph& GraphPt); 00031 PNGraph GetGraph() { return G; } 00032 PNGraph GetGraphRawNID(); 00033 void SetRegCoef(const double _RegCoef) { RegCoef = _RegCoef; } 00034 double GetRegCoef() { return RegCoef; } 00035 void RandomInit(const int InitComs); 00036 int GetNumComs() { return NumComs.Val; } 00037 void NeighborComInit(const int InitComs); 00038 void NeighborComInit(TFltIntPrV& NIdPhiV, const int InitComs); 00039 void SetCmtyVV(const TVec<TIntV>& CmtyVVOut, const TVec<TIntV>& CmtyVVIn); 00040 double Likelihood(const bool DoParallel = false); 00041 double LikelihoodForNode(const bool IsRow, const int UID); 00042 double LikelihoodForNode(const bool IsRow, const int UID, const TIntFltH& FU); 00043 void GetNonEdgePairScores(TFltIntIntTrV& ScoreV); 00044 void GetNIDValH(TIntFltH& NIdValInOutH, TIntFltH& NIdValOutH, TIntFltH& NIdValInH, const int CID, const double Thres); 00045 void DumpMemberships(const TStr& OutFNm, const TStrHash<TInt>& NodeNameH) { DumpMemberships(OutFNm, NodeNameH, sqrt(PNoCom)); } 00046 void DumpMemberships(const TStr& OutFNm, const TStrHash<TInt>& NodeNameH, const double Thres); 00047 void GetCmtyS(TIntSet& CmtySOut, TIntSet& CmtySIn, const int CID, const double Thres); 00048 void DumpMemberships(const TStr& OutFNm, const double Thres); 00049 void DumpMemberships(const TStr& OutFNm) { DumpMemberships(OutFNm, sqrt(PNoCom)); } 00050 void GetCommunity(TIntV& CmtyVIn, TIntV& CmtyVOut, const int CID) { GetCommunity(CmtyVIn, CmtyVOut, CID, sqrt(PNoCom)); } 00051 void GetCommunity(TIntV& CmtyVIn, TIntV& CmtyVOut, const int CID, const double Thres); 00052 void GetTopCIDs(TIntV& CIdV, const int TopK, const int IsAverage = 1, const int MinSz = 1); 00053 void GradientForNode(const bool IsRow, const int UID, TIntFltH& GradU, const TIntSet& CIDSet); 00054 void SetHoldOut(const double HOFrac) { TVec<TIntSet> HoldOut; TAGMFastUtil::GenHoldOutPairs(G, HoldOut, HOFrac, Rnd); HOVIDSV = HoldOut; } 00055 //double LikelihoodForRow(const int UID); 00056 //double LikelihoodForRow(const int UID, const TIntFltH& FU); 00057 //double LikelihoodForCol(const int VID); 00058 //double LikelihoodForCol(const int VID, const TIntFltH& HV); 00059 //void GradientForRow(const int UID, TIntFltH& GradU, const TIntSet& CIDSet); 00060 void GetCmtyVV(TVec<TIntV>& CmtyVVOut, TVec<TIntV>& CmtyVVIn, const int MinSz = 3); 00061 void GetCmtyVV(TVec<TIntV>& CmtyVVOut, TVec<TIntV>& CmtyVVIn, const double ThresOut, const double ThresIn, const int MinSz = 3); 00062 void GetCmtyVV(const bool IsOut, TVec<TIntV>& CmtyVV); 00063 void GetCmtyVV(const bool IsOut, TVec<TIntV>& CmtyVV, const double Thres, const int MinSz = 3); 00064 void GetCmtyVVUnSorted(const bool IsOut, TVec<TIntV>& CmtyVV, const double Thres, const int MinSz = 3); 00065 void GetCmtyVVUnSorted(TVec<TIntV>& CmtyVVOut, TVec<TIntV>& CmtyVVIn); 00066 //void GetCmtyVVIn(TVec<TIntV>& CmtyVV); 00067 //void GetCmtyVVIn(TVec<TIntV>& CmtyVV, const double Thres, const int MinSz = 3); 00068 int FindComsByCV(TIntV& ComsV, const double HOFrac = 0.2, const int NumThreads = 20, const TStr PlotLFNm = TStr(), const int EdgesForCV = 100, const double StepAlpha = 0.3, const double StepBeta = 0.1); 00069 int FindComsByCV(const int NumThreads, const int MaxComs, const int MinComs, const int DivComs, const TStr OutFNm, const int EdgesForCV = 100, const double StepAlpha = 0.3, const double StepBeta = 0.3); 00070 double LikelihoodHoldOut(const bool DoParallel = false); 00071 double GetStepSizeByLineSearch(const bool IsRow, const int UID, const TIntFltH& DeltaV, const TIntFltH& GradV, const double& Alpha, const double& Beta, const int MaxIter = 10); 00072 int MLEGradAscent(const double& Thres, const int& MaxIter, const TStr PlotNm, const double StepAlpha = 0.3, const double StepBeta = 0.1); 00073 int MLEGradAscentParallel(const double& Thres, const int& MaxIter, const int ChunkNum, const int ChunkSize, const TStr PlotNm, const double StepAlpha = 0.3, const double StepBeta = 0.1); 00074 int MLEGradAscentParallel(const double& Thres, const int& MaxIter, const int ChunkNum, const TStr PlotNm = TStr(), const double StepAlpha = 0.3, const double StepBeta = 0.1) { 00075 int ChunkSize = G->GetNodes() / 10 / ChunkNum; 00076 if (ChunkSize == 0) { ChunkSize = 1; } 00077 return MLEGradAscentParallel(Thres, MaxIter, ChunkNum, ChunkSize, PlotNm, StepAlpha, StepBeta); 00078 } 00079 //int MLENewton(const double& Thres, const int& MaxIter, const TStr PlotNm = TStr()); 00080 //double GradientForOneVar(const TFltV& AlphaKV, const int UID, const int CID, const double& Val); 00081 //double HessianForOneVar(const TFltV& AlphaKV, const int UID, const int CID, const double& Val); 00082 //double LikelihoodForOneVar(const TFltV& AlphaKV, const int UID, const int CID, const double& Val); 00083 //double FindOptimalThres(const TVec<TIntV>& TrueCmtyVV, TVec<TIntV>& CmtyVV); 00084 void Save(TSOut& SOut); 00085 void Load(TSIn& SIn, const int& RndSeed = 0); 00086 TFlt& GetSumVal(const bool IsOut, const int CID) { 00087 if (IsOut) { 00088 return SumFV[CID]; 00089 } else { 00090 return SumHV[CID]; 00091 } 00092 } 00093 double inline GetCom(const bool IsOut, const int& NID, const int& CID) { 00094 if (IsOut) { 00095 return GetComOut(NID, CID); 00096 } else { 00097 return GetComIn(NID, CID); 00098 } 00099 } 00100 double inline GetComOut(const int& NID, const int& CID) { 00101 if (F[NID].IsKey(CID)) { 00102 return F[NID].GetDat(CID); 00103 } else { 00104 return 0.0; 00105 } 00106 } 00107 double inline GetComIn(const int& NID, const int& CID) { 00108 if (H[NID].IsKey(CID)) { 00109 return H[NID].GetDat(CID); 00110 } else { 00111 return 0.0; 00112 } 00113 } 00114 void inline AddCom(const bool IsOut, const int& NID, const int& CID, const double& Val) { 00115 if (IsOut) { 00116 AddComOut(NID, CID, Val); 00117 } else { 00118 AddComIn(NID, CID, Val); 00119 } 00120 } 00121 void inline AddComOut(const int& NID, const int& CID, const double& Val) { 00122 if (F[NID].IsKey(CID)) { 00123 SumFV[CID] -= F[NID].GetDat(CID); 00124 } 00125 F[NID].AddDat(CID) = Val; 00126 SumFV[CID] += Val; 00127 } 00128 void inline AddComIn(const int& NID, const int& CID, const double& Val) { 00129 if (H[NID].IsKey(CID)) { 00130 SumHV[CID] -= H[NID].GetDat(CID); 00131 } 00132 H[NID].AddDat(CID) = Val; 00133 SumHV[CID] += Val; 00134 } 00135 void inline DelCom(const bool IsOut, const int& NID, const int& CID) { 00136 if (IsOut) { 00137 return DelComOut(NID, CID); 00138 } else { 00139 return DelComIn(NID, CID); 00140 } 00141 } 00142 void inline DelComOut(const int& NID, const int& CID) { 00143 if (F[NID].IsKey(CID)) { 00144 SumFV[CID] -= F[NID].GetDat(CID); 00145 F[NID].DelKey(CID); 00146 } 00147 } 00148 void inline DelComIn(const int& NID, const int& CID) { 00149 if (H[NID].IsKey(CID)) { 00150 SumHV[CID] -= H[NID].GetDat(CID); 00151 H[NID].DelKey(CID); 00152 } 00153 } 00154 double inline DotProduct(const TIntFltH& UV, const TIntFltH& VV) { 00155 double DP = 0; 00156 if (UV.Len() > VV.Len()) { 00157 for (TIntFltH::TIter HI = UV.BegI(); HI < UV.EndI(); HI++) { 00158 if (VV.IsKey(HI.GetKey())) { 00159 DP += VV.GetDat(HI.GetKey()) * HI.GetDat(); 00160 } 00161 } 00162 } else { 00163 for (TIntFltH::TIter HI = VV.BegI(); HI < VV.EndI(); HI++) { 00164 if (UV.IsKey(HI.GetKey())) { 00165 DP += UV.GetDat(HI.GetKey()) * HI.GetDat(); 00166 } 00167 } 00168 } 00169 return DP; 00170 } 00171 double inline DotProductUtoV(const int& UID, const int& VID) { 00172 return DotProduct(F[UID], H[VID]); 00173 } 00174 double inline Prediction(const TIntFltH& FU, const TIntFltH& HV) { 00175 double DP = log (1.0 / (1.0 - PNoCom)) + DotProduct(FU, HV); 00176 IAssertR(DP > 0.0, TStr::Fmt("DP: %f", DP)); 00177 return exp(- DP); 00178 } 00179 double inline Prediction(const int& UID, const int& VID) { 00180 return Prediction(F[UID], H[VID]); 00181 } 00182 double inline Sum(const TIntFltH& UV) { 00183 double N = 0.0; 00184 for (TIntFltH::TIter HI = UV.BegI(); HI < UV.EndI(); HI++) { 00185 N += HI.GetDat(); 00186 } 00187 return N; 00188 } 00189 double inline Norm2(const TIntFltH& UV) { 00190 double N = 0.0; 00191 for (TIntFltH::TIter HI = UV.BegI(); HI < UV.EndI(); HI++) { 00192 N += HI.GetDat() * HI.GetDat(); 00193 } 00194 return N; 00195 } 00196 }; 00197 00198 class TCodaAnalyzer { 00199 public: 00200 PNGraph G; 00201 TVec<TIntFltH> InCmtyValHV; 00202 TVec<TIntFltH> OutCmtyValHV; 00203 TVec<TIntFltH> InOutCmtyValHV; 00204 TCodaAnalyzer() { G = TNGraph::New(); } 00205 TCodaAnalyzer(TCoda& Coda, const double MemThres = -1.0) { 00206 G = Coda.GetGraphRawNID(); 00207 printf("graph copied (%d nodes %d edges)\n", G->GetNodes(), G->GetEdges()); 00208 TIntV CIdV; 00209 Coda.GetTopCIDs(CIdV, Coda.GetNumComs()); 00210 double Delta = MemThres == -1.0 ? sqrt(Coda.PNoCom): MemThres; 00211 for (int c = 0; c < CIdV.Len(); c++) { 00212 int CID = CIdV[c]; 00213 TIntFltH InMemH, OutMemH, InOutMemH; 00214 Coda.GetNIDValH(InOutMemH, OutMemH, InMemH, CID, Delta); 00215 InCmtyValHV.Add(InMemH); 00216 OutCmtyValHV.Add(OutMemH); 00217 InOutCmtyValHV.Add(InOutMemH); 00218 } 00219 printf("Communities copied (%d communities)\n", InCmtyValHV.Len()); 00220 } 00221 void GetAllCmtyVV(TVec<TIntV>& CmtyVV, const int MinSz) { 00222 for (int c = 0; c < InCmtyValHV.Len(); c++) { 00223 TIntV CmtyVIn, CmtyVOut, CmtyVInOut; 00224 if (InCmtyValHV[c].Len() < MinSz || OutCmtyValHV[c].Len() < MinSz) { continue; } 00225 InOutCmtyValHV[c].GetKeyV(CmtyVInOut); 00226 InCmtyValHV[c].GetKeyV(CmtyVIn); 00227 OutCmtyValHV[c].GetKeyV(CmtyVOut); 00228 CmtyVV.Add(CmtyVInOut); 00229 CmtyVV.Add(CmtyVOut); 00230 CmtyVV.Add(CmtyVIn); 00231 } 00232 } 00233 00234 double GetFrac2Mode(const double Thres2Mode = 0.2, const int MinSzEach = 2) { 00235 int Cnt2Mode = 0; 00236 int CntAll = 0; 00237 for (int c = 0; c < InCmtyValHV.Len(); c++) { 00238 double Jacc = (double) InOutCmtyValHV[c].Len() / (double) (InCmtyValHV[c].Len() + OutCmtyValHV[c].Len() - InOutCmtyValHV[c].Len()); 00239 if (InCmtyValHV[c].Len() < MinSzEach || OutCmtyValHV[c].Len() < MinSzEach) { continue; } 00240 if (Jacc <= Thres2Mode) { Cnt2Mode++; } 00241 CntAll++; 00242 } 00243 return (double) Cnt2Mode / (double) CntAll; 00244 } 00245 00246 void Summary(const int TopK = 10, const double Thres2Mode = 0.2) { 00247 int Cnt2Mode = 0; 00248 double SumJacc = 0.0; 00249 for (int c = 0; c < InCmtyValHV.Len(); c++) { 00250 double Jacc = (double) InOutCmtyValHV[c].Len() / (double) (InCmtyValHV[c].Len() + OutCmtyValHV[c].Len() - InOutCmtyValHV[c].Len()); 00251 if (Jacc <= Thres2Mode) { Cnt2Mode++; } 00252 SumJacc += Jacc; 00253 if (c < TopK) { 00254 printf("Cmty %d: InOut: %d, In:%d, Out:%d, Jacc;%.3f\n", c, InCmtyValHV[c].Len(), InCmtyValHV[c].Len(), OutCmtyValHV[c].Len(), Jacc); 00255 } 00256 } 00257 double AvgJacc = SumJacc / (double) InCmtyValHV.Len(); 00258 printf("Average jaccard similarity = %.3f. (%d / %d communities are 2-mode)\n", AvgJacc, Cnt2Mode, InCmtyValHV.Len()); 00259 } 00260 int GetNumComs() { return InCmtyValHV.Len(); } 00262 00263 void GetCmtyVAll(TIntV& CmtyVAll, const int CID) { 00264 TIntV CmtyVIn, CmtyVOut; 00265 InCmtyValHV[CID].GetKeyV(CmtyVIn); 00266 OutCmtyValHV[CID].GetKeyV(CmtyVOut); 00267 CmtyVIn.Sort(); 00268 CmtyVOut.Sort(); 00269 CmtyVAll.Gen(CmtyVIn.Len() + CmtyVOut.Len(), 0); 00270 CmtyVIn.Union(CmtyVOut, CmtyVAll); 00271 } 00272 00273 PNGraph Net2ModeCommunities(const double MaxJac, const double JacEdge, const bool GetWcc = true) { 00274 //if In(A) is similar to Out(B), create an edge A->B between 2 communities A, B 00275 int Coms = InCmtyValHV.Len(); 00276 PNGraph ComG = TNGraph::New(Coms, -1); 00277 for (int c = 0; c < InCmtyValHV.Len(); c++) { 00278 double Jacc = (double) InOutCmtyValHV[c].Len() / (double) (InCmtyValHV[c].Len() + OutCmtyValHV[c].Len() - InOutCmtyValHV[c].Len()); 00279 if (Jacc > MaxJac) { continue; } 00280 ComG->AddNode(c); 00281 } 00282 TVec<TIntSet> CmtySVIn, CmtySVOut; 00283 for (int c = 0; c < Coms; c++) { 00284 TIntV CmtyVIn, CmtyVOut; 00285 InCmtyValHV[c].GetKeyV(CmtyVIn); 00286 OutCmtyValHV[c].GetKeyV(CmtyVOut); 00287 TIntSet CmtySIn(CmtyVIn), CmtySOut(CmtyVOut); 00288 CmtySVIn.Add(CmtySIn); 00289 CmtySVOut.Add(CmtySOut); 00290 } 00291 for (int c1 = 0; c1 < Coms; c1++) { 00292 if (! ComG->IsNode(c1)) { continue; } 00293 for (int c2 = 0; c2 < Coms; c2++) { 00294 if (! ComG->IsNode(c2)) { continue; } 00295 int IntC1C2 = TAGMUtil::Intersection(CmtySVIn[c1], CmtySVOut[c2]); 00296 double Jac = (double) IntC1C2 / (CmtySVIn[c1].Len() + CmtySVOut[c2].Len() - IntC1C2); 00297 if (Jac >= JacEdge) { 00298 ComG->AddEdge(c1, c2); 00299 } 00300 } 00301 } 00302 //PNGraph Wcc = TSnap::GetMxWcc(ComG); 00303 TIntV NIDV; 00304 ComG->GetNIdV(NIDV); 00305 for (int u = 0; u < NIDV.Len(); u++) { 00306 int NID = NIDV[u]; 00307 TNGraph::TNodeI NI = ComG->GetNI(NID); 00308 if (NI.GetDeg() == 0) { ComG->DelNode(NID); } 00309 if (NI.GetInDeg() == 1 && NI.GetOutDeg() == 1 && NI.GetOutNId(0) == NID) { ComG->DelNode(NID); } 00310 } 00311 printf("Community graph made (Jaccard similarity for edges: %f, %d nodes, %d edges)\n", JacEdge, ComG->GetNodes(), ComG->GetEdges()); 00312 return ComG; 00313 } 00314 00315 // RS:2014/03/11 default parameter values do not compile on OS X with g++-4.2 00316 //void Dump2ModeCommunities(const TStr& OutFNm, const double MaxJac, const TIntStrH& NIDNameH = THash<TInt, TStr>()) { 00317 void Dump2ModeCommunities(const TStr& OutFNm, const double MaxJac, const TIntStrH& NIDNameH) { 00318 FILE* F = fopen(OutFNm.CStr(), "wt"); 00319 for (int c = 0; c < InCmtyValHV.Len(); c++) { 00320 double Jacc = (double) InOutCmtyValHV[c].Len() / (double) (InCmtyValHV[c].Len() + OutCmtyValHV[c].Len() - InOutCmtyValHV[c].Len()); 00321 if (Jacc > MaxJac) { continue; } 00322 TIntV CmtyVIn, CmtyVOut, CmtyVAll; 00323 InCmtyValHV[c].GetKeyV(CmtyVIn); 00324 OutCmtyValHV[c].GetKeyV(CmtyVOut); 00325 GetCmtyVAll(CmtyVAll, c); 00326 //adjust for the nodes who belong to both cmtyvin and cmtyvout 00327 for (int u = 0; u < InOutCmtyValHV[c].Len(); u++) { 00328 int UID = InOutCmtyValHV[c].GetKey(u); 00329 if (CmtyVIn.Len() >= CmtyVOut.Len()) { 00330 CmtyVIn.DelIfIn(UID); 00331 } else { 00332 CmtyVOut.DelIfIn(UID); 00333 } 00334 } 00335 if (CmtyVAll.Len() == 0) { continue; } 00336 fprintf(F, "Com %d\n", c); 00337 for (int u = 0; u < CmtyVOut.Len(); u++) { 00338 int NID = CmtyVOut[u]; 00339 TStr Label = NIDNameH.IsKey(NID)? NIDNameH.GetDat(NID): TStr::Fmt("Concept %d", NID); 00340 fprintf(F, "%s:%f\n", Label.CStr(), OutCmtyValHV[c].GetDat(NID).Val); 00341 } 00342 fprintf(F, "||==>||\n"); 00343 for (int u = 0; u < CmtyVIn.Len(); u++) { 00344 int NID = CmtyVIn[u]; 00345 TStr Label = NIDNameH.IsKey(NID)? NIDNameH.GetDat(NID): TStr::Fmt("Concept %d", NID); 00346 fprintf(F, "%s:%f\n", Label.CStr(), InCmtyValHV[c].GetDat(NID).Val); 00347 } 00348 fprintf(F, "\n"); 00349 } 00350 fclose(F); 00351 } 00352 00353 // RS:2014/03/11 default parameter values do not compile on OS X with g++-4.2 00354 //void Draw2ModeCommunity(const int CID, const TStr& OutFNm, const TIntStrH& NIDNameH = THash<TInt, TStr>(), const THash<TInt, TIntTr>& NIDColorH = THash<TInt, TIntTr>() ) { 00355 void Draw2ModeCommunity(const int CID, const TStr& OutFNm, const TIntStrH& NIDNameH, const THash<TInt, TIntTr>& NIDColorH) { 00356 TIntV CmtyVIn, CmtyVOut, CmtyVAll; 00357 InCmtyValHV[CID].GetKeyV(CmtyVIn); 00358 OutCmtyValHV[CID].GetKeyV(CmtyVOut); 00359 GetCmtyVAll(CmtyVAll, CID); 00360 00361 //adjust for the nodes who belong to both cmtyvin and cmtyvout 00362 for (int u = 0; u < InOutCmtyValHV[CID].Len(); u++) { 00363 int UID = InOutCmtyValHV[CID].GetKey(u); 00364 if (CmtyVIn.Len() >= CmtyVOut.Len()) { 00365 CmtyVIn.DelIfIn(UID); 00366 } else { 00367 CmtyVOut.DelIfIn(UID); 00368 } 00369 } 00370 00371 PNGraph SG = TSnap::GetSubGraph(G, CmtyVAll); 00373 if (CmtyVAll.Len() == 0) { return; } 00374 double OXMin = 0.1, YMin = 0.1, OXMax = 2500.00, YMax = 1000.0, IXMin = 0.1, IXMax = 2500.00; 00375 double OStep = (OXMax - OXMin) / (double) CmtyVOut.Len(), IStep = (IXMax - IXMin) / (double) CmtyVIn.Len(); 00376 00377 FILE* F = fopen(OutFNm.CStr(), "wt"); 00378 fprintf(F, "<?xml version='1.0' encoding='UTF-8'?>\n"); 00379 fprintf(F, "<gexf xmlns='http://www.gexf.net/1.2draft' xmlns:viz='http://www.gexf.net/1.1draft/viz' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.gexf.net/1.2draft http://www.gexf.net/1.2draft/gexf.xsd' version='1.2'>\n"); 00380 fprintf(F, "\t<graph mode='static' defaultedgetype='directed'>\n"); 00381 fprintf(F, "\t\t<nodes>\n"); 00382 for (int c = 0; c < CmtyVOut.Len(); c++) { 00383 int NID = CmtyVOut[c]; 00384 double XPos = c * OStep + OXMin; 00385 TStr Label = NIDNameH.IsKey(NID)? NIDNameH.GetDat(NID): ""; 00386 Label.ChangeChAll('<', ' '); 00387 Label.ChangeChAll('>', ' '); 00388 Label.ChangeChAll('&', ' '); 00389 Label.ChangeChAll('\'', ' '); 00390 TIntTr Color = NIDColorH.IsKey(NID)? NIDColorH.GetDat(NID) : TIntTr(120, 120, 120); 00391 fprintf(F, "\t\t\t<node id='%d' label='%s'>\n", NID, Label.CStr()); 00392 fprintf(F, "\t\t\t\t<viz:color r='%d' g='%d' b='%d'/>\n", Color.Val1.Val, Color.Val2.Val, Color.Val3.Val); 00393 fprintf(F, "\t\t\t\t<viz:size value='4.0'/>\n"); 00394 fprintf(F, "\t\t\t\t<viz:shape value='square'/>\n"); 00395 fprintf(F, "\t\t\t\t<viz:position x='%f' y='%f' z='0.0'/>\n", XPos, YMax); 00396 fprintf(F, "\t\t\t</node>\n"); 00397 } 00398 00399 for (int u = 0; u < CmtyVIn.Len(); u++) { 00400 int NID = CmtyVIn[u]; 00401 TStr Label = NIDNameH.IsKey(NID)? NIDNameH.GetDat(NID): ""; 00402 Label.ChangeChAll('<', ' '); 00403 Label.ChangeChAll('>', ' '); 00404 Label.ChangeChAll('&', ' '); 00405 Label.ChangeChAll('\'', ' '); 00406 double XPos = IXMin + u * IStep; 00407 TIntTr Color = NIDColorH.IsKey(NID)? NIDColorH.GetDat(NID) : TIntTr(120, 120, 120); 00408 double Alpha = 1.0; 00409 fprintf(F, "\t\t\t<node id='%d' label='%s'>\n", NID, Label.CStr()); 00410 fprintf(F, "\t\t\t\t<viz:color r='%d' g='%d' b='%d' a='%.1f'/>\n", Color.Val1.Val, Color.Val2.Val, Color.Val3.Val, Alpha); 00411 fprintf(F, "\t\t\t\t<viz:size value='4.0'/>\n"); 00412 fprintf(F, "\t\t\t\t<viz:shape value='square'/>\n"); 00413 fprintf(F, "\t\t\t\t<viz:position x='%f' y='%f' z='0.0'/>\n", XPos, YMin); 00414 fprintf(F, "\t\t\t</node>\n"); 00415 } 00416 fprintf(F, "\t\t</nodes>\n"); 00417 //plot edges 00418 int EID = 0; 00419 fprintf(F, "\t\t<edges>\n"); 00420 for (TNGraph::TNodeI NI = SG->BegNI(); NI < SG->EndNI(); NI++) { 00421 if (NI.GetOutDeg() == 0 && NI.GetInDeg() == 0 ) { continue; } 00422 for (int e = 0; e < NI.GetOutDeg(); e++) { 00423 fprintf(F, "\t\t\t<edge id='%d' source='%d' target='%d'/>\n", EID++, NI.GetId(), NI.GetOutNId(e)); 00424 } 00425 } 00426 fprintf(F, "\t\t</edges>\n"); 00427 fprintf(F, "\t</graph>\n"); 00428 fprintf(F, "</gexf>\n"); 00429 fclose(F); 00430 } 00431 00432 }; 00433 00434 #endif