// 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; } } }
// GIRVAN-NEWMAN algorithm // 1. The betweenness of all existing edges in the network is calculated first. // 2. The edge with the highest betweenness is removed. // 3. The betweenness of all edges affected by the removal is recalculated. // 4. Steps 2 and 3 are repeated until no edges remain. // Girvan M. and Newman M. E. J., Community structure in social and biological networks, Proc. Natl. Acad. Sci. USA 99, 7821–7826 (2002) // Keep removing edges from Graph until one of the connected components of Graph splits into two. void CmtyGirvanNewmanStep(PUNGraph& Graph, TIntV& Cmty1, TIntV& Cmty2) { TIntPrFltH BtwEH; TBreathFS<PUNGraph> BFS(Graph); Cmty1.Clr(false); Cmty2.Clr(false); while (true) { TSnap::GetBetweennessCentr(Graph, BtwEH); BtwEH.SortByDat(false); if (BtwEH.Empty()) { return; } const int NId1 = BtwEH.GetKey(0).Val1; const int NId2 = BtwEH.GetKey(0).Val2; Graph->DelEdge(NId1, NId2); BFS.DoBfs(NId1, true, false, NId2, TInt::Mx); if (BFS.GetHops(NId1, NId2) == -1) { // two components TSnap::GetNodeWcc(Graph, NId1, Cmty1); TSnap::GetNodeWcc(Graph, NId2, Cmty2); return; } } }