91 lines
3.0 KiB
C#
91 lines
3.0 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
|
|||
|
|
namespace SchematicDrawing
|
|||
|
|
{
|
|||
|
|
public class Graph
|
|||
|
|
{
|
|||
|
|
IList<GNode> nodes;
|
|||
|
|
GNode currentNode;
|
|||
|
|
|
|||
|
|
public Graph()
|
|||
|
|
{
|
|||
|
|
nodes = new List<GNode>();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Clear()
|
|||
|
|
{
|
|||
|
|
nodes.Clear();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Add a node to the list of graph nodes
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="node">Graph node</param>
|
|||
|
|
public void AddNode(GNode node)
|
|||
|
|
{
|
|||
|
|
nodes.Add(node);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Add an edge to the list of edges of node1.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="node1">Node 1 (start)</param>
|
|||
|
|
/// <param name="node2">NOde 2 (end)</param>
|
|||
|
|
/// <param name="defaultDist">Default distance (when closed)</param>
|
|||
|
|
/// <param name="routeCouple">Way the route affects this edge</param>
|
|||
|
|
/// <returns>Added graph edge</returns>
|
|||
|
|
public GEdge AddEdge(GNode node1, GNode node2, int defaultDist, RouteCouple routeCouple = RouteCouple.None)
|
|||
|
|
{
|
|||
|
|
GEdge gedge = new GEdge(node1, node2, defaultDist, routeCouple);
|
|||
|
|
node1.AddEdge(gedge);
|
|||
|
|
return gedge;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Run Dijkstra shortest path algorithm to determine schematic drawing coloring
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="startNode">Start node</param>
|
|||
|
|
/// <param name="secondaryStartNodes">List of secondary start nodes</param>
|
|||
|
|
public void RunDijkstraAlgo(GNode startNode, IList<GNode> secondaryStartNodes = null)
|
|||
|
|
{
|
|||
|
|
if (nodes == null || startNode == null || !nodes.Contains(startNode)) return;
|
|||
|
|
|
|||
|
|
/// Reset all nodes
|
|||
|
|
foreach (var node in nodes) node.Reset();
|
|||
|
|
|
|||
|
|
startNode.Dist = 0;
|
|||
|
|
if (secondaryStartNodes != null) foreach (var ssn in secondaryStartNodes) ssn.Dist = 10000;
|
|||
|
|
currentNode = startNode;
|
|||
|
|
|
|||
|
|
int minDistance = int.MaxValue;
|
|||
|
|
do
|
|||
|
|
{
|
|||
|
|
/// Consider all unvisited neighbors of the current node
|
|||
|
|
foreach (var e in currentNode.Edges)
|
|||
|
|
{
|
|||
|
|
int distViaCurrNode = (e.Dist == int.MaxValue) ? int.MaxValue : currentNode.Dist + e.Dist;
|
|||
|
|
if (!e.EndNode.Visited && distViaCurrNode < e.EndNode.Dist)
|
|||
|
|
{
|
|||
|
|
e.EndNode.Dist = distViaCurrNode;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
currentNode.Visited = true;
|
|||
|
|
|
|||
|
|
/// Find new current node from all unvisited nodes
|
|||
|
|
currentNode = null;
|
|||
|
|
minDistance = int.MaxValue;
|
|||
|
|
foreach (var n in nodes)
|
|||
|
|
{
|
|||
|
|
if (!n.Visited && n.Dist < minDistance)
|
|||
|
|
{
|
|||
|
|
minDistance = n.Dist;
|
|||
|
|
currentNode = n;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
while (minDistance < int.MaxValue && currentNode != null);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|