InitializeDeltaQs ( LinkedList <Community> oCommunities, DeltaQMaxHeap oDeltaQMaxHeap, Int32 iEdgesInGraph ) { Debug.Assert(oCommunities != null); Debug.Assert(oDeltaQMaxHeap != null); Debug.Assert(iEdgesInGraph > 0); AssertValid(); foreach (Community oCommunity in oCommunities) { // Initialize the delta Q values for the community. oCommunity.InitializeDeltaQs(oCommunities, iEdgesInGraph); Single fMaximumDeltaQ = oCommunity.MaximumDeltaQ; if (fMaximumDeltaQ != Community.DeltaQNotSet) { // Store the community's maximum delta Q on the max heap. oDeltaQMaxHeap.Add(oCommunity, fMaximumDeltaQ); } } }
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); }