private static void UpdateReachableNodesTotalCost(MinDistanceWpf.Classes.Node node) { double currentCost = node.TotalCost; foreach (ReachableNode rn in _reachableNodes.ReachableNodes) { if (currentCost + rn.Edge.Length < rn.Node.TotalCost || rn.Node.TotalCost == -1) rn.Node.TotalCost = currentCost + rn.Edge.Length; } _reachableNodes.SortReachableNodes(); }
private static List<int> PaintMinDistancePath(MinDistanceWpf.Classes.Node start, MinDistanceWpf.Classes.Node end) { List<int> Ret = new List<int>(); if (_isGraphConnected) { MinDistanceWpf.Classes.Node currentNode = end; double totalCost = 0; while (currentNode != start) { currentNode.Visited = true; currentNode.EdgeCameFrom.Visited = true; totalCost += currentNode.EdgeCameFrom.Length; Console.WriteLine("Node: " + currentNode.Label); Ret.Add(Convert.ToInt32(currentNode.Label)); Console.WriteLine("Edge: " + currentNode.EdgeCameFrom.Length + " " + currentNode.EdgeCameFrom.FirstNode.Label); currentNode = GetNeighbour(currentNode, currentNode.EdgeCameFrom); } //paint the current node -> this is the start node if (currentNode != null) { Console.WriteLine("Node: " + currentNode.Label); Ret.Add(Convert.ToInt32(currentNode.Label)); } start.Visited = true; Console.WriteLine("Total cost: " + totalCost.ToString()); } else { start = end = null; _isGraphConnected = true; // _findMinDistance = false; Ret = null; Console.WriteLine("The graph is not connected. Cannot find a path", "Error"); } return Ret; }
private static void FindMinDistancePath(MinDistanceWpf.Classes.Node start, MinDistanceWpf.Classes.Node end) { if (start != null && end != null) { _cloud.Clear(); _reachableNodes.Clear(); MinDistanceWpf.Classes.Node currentNode = start; currentNode.Visited = true; start.TotalCost = 0; _cloud.Add(currentNode); ReachableNode currentReachableNode; while (currentNode != end) { AddReachableNodes(currentNode); UpdateReachableNodesTotalCost(currentNode); //if we cannot reach any other node, the graph is not connected if (_reachableNodes.ReachableNodes.Count == 0) { _isGraphConnected = false; break; } //get the closest reachable node currentReachableNode = _reachableNodes.ReachableNodes[0]; //remove if from the reachable nodes list _reachableNodes.RemoveReachableNode(currentReachableNode); //mark the current node as visited currentNode.Visited = true; //set the current node to the closest one from the cloud currentNode = currentReachableNode.Node; //set a pointer to the edge from where we came from currentNode.EdgeCameFrom = currentReachableNode.Edge; //mark the edge as visited currentReachableNode.Edge.Visited = true; _cloud.Add(currentNode); } } return; }
private static MinDistanceWpf.Classes.Node GetNeighbour(MinDistanceWpf.Classes.Node node, Edge edge) { if (edge.FirstNode == node) return edge.SecondNode; else return edge.FirstNode; }
private static void AddReachableNodes(MinDistanceWpf.Classes.Node node) { MinDistanceWpf.Classes.Node neighbour; ReachableNode rn; foreach (Edge edge in node.Edges) { neighbour = GetNeighbour(node, edge); //make sure we don't add the node we came from if (node.EdgeCameFrom == null || neighbour != GetNeighbour(node, node.EdgeCameFrom)) { //make sure we don't add a node already in the cloud if (!_cloud.Contains(neighbour)) { //if the node is already reachable if (_reachableNodes.HasNode(neighbour)) { //if the distance from this edge is smaller than the current total cost //amend the reachable node using the current edge if (node.TotalCost + edge.Length < neighbour.TotalCost) { rn = _reachableNodes.GetReachableNodeFromNode(neighbour); rn.Edge = edge; } } else { rn = new ReachableNode(neighbour, edge); _reachableNodes.AddReachableNode(rn); } } } } }