#include "stdafx.h" #include "cliques.h" ///////////////////////////////////////////////// // TCommunity implementation void TCliqueOverlap::GetRelativeComplement(const THashSet& A, const THashSet& B, THashSet& Complement) { for (THashSet::TIter it=A.BegI(); it& A, const THashSet& B, THashSet& C) { if (A.Len() < B.Len()) { for (THashSetKeyI it=A.BegI(); it it=B.BegI(); it& A, const THashSet& B) { int n = 0; if (A.Len() < B.Len()) { for (THashSetKeyI it=A.BegI(); it it=B.BegI(); it& Nbhs) const{ TUNGraph::TNodeI node = m_G->GetNI(NId); int deg = node.GetDeg(); for (int i=0; i& Set) const{ int id = -1; int maxDeg = -1; // for (THashSetKeyI it=Set.BegI(); itGetNI(nId).GetDeg(); if (maxDeg < deg) { maxDeg=deg; id=nId; } } return id; } int TCliqueOverlap::MaxNbhsInCANDNodeId(const THashSet& SUBG, const THashSet& CAND) const{ int id = -1; int maxIntersection = -1; // for (THashSetKeyI it=SUBG.BegI(); itGetNI(nId); int deg = nIt.GetDeg(); // int curIntersection = 0; for (int i=0; i& SUBG, THashSet& CAND) { if (SUBG.Len()==0) { if (m_Q.Len() >= m_minMaxCliqueSize) { m_Q.Pack(); m_maxCliques->Add(m_Q); } return; } if (CAND.Len()==0) return; //Get u that maximaze CAND intersection with neighbours of vertex u int u = MaxNbhsInCANDNodeId(SUBG, CAND); //Get neighbours of node u THashSet nbhsU; GetNbhs(u, nbhsU); //Get relative complement of nbhsU in CAND THashSet EXT; GetRelativeComplement(CAND, nbhsU, EXT); while(EXT.Len() != 0) { int q = GetNodeIdWithMaxDeg(EXT); // m_Q.Add(q); // THashSet nbhsQ; GetNbhs(q, nbhsQ); // THashSet SUBGq; GetIntersection(SUBG, nbhsQ, SUBGq); // THashSet CANDq; GetIntersection(CAND, nbhsQ, CANDq); // Expand(SUBGq, CANDq); // CAND.DelKey(q); m_Q.DelLast(); // EXT.Clr(); GetRelativeComplement(CAND, nbhsU, EXT); } } void TCliqueOverlap::GetMaximalCliques(const PUNGraph& G, int MinMaxCliqueSize, TVec& MaxCliques) { if (G->GetNodes() == 0) return; // m_G = G; m_minMaxCliqueSize = MinMaxCliqueSize; m_maxCliques =& MaxCliques; m_Q.Clr(); // THashSet SUBG; THashSet CAND; for (TUNGraph::TNodeI NI=m_G->BegNI(); NIEndNI(); NI++) { TInt nId = NI.GetId(); SUBG.AddKey(nId); CAND.AddKey(nId); } // Expand(SUBG, CAND); } void TCliqueOverlap::CalculateOverlapMtx(const TVec& MaxCliques, int MinNodeOverlap, TVec& OverlapMtx) { OverlapMtx.Clr(); // int n = MaxCliques.Len(); //Convert max cliques to HashSets TVec > cliques; for (int i=0; i& set = cliques.Last(); set.Gen(len); for (int j=0; j& MaxCliques, int MinNodeOverlap) { const int n = MaxCliques.Len(); //Convert max cliques to HashSets TVec > cliques; for (int i=0; i& set = cliques.Last(); set.Gen(len); for (int j=0; jAddNode(i); } //Calculate clique clique overlap matrix for (int i=0; i= MinNodeOverlap) { OverlapMtx->AddEdge(i,j); } } } return OverlapMtx; } void TCliqueOverlap::GetOverlapCliques(const TVec& OverlapMtx, int MinNodeOverlap, TVec& CliqueIdVV) { int n = OverlapMtx.Len(); for (int i=0; i= MinNodeOverlap) { if (! isCommunity) { TIntV v; v.Add(i); CliqueIdVV.Add(v); isCommunity=true; } CliqueIdVV.Last().Add(j); } } } } void TCliqueOverlap::GetOverlapCliques(const TVec& OverlapMtx, const TVec& MaxCliques, double MinOverlapFrac, TVec& CliqueIdVV) { int n = OverlapMtx.Len(); for(int i=0; i= MinOverlapFrac){ if(!isCommunity){ TIntV v; v.Add(i); CliqueIdVV.Add(v); isCommunity=true; } CliqueIdVV.Last().Add(j); } } } } /// Enumerate maximal cliques of the network on more than MinMaxCliqueSize nodes void TCliqueOverlap::GetMaxCliques(const PUNGraph& G, int MinMaxCliqueSize, TVec& MaxCliques) { TCliqueOverlap CO; MaxCliques.Clr(false); CO.GetMaximalCliques(G, MinMaxCliqueSize, MaxCliques); } /// Clique Percolation method communities void TCliqueOverlap::GetCPMCommunities(const PUNGraph& G, int MinMaxCliqueSize, TVec& NIdCmtyVV) { printf("Clique Percolation Method\n"); TExeTm ExeTm; TVec MaxCliques; TCliqueOverlap::GetMaxCliques(G, MinMaxCliqueSize, MaxCliques); printf("...%d cliques found\n"); // get clique overlap matrix (graph) PUNGraph OverlapGraph = TCliqueOverlap::CalculateOverlapMtx(MaxCliques, MinMaxCliqueSize-1); printf("...overlap matrix (%d, %d)\n", G->GetNodes(), G->GetEdges()); // connected components are communities TCnComV CnComV; TSnap::GetWccs(OverlapGraph, CnComV); NIdCmtyVV.Clr(false); TIntSet CmtySet; for (int c = 0; c < CnComV.Len(); c++) { CmtySet.Clr(false); for (int i = 0; i