/// <summary> /// Calculate distance between two nodes to be used as edge weidght /// </summary> /// <param name="start">First node</param> /// <param name="end">Second node</param> /// <returns>Distance between the two nodes</returns> private Double GetEdgeWeight(Node start, Node end) { System.Diagnostics.Debug.WriteLine(start.ID + end.ID); Double DX = start.Coordinates.X - end.Coordinates.X; Double DY = start.Coordinates.Y - end.Coordinates.Y; Double DD = Math.Sqrt((DX * DX) + (DY * DY)); return DD; }
/// <summary> /// Finds the shortes route between the two specified nodes. If the disabled /// parameter is set to true, nodes marked as not disabled-friendly will not /// be considered at all. If there is no route between the two nodes (should /// not happen in the final version of the program) the route will only consist /// of the endpoint. /// </summary> /// <param name="start">Node to start from</param> /// <param name="end">Node to arrive to</param> /// <param name="disabled">Whether to find a disabled-friendly route</param> /// <returns> /// A list of Nodes that create the path between the two points specified, /// including those two points /// </returns> public List<Node> FindRoute(Node start, Node end, bool disabled) { Dictionary<Node, double> distances = new Dictionary<Node, double>(); Dictionary<Node, Node> predecessors = new Dictionary<Node, Node>(); /* Initializing both lists */ foreach (Node node in NodeList) { distances.Add(node, double.MaxValue); predecessors.Add(node, null); } distances[start] = 0.0; /* Initializing the list we will be deleting nodes from */ List<Node> nodes = new List<Node>(NodeList); while (nodes.Count > 0) { double smallestDist = double.MaxValue; Node nearestNode = null; foreach(Node n in nodes) if (distances[n] < smallestDist) { smallestDist = distances[n]; nearestNode = n; } if (smallestDist == double.MaxValue) break; nodes.Remove(nearestNode); if (nearestNode.Equals(end)) break; foreach (Node n in GetNeighbours(nearestNode, disabled)) { double d = distances[nearestNode] + GetEdgeWeight(nearestNode, n); if (d < distances[n]) { distances[n] = d; predecessors[n] = nearestNode; } } } /* Creating the route */ List<Node> route = new List<Node>(); Node u = end; while (predecessors[u] != null) { route.Add(predecessors[u]); u = predecessors[u]; } route.Reverse(); route.Add(end); return route; }
public Edge(Node NodeStart, Node NodeEnd, double Weight) { this.NodeStart = NodeStart; this.NodeEnd = NodeEnd; this.Weight = Weight; }
/// <summary> /// Finds all neighbours of the specified node. If the disabled parametet is /// set to true, only disabled-friendly nodes will be returned. /// </summary> /// <param name="source">Node to analyze</param> /// <param name="disabled">Whether to return only disabled-friendly nodes</param> /// <returns>A list of nodes directly connected to the node specified</returns> private List<Node> GetNeighbours(Node source, bool disabled) { List<Node> neighbours = new List<Node>(); foreach (Edge edge in EdgeList) { if (edge.NodeStart.Equals(source) && (!disabled || edge.NodeEnd.Disabled)) neighbours.Add(edge.NodeEnd); if (edge.NodeEnd.Equals(source) && (!disabled || edge.NodeStart.Disabled)) neighbours.Add(edge.NodeStart); } return neighbours; }
/// <summary> /// Find the edge connecting the two specified nodes and returns its weight. /// </summary> /// <param name="start">One of the nodes</param> /// <param name="end">The other node</param> /// <returns>Weight of the edge between the two nodes, or double.MaxValue if there is no edge</returns> private double GetEdgeWeight(Node start, Node end) { foreach (Edge edge in EdgeList) { if (edge.NodeStart.Equals(start) && edge.NodeEnd.Equals(end)) return edge.Weight; if (edge.NodeStart.Equals(end) && edge.NodeEnd.Equals(start)) return edge.Weight; } return double.MaxValue; }