public Boolean TryCalculateClustersWakitaTsurumi
(IGraph oGraph, BackgroundWorker oBackgroundWorker,out ICollection<Community> oGraphMetrics)
{
Debug.Assert(oGraph != null);
IVertexCollection oVertices = oGraph.Vertices;
Int32 iVertices = oVertices.Count;
Int32 iEdges = oGraph.Edges.Count;
IDGenerator oIDGenerator = new IDGenerator(1);
// Create and populate a community for each of the graph's vertices.
LinkedList<Community> oCommunities =
CreateCommunities(oVertices, oIDGenerator);
oGraphMetrics = oCommunities;
if (iVertices == 0 || iEdges == 0)
{
// There is no point in going any further.
return (true);
}
// This max heap is used to keep track of the maximum delta Q value in
// each community. There is an element in the max heap for each
// community. The key is the Community and the value is the
// Community's maximum delta Q.
DeltaQMaxHeap oDeltaQMaxHeap = new DeltaQMaxHeap(iVertices);
// Initialize all the delta Q values.
InitializeDeltaQs(oCommunities, oDeltaQMaxHeap, iEdges);
// Run the algorithm outlined in the Wakita/Tsurumi paper.
BinaryHeapItem<Community, Single> oBinaryHeapItemWithMaximumDeltaQ;
Int32 iMergeCycles = 0;
// Retrieve the community pair with the largest delta Q.
while (oDeltaQMaxHeap.TryGetTop(out oBinaryHeapItemWithMaximumDeltaQ))
{
// Check for cancellation and report progress every
// MergeCyclesPerProgressReport calculations.
if (
iMergeCycles % MergeCyclesPerProgressReport == 0
&&
!ReportProgressAndCheckCancellationPending(
iMergeCycles, iVertices, oBackgroundWorker)
)
{
return (false);
}
Community oCommunityWithMaximumDeltaQ =
oBinaryHeapItemWithMaximumDeltaQ.Key;
Single fMaximumGlobalDeltaQ =
oBinaryHeapItemWithMaximumDeltaQ.Value;
if (fMaximumGlobalDeltaQ < 0)
{
// Merging additional communities would yield worse results, so
// quit.
break;
}
// Merge the communities in the community pair with maximum
// delta Q, update the maximum delta Q values for all communities,
// and update the global max heap.
CommunityPair oCommunityPairWithMaximumDeltaQ =
oCommunityWithMaximumDeltaQ.CommunityPairWithMaximumDeltaQ;
MergeCommunities(oCommunities, oCommunityPairWithMaximumDeltaQ,
oDeltaQMaxHeap, iEdges, oIDGenerator);
iMergeCycles++;
}
return (true);
}