Smrf.NodeXL.Algorithms.ClusterCalculator.MergeCommunities C# (CSharp) Méthode

MergeCommunities() protected méthode

protected MergeCommunities ( LinkedList oCommunities, CommunityPair oCommunityPairToMerge, DeltaQMaxHeap oDeltaQMaxHeap, Int32 iEdgesInGraph, IDGenerator oIDGenerator ) : void
oCommunities LinkedList
oCommunityPairToMerge CommunityPair
oDeltaQMaxHeap DeltaQMaxHeap
iEdgesInGraph System.Int32
oIDGenerator Smrf.NodeXL.Core.IDGenerator
Résultat void
    MergeCommunities
    (
        LinkedList<Community> oCommunities,
        CommunityPair oCommunityPairToMerge,
        DeltaQMaxHeap oDeltaQMaxHeap,
        Int32 iEdgesInGraph,
        IDGenerator oIDGenerator
    )
    {
        Debug.Assert(oCommunityPairToMerge != null);
        Debug.Assert(oCommunities != null);
        Debug.Assert(oDeltaQMaxHeap != null);
        Debug.Assert(iEdgesInGraph > 0);
        Debug.Assert(oIDGenerator != null);

        // Merge Community1 and Community2 into a NewCommunity.

        Community oCommunity1 = oCommunityPairToMerge.Community1;
        Community oCommunity2 = oCommunityPairToMerge.Community2;

        Community oNewCommunity = new Community();

        oNewCommunity.ID = oIDGenerator.GetNextID();
        oNewCommunity.Degree = oCommunity1.Degree + oCommunity2.Degree;

        ICollection<IVertex> oNewCommunityVertices = oNewCommunity.Vertices;

        foreach (IVertex oVertex in oCommunity1.Vertices)
        {
            oNewCommunityVertices.Add(oVertex);
        }

        foreach (IVertex oVertex in oCommunity2.Vertices)
        {
            oNewCommunityVertices.Add(oVertex);
        }

        // In the following sorted lists, the sort key is the ID of
        // CommunityPair.Community2 and the value is the CommunityPair.

        SortedList<Int32, CommunityPair> oCommunity1CommunityPairs =
            oCommunity1.CommunityPairs;

        SortedList<Int32, CommunityPair> oCommunity2CommunityPairs =
            oCommunity2.CommunityPairs;

        SortedList<Int32, CommunityPair> oNewCommunityCommunityPairs =
            oNewCommunity.CommunityPairs;

        Int32 iCommunity1CommunityPairs = oCommunity1CommunityPairs.Count;
        Int32 iCommunity2CommunityPairs = oCommunity2CommunityPairs.Count;

        IList<Int32> oCommunity1Keys = oCommunity1CommunityPairs.Keys;

        IList<CommunityPair> oCommunity1Values =
            oCommunity1CommunityPairs.Values;

        IList<Int32> oCommunity2Keys = oCommunity2CommunityPairs.Keys;

        IList<CommunityPair> oCommunity2Values =
            oCommunity2CommunityPairs.Values;

        // Step through the community pairs in oCommunity1 and oCommunity2.

        Int32 iCommunity1Index = 0;
        Int32 iCommunity2Index = 0;

        Single fMaximumDeltaQ = Single.MinValue;
        CommunityPair oCommunityPairWithMaximumDeltaQ = null;
        Single fTwoTimesEdgesInGraph = 2F * iEdgesInGraph;

        while (iCommunity1Index < iCommunity1CommunityPairs ||
               iCommunity2Index < iCommunity2CommunityPairs)
        {
            Int32 iCommunity1OtherCommunityID =
                (iCommunity1Index < iCommunity1CommunityPairs) ?
                oCommunity1Keys[iCommunity1Index] : Int32.MaxValue;

            Int32 iCommunity2OtherCommunityID =
                (iCommunity2Index < iCommunity2CommunityPairs) ?
                oCommunity2Keys[iCommunity2Index] : Int32.MaxValue;

            CommunityPair oNewCommunityPair = new CommunityPair();
            oNewCommunityPair.Community1 = oNewCommunity;

            if (iCommunity1OtherCommunityID == oCommunity2.ID)
            {
                // This is an internal connection eliminated by the merge.
                // Skip it.

                iCommunity1Index++;
                continue;
            }
            else if (iCommunity2OtherCommunityID == oCommunity1.ID)
            {
                // This is an internal connection eliminated by the merge.
                // Skip it.

                iCommunity2Index++;
                continue;
            }
            else if (iCommunity1OtherCommunityID == iCommunity2OtherCommunityID)
            {
                // The other community is connected to both commmunity 1 and
                // community 2.
                //
                // This is equation 10a from the paper "Finding Community
                // Structure in Very Large Networks," by Clauset, Newman, and
                // Moore.

                oNewCommunityPair.Community2 =
                    oCommunity1Values[iCommunity1Index].Community2;

                oNewCommunityPair.DeltaQ = 
                    oCommunity1Values[iCommunity1Index].DeltaQ +
                    oCommunity2Values[iCommunity2Index].DeltaQ;

                iCommunity1Index++;
                iCommunity2Index++;
            }
            else if (iCommunity1OtherCommunityID < iCommunity2OtherCommunityID)
            {
                // The other community is connected only to commmunity 1.
                //
                // This is equation 10b from the same paper.

                Community oOtherCommunity =
                    oCommunity1Values[iCommunity1Index].Community2;

                oNewCommunityPair.Community2 = oOtherCommunity;

                Single fAj = oCommunity2.Degree / fTwoTimesEdgesInGraph;
                Single fAk = oOtherCommunity.Degree / fTwoTimesEdgesInGraph;

                oNewCommunityPair.DeltaQ = 
                    oCommunity1Values[iCommunity1Index].DeltaQ -
                    2F * fAj * fAk;

                iCommunity1Index++;
            }
            else
            {
                // The other community is connected only to commmunity 2.
                //
                // This is equation 10c from the same paper.

                Community oOtherCommunity =
                    oCommunity2Values[iCommunity2Index].Community2;

                oNewCommunityPair.Community2 = oOtherCommunity;

                Single fAi = oCommunity1.Degree / fTwoTimesEdgesInGraph;
                Single fAk = oOtherCommunity.Degree / fTwoTimesEdgesInGraph;

                oNewCommunityPair.DeltaQ = 
                    oCommunity2Values[iCommunity2Index].DeltaQ -
                    2F * fAi * fAk;

                iCommunity2Index++;
            }

            oNewCommunityCommunityPairs.Add(oNewCommunityPair.Community2.ID,
                oNewCommunityPair);

            Single fNewCommunityPairDeltaQ = oNewCommunityPair.DeltaQ;

            if (fNewCommunityPairDeltaQ > fMaximumDeltaQ)
            {
                fMaximumDeltaQ = oNewCommunityPair.DeltaQ;
                oCommunityPairWithMaximumDeltaQ = oNewCommunityPair;
            }

            // The other community is connected to one or both of the merged
            // communities.  Update it.

            oNewCommunityPair.Community2.OnMergedCommunities(
                oCommunity1, oCommunity2, oNewCommunity,
                fNewCommunityPairDeltaQ, oDeltaQMaxHeap);
        }

        oNewCommunity.CommunityPairWithMaximumDeltaQ =
            oCommunityPairWithMaximumDeltaQ;

        // Update the community list.

        oCommunities.Remove(oCommunity1);
        oCommunities.Remove(oCommunity2);
        oCommunities.AddLast(oNewCommunity);

        // Update the max heap.

        oDeltaQMaxHeap.Remove(oCommunity1);
        oDeltaQMaxHeap.Remove(oCommunity2);
        oDeltaQMaxHeap.Add(oNewCommunity, oNewCommunity.MaximumDeltaQ);
    }