snap-stanford / snap

Stanford Network Analysis Platform (SNAP) is a general purpose network analysis and graph mining library.
Other
2.16k stars 795 forks source link

CESNA generate non overlapping communities #223

Open userAman16 opened 3 years ago

userAman16 commented 3 years ago

Hi,

How can we generate non-overlapping communities in in CESNA, I ran https://github.com/snap-stanford/snap/tree/master/examples/cesna and getting communities. I used command line arguments to configure the number of communities to be discovered. I read the paper https://www-cs.stanford.edu/~jure/pubs/cesna-icdm13.pdf and found CESNA can detect overlapping, non-overlapping, as well as hierarchically nested communities in networks,

I found two function TCesna::RandomInit and TCesna::NeighborComInit i think to have a non overlapping Init needs to be modified!!

Any lead on how to generate non overlapping communities will be very helpful.

userAman16 commented 3 years ago

added this function GetNonOverLapCmtyVV in agmattr.cpp and using GetNonOverLapCmtyVV instead of GetCmtyVV in exmaple/Cesna.cpp basically i am taking the best affiliation for each node

//extract non-overlapping community affiliation

void TCesna::GetNonOverLapCmtyVV(TVec<TIntV>& CmtyVV, TVec<TFltV>& Wck, const double Thres, const int MinSz) {
    TIntFltPrV NIdxVF(F.Len(), 0);
    for (int i = 0; i < F.Len(); i++) 
    {
        TInt selectedKey = -1;
        TFlt selectedDat = 0;
        TFlt max = 0;
        for (TIntFltH::TIter CI = F[i].BegI(); CI < F[i].EndI(); CI++) 
        {
            TFlt tempDat = CI.GetDat();
            if (max < tempDat) {
                max = tempDat;
                selectedKey = CI.GetKey();
                selectedDat = CI.GetDat();
            }
        }
        max = 0;
        NIdxVF.Add(TIntFltPr(selectedKey, selectedDat));
    }
    CmtyVV.Gen(NumComs, 0);
    Wck.Gen(NumComs, 0);
    TIntFltH CIDSumFH(NumComs);
    for (int c = 0; c < SumFV.Len(); c++) {
        CIDSumFH.AddDat(c, SumFV[c]);
    }
    CIDSumFH.SortByDat(false);
    for (int c = 0; c < NumComs; c++) {
        int CID = CIDSumFH.GetKey(c);
        TIntFltH NIDFucH(F.Len() / 10);
        TIntV CmtyV;
        IAssert(SumFV[CID] == CIDSumFH.GetDat(CID));
        if (SumFV[CID] < Thres) { continue; }
        for (int u = 0; u < NIdxVF.Len(); u++) {
            int NID = NIDToIdx[u];
            if ((NIdxVF[u].Val1) == CID && NIdxVF[u].Val2 >= Thres) {
                NIDFucH.AddDat(NID, NIdxVF[u].Val2);
            }
        }
        NIDFucH.SortByDat(false);
        NIDFucH.GetKeyV(CmtyV);
        if (CmtyV.Len() < MinSz) { continue; }
        CmtyVV.Add(CmtyV);
        TFltV WV(Attrs);
        for (int k = 0; k < Attrs; k++) {
            WV[k] = GetW(CID, k);
        }
        Wck.Add(WV);
    }
    if (NumComs != CmtyVV.Len()) {
        printf("Community vector generated. %d communities are ommitted\n", NumComs.Val - CmtyVV.Len());
    }
}