/// <summary> /// The main loop which is the body of the algorithm. /// Loops through every neighbour of the current node checking to see if they: /// A. Have been visited before /// B. Have been visited before but are now a shorter route /// </summary> /// <param name="current">The node currently being checked.</param> /// <param name="prev">The previous node that was checked.</param> /// <returns>The last node to be checked.</returns> private void MainLoop(DijkstraNode current, DijkstraNode prev) { while (_cont && current != null && !hitTarget(current)) { //If necessary display text and wait if (_cont && _text && _visualise) { current.Say("4. Iterating through neighbours excluding neighbours in Confirmed"); Pause(); } //Get the current distance to the target float dist = current.GetDistanceFromRoot(ID); foreach (var n in current.Neighbours) { IMLink link = current.Links[n.ID]; if (_visualise) { _links.AddFirst(link); } var neighbour = this.GetAlgNode <DijkstraNode>(n.ID); if (_cont && !_confirmed.Contains(neighbour)) { if (_visualise && _text) { VisualiseCheckNeighbourText(neighbour, current, dist, link); } else if (_visualise) { VisualiseCheckNeighbour(neighbour, current, dist, link); } checkNeighbour(neighbour, current, dist, link); } if (!_cont) { break; } } //Store the old previous node prev = current; if (_cont && _text && _visualise) { Say("Finished iterating through current's (" + current.Name + "'s) neighbours, getting next current from tentative list"); Pause(); } //Get the next node to be checked (the one which has the shortest path to it) current = getNext(current); } FinishedReset(current, prev); }
/// <summary> /// Visualises the process of checking a neighbour node and prints out text explaining what is happening. /// </summary> /// <param name="neighbour">The neighbour to check.</param> /// <param name="current">The current node.</param> /// <param name="dist">The distance from the root to the current node.</param> /// <param name="link">The link between current and neighbour.</param> private void VisualiseCheckNeighbourText(DijkstraNode neighbour, DijkstraNode current, float dist, IMLink link) { if (!_visualise && !_text) return; float newDistance = dist + link.Weight; if (_cont) { //if (_cont && _text) // current.Say("Examining neighbour " + neighbour.Name); Pause(4f); link.Colour = Color.Blue; if (_cont && _text) { Pause(); current.Say("5. Test cost to " + neighbour.Name + " = " + dist + " + " + link.Weight + " = " + newDistance); Pause(); } Pause(4f); } try { if (_cont && !_tentative.Contains(neighbour)) { if (_cont && _text) current.Say(neighbour.Name + " is not in tentative list"); _tentative.AddFirst(neighbour); neighbour.SetDistanceFromRoot(ID, newDistance, current, link); if (_cont) { Pause(4f); neighbour.Selected = tentativeGlow; if (_cont && _text) { current.Say("6a. Adding " + neighbour.Name + " to the tentative list"); Pause(); current.Say("6b. " + neighbour.Name + ".cost = test cost (" + newDistance + ")"); } } } //If the new route from root to neighbour is shorter than the old route or there was no old route //set the current node as the first step towards the root from neighbour else if (_cont && newDistance <= neighbour.GetDistanceFromRoot(ID)) { neighbour.SetDistanceFromRoot(ID, newDistance, current, link); if (_cont && _text) { current.Say(neighbour.Name + ".cost (" + neighbour.GetDistanceFromRoot(ID) + ") > test cost (" + newDistance + ")"); Pause(); current.Say("7. " + neighbour.Name + ".cost = test cost (" + newDistance + ")"); Pause(); } } } catch (KeyNotFoundException e) { //If the AddLink being checked is no Keyer in the list of links the algorithm needs to stop _cont = false; if (_visualise) VisualisedNode = null; Logger.Debug("Trying to work with a neighbour (" + neighbour.Name + ") which is not actually connected to " + current.Name + " (root = " + Name + ")"); } if (_cont && newDistance < neighbour.GetDistanceFromRoot(ID)) neighbour.SetDistanceFromRoot(ID, newDistance, neighbour, link); if (_cont) { Pause(4f); link.Colour = Color.White; Pause(6f); } }
/// <summary> /// The main loop which is the body of the algorithm. /// Loops through every neighbour of the current node checking to see if they: /// A. Have been visited before /// B. Have been visited before but are now a shorter route /// </summary> /// <param name="current">The node currently being checked.</param> /// <param name="prev">The previous node that was checked.</param> /// <returns>The last node to be checked.</returns> private void MainLoop(DijkstraNode current, DijkstraNode prev) { while (_cont && current != null && !hitTarget(current)) { //If necessary display text and wait if (_cont && _text && _visualise) { current.Say("4. Iterating through neighbours excluding neighbours in Confirmed"); Pause(); } //Get the current distance to the target float dist = current.GetDistanceFromRoot(ID); foreach (var n in current.Neighbours) { IMLink link = current.Links[n.ID]; if (_visualise) _links.AddFirst(link); var neighbour = this.GetAlgNode<DijkstraNode>(n.ID); if (_cont && !_confirmed.Contains(neighbour)) { if (_visualise && _text) VisualiseCheckNeighbourText(neighbour, current, dist, link); else if (_visualise) VisualiseCheckNeighbour(neighbour, current, dist, link); checkNeighbour(neighbour, current, dist, link); } if (!_cont) break; } //Store the old previous node prev = current; if (_cont && _text && _visualise) { Say("Finished iterating through current's (" + current.Name + "'s) neighbours, getting next current from tentative list"); Pause(); } //Get the next node to be checked (the one which has the shortest path to it) current = getNext(current); } FinishedReset(current, prev); }
/// <summary> /// Visualises the process of checking a neighbour node and prints out text explaining what is happening. /// </summary> /// <param name="neighbour">The neighbour to check.</param> /// <param name="current">The current node.</param> /// <param name="dist">The distance from the root to the current node.</param> /// <param name="link">The link between current and neighbour.</param> private void VisualiseCheckNeighbourText(DijkstraNode neighbour, DijkstraNode current, float dist, IMLink link) { if (!_visualise && !_text) { return; } float newDistance = dist + link.Weight; if (_cont) { //if (_cont && _text) // current.Say("Examining neighbour " + neighbour.Name); Pause(4f); link.Colour = Color.Blue; if (_cont && _text) { Pause(); current.Say("5. Test cost to " + neighbour.Name + " = " + dist + " + " + link.Weight + " = " + newDistance); Pause(); } Pause(4f); } try { if (_cont && !_tentative.Contains(neighbour)) { if (_cont && _text) { current.Say(neighbour.Name + " is not in tentative list"); } _tentative.AddFirst(neighbour); neighbour.SetDistanceFromRoot(ID, newDistance, current, link); if (_cont) { Pause(4f); neighbour.Selected = tentativeGlow; if (_cont && _text) { current.Say("6a. Adding " + neighbour.Name + " to the tentative list"); Pause(); current.Say("6b. " + neighbour.Name + ".cost = test cost (" + newDistance + ")"); } } } //If the new route from root to neighbour is shorter than the old route or there was no old route //set the current node as the first step towards the root from neighbour else if (_cont && newDistance <= neighbour.GetDistanceFromRoot(ID)) { neighbour.SetDistanceFromRoot(ID, newDistance, current, link); if (_cont && _text) { current.Say(neighbour.Name + ".cost (" + neighbour.GetDistanceFromRoot(ID) + ") > test cost (" + newDistance + ")"); Pause(); current.Say("7. " + neighbour.Name + ".cost = test cost (" + newDistance + ")"); Pause(); } } } catch (KeyNotFoundException e) { //If the AddLink being checked is no Keyer in the list of links the algorithm needs to stop _cont = false; if (_visualise) { VisualisedNode = null; } Logger.Debug("Trying to work with a neighbour (" + neighbour.Name + ") which is not actually connected to " + current.Name + " (root = " + Name + ")"); } if (_cont && newDistance < neighbour.GetDistanceFromRoot(ID)) { neighbour.SetDistanceFromRoot(ID, newDistance, neighbour, link); } if (_cont) { Pause(4f); link.Colour = Color.White; Pause(6f); } }