예제 #1
0
        /// <summary>
        /// Check a neighbour of the current node to see if it needs to be added to the tentative list
        /// or the shortest route to it needs to be updated.
        /// </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 checkNeighbour(DijkstraNode neighbour, DijkstraNode current, float dist, IMLink link)
        {
            float newDistance = dist + link.Weight;

            try {
                //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
                if (_cont && !_tentative.Contains(neighbour))
                {
                    _tentative.AddFirst(neighbour);
                    neighbour.SetDistanceFromRoot(ID, newDistance, current, link);
                }
                else if (_cont && newDistance <= neighbour.GetDistanceFromRoot(ID))
                {
                    neighbour.SetDistanceFromRoot(ID, newDistance, current, link);
                }
            } 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 + ")");
            }

            //Incase another thread has modified the distance
            if (_cont && newDistance < neighbour.GetDistanceFromRoot(ID))
            {
                neighbour.SetDistanceFromRoot(ID, newDistance, neighbour, link);
            }
        }
예제 #2
0
 /// <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);
 }
예제 #3
0
        /// <summary>
        /// Visualise the process of choosing the next node. Will output text about what is going on if necessary.
        /// </summary>
        /// <param name="next">The next node to be current.</param>
        /// <param name="prev">The node that was previously current.</param>
        private void VisualiseChooseNext(DijkstraNode next, DijkstraNode prev)
        {
            if (_cont && !next.Equals(this))
            {
                if (_cont && _text)
                {
                    Say("8. There are nodes in the tentative list. Finding the node in tentative with the smallest cost");
                    Pause();
                }
                Pause(3f);
                if (_cont && _text)
                {
                    Say("9. new current = " + next.Name + " with cost " + next.GetDistanceFromRoot(ID));
                    Pause();
                    Say("10. Adding link between ct (" + prev.Name + ") and new current (" + next.Name + ") to the shortest path");
                    Pause();
                }
            }

            prev.Reset();

            IMLink confirmedLink = next.GetWIPRoute(ID);

            if (_cont && confirmedLink != null)
            {
                Pause(6f);
                confirmedLink.Colour = Color.Red;
            }

            if (_cont && _text)
            {
                Say((next.Equals(this) ? "2a" : "11a") + ". Adding " +
                    (next.Equals(this) ? "root" : "new current") + " (" + next.Name + ") to Confirmed");
                Pause();
                Say((next.Equals(this) ? "2b" : "11b") + ". Setting current to " +
                    (next.Equals(this) ? "root" : "new current") + " (" + next.Name + ")");
            }

            next.Reset();
            next.Selected = currentGlow;
            next.Colour   = Color.White;

            if (_cont && _text && !next.Equals(this))
            {
                Pause();
                Say("11c. Going to step 4");
                Pause();
            }
        }
예제 #4
0
        /// <summary>
        /// Visualise the process of choosing the next node. Will output text about what is going on if necessary.
        /// </summary>
        /// <param name="next">The next node to be current.</param>
        /// <param name="prev">The node that was previously current.</param>
        private void VisualiseChooseNext(DijkstraNode next, DijkstraNode prev)
        {
            if (_cont && !next.Equals(this)) {
                if (_cont && _text) {
                    Say("8. There are nodes in the tentative list. Finding the node in tentative with the smallest cost");
                    Pause();
                }
                Pause(3f);
                if (_cont && _text) {
                    Say("9. new current = " + next.Name + " with cost " + next.GetDistanceFromRoot(ID));
                    Pause();
                    Say("10. Adding link between ct (" + prev.Name + ") and new current (" + next.Name + ") to the shortest path");
                    Pause();
                }
            }

            prev.Reset();

            IMLink confirmedLink = next.GetWIPRoute(ID);
            if (_cont && confirmedLink != null) {
                Pause(6f);
                confirmedLink.Colour = Color.Red;
            }

            if (_cont && _text) {
                Say((next.Equals(this) ? "2a" : "11a") + ". Adding " +
                          (next.Equals(this) ? "root" : "new current") + " (" + next.Name + ") to Confirmed");
                Pause();
                Say((next.Equals(this) ? "2b" : "11b") + ". Setting current to " +
                          (next.Equals(this) ? "root" : "new current") + " (" + next.Name + ")");
            }

            next.Reset();
            next.Selected = currentGlow;
            next.Colour = Color.White;

            if (_cont && _text && !next.Equals(this)) {
                Pause();
                Say("11c. Going to step 4");
                Pause();
            }
        }
예제 #5
0
        /// <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);
            }
        }
예제 #6
0
 /// <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);
 }
예제 #7
0
        /// <summary>
        /// Check a neighbour of the current node to see if it needs to be added to the tentative list
        /// or the shortest route to it needs to be updated.
        /// </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 checkNeighbour(DijkstraNode neighbour, DijkstraNode current, float dist, IMLink link)
        {
            float newDistance = dist + link.Weight;

            try {
                //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
                if (_cont && !_tentative.Contains(neighbour)) {
                    _tentative.AddFirst(neighbour);
                    neighbour.SetDistanceFromRoot(ID, newDistance, current, link);
                } else if (_cont && newDistance <= neighbour.GetDistanceFromRoot(ID))
                    neighbour.SetDistanceFromRoot(ID, newDistance, current, link);
            } 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 + ")");
            }

            //Incase another thread has modified the distance
            if (_cont && newDistance < neighbour.GetDistanceFromRoot(ID))
                neighbour.SetDistanceFromRoot(ID, newDistance, neighbour, link);
        }
예제 #8
0
        /// <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);
            }
        }