tbf/SchematicDrawing/Graph.cs

91 lines
3.0 KiB
C#
Raw Normal View History

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);
}
}
}