using System; using System.Collections.Generic; namespace SchematicDrawing { public class Graph { IList nodes; GNode currentNode; public Graph() { nodes = new List(); } public void Clear() { nodes.Clear(); } /// /// Add a node to the list of graph nodes /// /// Graph node public void AddNode(GNode node) { nodes.Add(node); } /// /// Add an edge to the list of edges of node1. /// /// Node 1 (start) /// NOde 2 (end) /// Default distance (when closed) /// Way the route affects this edge /// Added graph edge 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; } /// /// Run Dijkstra shortest path algorithm to determine schematic drawing coloring /// /// Start node /// List of secondary start nodes public void RunDijkstraAlgo(GNode startNode, IList 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); } } }