GetSubgraph
(
IVertex vertex,
Decimal levels,
Boolean getSubgraphEdges,
out Dictionary<IVertex, Int32> subgraphVertices,
out HashSet<IEdge> subgraphEdges
)
{
Debug.Assert(vertex != null);
Debug.Assert(levels >= 0);
Debug.Assert(Decimal.Remainder(levels, 0.5M) == 0M);
subgraphVertices = new Dictionary<IVertex, Int32>();
subgraphEdges = new HashSet<IEdge>();
// This algorithm was suggested by Jure Leskovec at Carnegie Mellon
// University.
// Create a queue of vertices that need to be visited. A queue is used
// instead of recursion.
Queue<IVertex> oVerticesToVisit = new Queue<IVertex>();
// Get the level of the outermost vertices.
Int32 iOuterLevel = (Int32)Math.Truncate(levels);
subgraphVertices.Add(vertex, 0);
oVerticesToVisit.Enqueue(vertex);
while (oVerticesToVisit.Count > 0)
{
IVertex oVertexToVisit = oVerticesToVisit.Dequeue();
Int32 iLevel = subgraphVertices[oVertexToVisit];
if (iLevel == iOuterLevel)
{
continue;
}
foreach (IEdge oIncidentEdge in oVertexToVisit.IncidentEdges)
{
if (getSubgraphEdges)
{
subgraphEdges.Add(oIncidentEdge);
}
IVertex oAdjacentVertex =
oIncidentEdge.GetAdjacentVertex(oVertexToVisit);
if (!subgraphVertices.ContainsKey(oAdjacentVertex))
{
subgraphVertices.Add(oAdjacentVertex, iLevel + 1);
oVerticesToVisit.Enqueue(oAdjacentVertex);
}
}
}
if (getSubgraphEdges && ((levels / 0.5M) % 2M) == 1)
{
// levels is 0.5, 1.5, 2.5, etc. Any edges connecting the
// outermost vertices need to be added to the edge dictionary.
AddOuterEdgesToSubgraph(iOuterLevel, subgraphVertices,
subgraphEdges);
}
}