CreateCommunities
(
IVertexCollection oVertices,
IDGenerator oIDGenerator
)
{
Debug.Assert(oVertices != null);
Debug.Assert(oIDGenerator != null);
AssertValid();
// This is the list of communities. Initially, there will be one
// community for each of the graph's vertices.
LinkedList<Community> oCommunities = new LinkedList<Community>();
// This temporary dictionary is used to map a vertex ID to a community.
// The key is the IVertex.ID and the value is the corresponding
// Community object.
Dictionary<Int32, Community> oVertexIDDictionary =
new Dictionary<Int32, Community>(oVertices.Count);
// First, create a community for each of the graph's vertices. Each
// community contains just the vertex.
foreach (IVertex oVertex in oVertices)
{
Community oCommunity = new Community();
Int32 iID = oIDGenerator.GetNextID();
oCommunity.ID = iID;
oCommunity.Vertices.Add(oVertex);
// TODO: IVertex.AdjacentVertices includes self-loops. Should
// self-loops be eliminated everywhere, including here and within
// the graph's total edge count? Not sure how self-loops are
// affecting the algorithm used by this class...
oCommunity.Degree = oVertex.AdjacentVertices.Count;
oCommunities.AddLast(oCommunity);
oVertexIDDictionary.Add(oVertex.ID, oCommunity);
}
// Now populate each community's list of community pairs.
foreach (Community oCommunity1 in oCommunities)
{
Debug.Assert(oCommunity1.Vertices.Count == 1);
IVertex oVertex = oCommunity1.Vertices.First();
SortedList<Int32, CommunityPair> oCommunityPairs =
oCommunity1.CommunityPairs;
foreach (IVertex oAdjacentVertex in oVertex.AdjacentVertices)
{
if (oAdjacentVertex == oVertex)
{
// Skip self-loops.
continue;
}
Community oCommunity2 =
oVertexIDDictionary[oAdjacentVertex.ID];
CommunityPair oCommunityPair = new CommunityPair();
oCommunityPair.Community1 = oCommunity1;
oCommunityPair.Community2 = oCommunity2;
oCommunityPairs.Add(oCommunity2.ID, oCommunityPair);
}
}
return (oCommunities);
}