public void OnMergedCommunities
(Community mergedCommunity1,Community mergedCommunity2,Community newMergedCommunity,Single newCommunityPairDeltaQ,DeltaQMaxHeap deltaQMaxHeap)
{
Debug.Assert(mergedCommunity1 != null);
Debug.Assert(mergedCommunity2 != null);
Debug.Assert(newMergedCommunity != null);
Debug.Assert(deltaQMaxHeap != null);
// If only one of the two merged communities was connected to this
// community, fPreviousCommunityPairDeltaQ is the delta Q for this
// community's community pair for the merged community. If both were
// connected, fPreviousCommunityPairDeltaQ is the larger of the two
// delta Q values.
Single fPreviousCommunityPairDeltaQ = Single.MinValue;
Int32 iMergedCommunity1ID = mergedCommunity1.ID;
Int32 iMergedCommunity2ID = mergedCommunity2.ID;
Debug.Assert(iMergedCommunity1ID != iMergedCommunity2ID);
Int32 iSmallerMergedCommunityID =
Math.Min(iMergedCommunity1ID, iMergedCommunity2ID);
Int32 iLargerMergedCommunityID =
Math.Max(iMergedCommunity1ID, iMergedCommunity2ID);
// Delete the community pair or pairs that connect to one of the merged
// communities.
//
// Go backwards through the community pairs so that they can be deleted
// while looping. (Don't use foreach, because you can't delete while
// enumerating.)
for (Int32 i = m_oCommunityPairs.Count - 1; i >= 0; i--)
{
Int32 iOtherCommunityID = m_oCommunityPairs.Keys[i];
if (iOtherCommunityID > iLargerMergedCommunityID)
{
// We haven't yet reached the range of community pairs that
// might connect to either merged community.
continue;
}
if (iOtherCommunityID < iSmallerMergedCommunityID)
{
// We're beyond the range of community pairs that might connect
// to either merged community.
break;
}
CommunityPair oCommunityPair = m_oCommunityPairs.Values[i];
if (iOtherCommunityID == iLargerMergedCommunityID)
{
// This community pair connects to the merged community with
// the larger ID.
fPreviousCommunityPairDeltaQ = oCommunityPair.DeltaQ;
m_oCommunityPairs.RemoveAt(i);
}
else if (iOtherCommunityID == iSmallerMergedCommunityID)
{
// This community pair connects to the merged community with
// the smaller ID.
fPreviousCommunityPairDeltaQ = Math.Max(
fPreviousCommunityPairDeltaQ, oCommunityPair.DeltaQ);
m_oCommunityPairs.RemoveAt(i);
// There is no reason to continue looking at community pairs.
break;
}
else
{
// This community pair does not connect to either merged
// community.
continue;
}
}
Debug.Assert(fPreviousCommunityPairDeltaQ != Single.MinValue);
// Add a new community pair that connects to the new merged community.
CommunityPair oNewCommunityPair = new CommunityPair();
oNewCommunityPair.Community1 = this;
oNewCommunityPair.Community2 = newMergedCommunity;
oNewCommunityPair.DeltaQ = newCommunityPairDeltaQ;
m_oCommunityPairs.Add(newMergedCommunity.ID, oNewCommunityPair);
// Update m_oCommunityPairWithMaximumDeltaQ if necessary. These rules
// come from section 4.1 of "Finding Community Structure in Mega-scale
// Social Networks," by Ken Wakita and Toshiyuki Tsurumi.
Single fOldMaximumDeltaQ = this.MaximumDeltaQ;
if (fPreviousCommunityPairDeltaQ < fOldMaximumDeltaQ)
{
// The deleted community pair (or pairs) was not the one with the
// maximum delta Q.
if (newCommunityPairDeltaQ <= fPreviousCommunityPairDeltaQ)
{
// The delta Q value for the new community pair is less than or
// equal to the delta Q value of the deleted community pair (or
// pairs). Do nothing.
}
else
{
// The delta Q value for the new community pair is greater than
// the delta Q value of the deleted community pair (or pairs).
if (newCommunityPairDeltaQ > fOldMaximumDeltaQ)
{
// The new community pair is the one with the maximum
// delta Q.
m_oCommunityPairWithMaximumDeltaQ = oNewCommunityPair;
}
}
}
else
{
// The deleted community pair (or pairs) was the one with the
// maximum delta Q.
if (newCommunityPairDeltaQ >= fPreviousCommunityPairDeltaQ)
{
// The new community pair is the one with the maximum
// delta Q.
m_oCommunityPairWithMaximumDeltaQ = oNewCommunityPair;
}
else
{
// Worst case: All community pairs must be scanned.
Single fNewMaximumDeltaQ = Single.MinValue;
foreach (CommunityPair oCommunityPair in
m_oCommunityPairs.Values)
{
if (oCommunityPair.DeltaQ > fNewMaximumDeltaQ)
{
m_oCommunityPairWithMaximumDeltaQ = oCommunityPair;
fNewMaximumDeltaQ = oCommunityPair.DeltaQ;
}
}
}
}
if (fOldMaximumDeltaQ != this.MaximumDeltaQ)
{
// Update the max heap.
deltaQMaxHeap.UpdateValue(this, this.MaximumDeltaQ);
}
}