// get the node ids in 1-connected components void Get1CnCom(const PUNGraph& Graph, TCnComV& Cn1ComV) { //TCnCom::GetWccCnt(Graph, SzCntV); IAssertR(SzCntV.Len() == 1, "Graph is not connected."); TIntPrV EdgeV; GetEdgeBridges(Graph, EdgeV); if (EdgeV.Empty()) { Cn1ComV.Clr(false); return; } PUNGraph TmpG = TUNGraph::New(); *TmpG = *Graph; for (int e = 0; e < EdgeV.Len(); e++) { TmpG->DelEdge(EdgeV[e].Val1, EdgeV[e].Val2); } TCnComV CnComV; GetWccs(TmpG, CnComV); IAssert(CnComV.Len() >= 2); const TIntV& MxWcc = CnComV[0].NIdV; TIntSet MxCcSet(MxWcc.Len()); for (int i = 0; i < MxWcc.Len(); i++) { MxCcSet.AddKey(MxWcc[i]); } // create new graph: bridges not touching MxCc of G with no bridges for (int e = 0; e < EdgeV.Len(); e++) { if (! MxCcSet.IsKey(EdgeV[e].Val1) && ! MxCcSet.IsKey(EdgeV[e].Val2)) { TmpG->AddEdge(EdgeV[e].Val1, EdgeV[e].Val2); } } GetWccs(TmpG, Cn1ComV); // remove the largest component of G for (int c = 0; c < Cn1ComV.Len(); c++) { if (MxCcSet.IsKey(Cn1ComV[c].NIdV[0])) { Cn1ComV.Del(c); break; } } }
// Maximum modularity clustering by Girvan-Newman algorithm (slow) // Girvan M. and Newman M. E. J., Community structure in social and biological networks, Proc. Natl. Acad. Sci. USA 99, 7821–7826 (2002) double CommunityGirvanNewman(PUNGraph& Graph, TCnComV& CmtyV) { TIntH OutDegH; const int NEdges = Graph->GetEdges(); for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { OutDegH.AddDat(NI.GetId(), NI.GetOutDeg()); } double BestQ = -1; // modularity TCnComV CurCmtyV; CmtyV.Clr(); TIntV Cmty1, Cmty2; while (true) { CmtyGirvanNewmanStep(Graph, Cmty1, Cmty2); const double Q = _GirvanNewmanGetModularity(Graph, OutDegH, NEdges, CurCmtyV); //printf("current modularity: %f\n", Q); if (Q > BestQ) { BestQ = Q; CmtyV.Swap(CurCmtyV); } if (Cmty1.Len()==0 || Cmty2.Len() == 0) { break; } } return BestQ; }