/// <summary>
        ///     The Dijkstra's algorithm.
        /// </summary>
        private void _dijkstra()
        {
            while (!_minPriorityQueue.IsEmpty)
            {
                var currentVertex      = _minPriorityQueue.DequeueMin();
                var currentVertexIndex = _nodesToIndices[currentVertex];

                var outgoingEdges = _graph.OutgoingEdges(currentVertex);
                foreach (var outgoingEdge in outgoingEdges)
                {
                    var adjacentIndex = _nodesToIndices[outgoingEdge.Destination];
                    var delta         = _distances[currentVertexIndex] != Infinity ? _distances[currentVertexIndex] + outgoingEdge.Weight : Infinity;

                    if (delta < _distances[adjacentIndex])
                    {
                        _distances[adjacentIndex]    = delta;
                        _predecessors[adjacentIndex] = currentVertexIndex;

                        if (_minPriorityQueue.Contains(outgoingEdge.Destination))
                        {
                            _minPriorityQueue.UpdatePriority(outgoingEdge.Destination, delta);
                        }
                        else
                        {
                            _minPriorityQueue.Enqueue(outgoingEdge.Destination, delta);
                        }
                    }
                }
            }
        }
Example #2
0
        public static IEnumerable <Edge <T> > DijkstraShortestPath <T>(this IGraph <T> graph, T startVertex, T finishVertex) where T : IEquatable <T>
        {
            var currentVertex = startVertex;
            var weigths       = new MinPriorityQueue <Weight <T> >();
            var paths         = new Dictionary <T, Path <T> >
            {
                { startVertex, new Path <T> {
                      Weight = 0.0, Edges = new List <Edge <T> >()
                  } }
            };

            while (paths.Count < graph.VertexCount)
            {
                foreach (var edge in graph.EdgesOf(currentVertex))
                {
                    if (edge.Weight < 0)
                    {
                        throw new ArgumentOutOfRangeException(
                                  "Edge.Weight", edge.Weight,
                                  "Dijkstra's algorithm for shortest paths does not support negative weights.");
                    }
                    if (!paths.ContainsKey(edge.Target))
                    {
                        weigths.Enqueue(new Weight <T>
                        {
                            Edge       = edge,
                            PathWeight = paths[edge.Source].Weight + edge.Weight
                        });
                    }
                }

                Weight <T> smallest;
                do
                {
                    // skip obsolete edges
                    smallest = weigths.DequeueMin();
                } while (paths.ContainsKey(smallest.Edge.Target));

                var pathToSource = paths[smallest.Edge.Source];
                var path         = new List <Edge <T> >(pathToSource.Edges);
                path.Add(smallest.Edge);

                if (smallest.Edge.Target.Equals(finishVertex))
                {
                    return(path);
                }

                currentVertex = smallest.Edge.Target;
                paths.Add(smallest.Edge.Target, new Path <T> {
                    Weight = smallest.PathWeight, Edges = path
                });
            }
            return(new Edge <T> [0]);
        }
        /************************************************************************************************************/


        /// <summary>
        /// The Dijkstra's algorithm.
        /// </summary>
        private void _dijkstra(TGraph graph, TVertex source)
        {
            var minPQ = new MinPriorityQueue <TVertex, decimal>((uint)_verticesCount);

            var srcIndex = _nodesToIndices[source];

            _srcIndex            = srcIndex;
            _distances[srcIndex] = 0;

            minPQ.Enqueue(source, _distances[srcIndex]);

            // Main loop
            while (!minPQ.IsEmpty)
            {
                var current      = minPQ.DequeueMin();                                                    // get vertex with min weight
                var currentIndex = _nodesToIndices[current];                                              // get its index
                var edges        = graph.OutgoingEdges(current) as IEnumerable <WeightedEdge <TVertex> >; // get its outgoing weighted edges

                foreach (var edge in edges)
                {
                    var adjacentIndex = _nodesToIndices[edge.Destination];

                    // calculate a new possible weighted path if the edge weight is less than infinity
                    var delta = Infinity;
                    if (edge.Weight < Infinity && _distances[currentIndex] + edge.Weight < Infinity)  // Handles overflow
                    {
                        delta = _distances[currentIndex] + edge.Weight;
                    }

                    // Relax the edge
                    // if check is true, a shorter path is found from current to adjacent
                    if (delta < _distances[adjacentIndex])
                    {
                        _edgeTo[adjacentIndex]       = edge;
                        _distances[adjacentIndex]    = delta;
                        _predecessors[adjacentIndex] = currentIndex;

                        // decrease priority with a new distance if it exists; otherwise enqueque it
                        if (minPQ.Contains(edge.Destination))
                        {
                            minPQ.UpdatePriority(edge.Destination, delta);
                        }
                        else
                        {
                            minPQ.Enqueue(edge.Destination, delta);
                        }
                    }
                } //end-foreach
            }     //end-while
        }
Example #4
0
        public void MinPriorityQueue_SingleEnqueueDequeueTest()
        {
            string test  = "test";
            var    queue = new MinPriorityQueue <string>();

            queue.Enqueue(test);

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(1, queue.Size);

            var dequeued = queue.DequeueMin();

            Assert.IsTrue(queue.IsEmpty);
            Assert.AreEqual(0, queue.Size);
            Assert.AreEqual(test, dequeued);
        }
        /************************************************************************************************************/


        /// <summary>
        /// The Dijkstra's algorithm.
        /// </summary>
        private void _dijkstra(TGraph graph, TVertex source)
        {
            var minPQ = new MinPriorityQueue <TVertex, long>((uint)_verticesCount);

            int srcIndex = _nodesToIndices[source];

            _distances[srcIndex] = 0;

            // Add all vertices to the queue
            foreach (var vertex in _nodesToIndices)
            {
                minPQ.Enqueue(vertex.Key, _distances[vertex.Value]);
            }

            // Main loop
            while (!minPQ.IsEmpty)
            {
                var current      = minPQ.DequeueMin();           // get vertex with min weight
                var currentIndex = _nodesToIndices[current];     // get its index
                var edges        = graph.OutgoingEdges(current); // get its outgoing weighted edges

                foreach (var edge in edges)
                {
                    var adjacentIndex = _nodesToIndices[edge.Destination];
                    var delta         = _distances[currentIndex] + edge.Weight; // calculate a new possible weighted path

                    if (delta < _distances[adjacentIndex])                      // if true, a shorter path is found from current to adjacent
                    {
                        _edgeTo[adjacentIndex]       = edge;
                        _distances[adjacentIndex]    = delta;
                        _predecessors[adjacentIndex] = currentIndex;
                        minPQ.UpdatePriority(edge.Destination, delta);      // decrease priority with a new edge weight
                    }
                }//end-foreach
            }//end-while
        }
Example #6
0
        // GET: /<controller>/
        public IActionResult Index()
        {
            string result = string.Empty;

            // KEYED PRIORITY QUEUE
            PriorityQueue <int, int, int> keyedPriorityQueue = new PriorityQueue <int, int, int>(10);

            for (int i = 0; i < 20; ++i)
            {
                keyedPriorityQueue.Enqueue(i, i, (i / 3) + 1);
            }

            result = result + "Enqueue Keys: ";
            foreach (var key in keyedPriorityQueue.Keys)
            {
                result = result + key + ",";
            }

            var keyedPQHighest = keyedPriorityQueue.Dequeue();

            result = result + "\nAfter Dequeue, Keyed PQ Highest = " + keyedPQHighest + "\n\n";

            // Integer-index priority-queue
            string alphabet = "abcdefghijklmnopqrstuvwxyz";

            result = result + "Alphabets: " + "abcdefghijklmnopqrstuvwxyz" + "\n";
            MinPriorityQueue <string, int> priorityQueue = new MinPriorityQueue <string, int>((uint)alphabet.Length);

            for (int i = 0; i < alphabet.Length; ++i)
            {
                priorityQueue.Enqueue(alphabet[i].ToString(), (i / 3) + 1);
            }

            var PQMin = priorityQueue.DequeueMin();

            result = result + "PQ Min = " + PQMin + "\n\n";

            // Processes with priorities
            MinPriorityQueue <Process, int> sysProcesses = new MinPriorityQueue <Process, int>();

            var process1 = new Process(
                id: 432654,
                action: new Action(() => System.Console.Write("I am Process #1.\r\n1 + 1 = " + (1 + 1))),
                desc: "Process 1");

            result = result + "Id: " + process1.Id + "\nI am Process #1: 1 + 1 = " + (1 + 1) + "\n\n";

            var process2 = new Process(
                id: 123456,
                action: new Action(() => System.Console.Write("Hello, World! I am Process #2")),
                desc: "Process 2");

            result = result + "Id: " + process2.Id + "\nHello, World! I am Process #2" + "\n\n";

            var process3 = new Process(
                id: 345098,
                action: new Action(() => System.Console.Write("I am Process #3")),
                desc: "Process 3");

            result = result + "Id: " + process3.Id + "\nI am Process #3" + "\n\n";

            var process4 = new Process(
                id: 109875,
                action: new Action(() => System.Console.Write("I am Process #4")),
                desc: "Process 4");

            result = result + "Id: " + process4.Id + "\nI am Process #4" + "\n\n";

            var process5 = new Process(
                id: 13579,
                action: new Action(() => System.Console.Write("I am Process #5")),
                desc: "Process 5");

            result = result + "Id: " + process5.Id + "\nI am Process #5" + "\n\n";

            var process6 = new Process(
                id: 24680,
                action: new Action(() => System.Console.Write("I am Process #6")),
                desc: "Process 6");

            result = result + "Id: " + process6.Id + "\nI am Process #6" + "\n\n";

            sysProcesses.Enqueue(process1, 1);
            sysProcesses.Enqueue(process2, 10);
            sysProcesses.Enqueue(process3, 5);
            sysProcesses.Enqueue(process4, 7);
            sysProcesses.Enqueue(process5, 3);
            sysProcesses.Enqueue(process6, 6);

            var leastPriorityProcess = sysProcesses.PeekAtMinPriority();

            result = result + "First, Least Priority Process.Id = " + leastPriorityProcess.Id + "\n";

            sysProcesses.DequeueMin();

            leastPriorityProcess = sysProcesses.PeekAtMinPriority();
            result = result + "After the second DequeueMin(), Least Priority Process.Id = " + leastPriorityProcess.Id + "\n";

            sysProcesses.DequeueMin();

            leastPriorityProcess = sysProcesses.PeekAtMinPriority();
            result = result + "After the third DequeueMin(), Least Priority Process.Id = " + leastPriorityProcess.Id + "\n";

            sysProcesses.DequeueMin();

            leastPriorityProcess = sysProcesses.PeekAtMinPriority();
            result = result + "After the forth DequeueMin(), Least Priority Process.Id = " + leastPriorityProcess.Id + "\n";

            leastPriorityProcess.Action();

            HtmlString html = StringHelper.GetHtmlString(result);

            return(View(html));
        }
Example #7
0
        public void MinPriorityQueue_DequeueMinFromEmptyQueueTest()
        {
            var queue = new MinPriorityQueue <string>();

            queue.DequeueMin();
        }
Example #8
0
        public void MinPriorityQueue_MultipleEnqueueDequeueTest()
        {
            var testData = new int[] { 12, 0, 3, 9, 1, 3, 4, 4, 5, 2, 13, 7, 8, 3, 11, 14, 15 };
            var queue    = new MinPriorityQueue <int>();

            foreach (var item in testData)
            {
                queue.Enqueue(item);
            }

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length, queue.Size);

            var dequeued = queue.DequeueMin();

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length - 1, queue.Size);
            Assert.AreEqual(0, dequeued);

            dequeued = queue.DequeueMin();

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length - 2, queue.Size);
            Assert.AreEqual(1, dequeued);

            dequeued = queue.Min;

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length - 2, queue.Size);
            Assert.AreEqual(2, dequeued);

            dequeued = queue.DequeueMin();

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length - 3, queue.Size);
            Assert.AreEqual(2, dequeued);

            dequeued = queue.DequeueMin();

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length - 4, queue.Size);
            Assert.AreEqual(3, dequeued);

            dequeued = queue.DequeueMin();

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length - 5, queue.Size);
            Assert.AreEqual(3, dequeued);

            dequeued = queue.DequeueMin();

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length - 6, queue.Size);
            Assert.AreEqual(3, dequeued);

            dequeued = queue.DequeueMin();

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length - 7, queue.Size);
            Assert.AreEqual(4, dequeued);

            dequeued = queue.DequeueMin();

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length - 8, queue.Size);
            Assert.AreEqual(4, dequeued);

            dequeued = queue.DequeueMin();

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length - 9, queue.Size);
            Assert.AreEqual(5, dequeued);

            dequeued = queue.DequeueMin();

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length - 10, queue.Size);
            Assert.AreEqual(7, dequeued);

            dequeued = queue.DequeueMin();

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length - 11, queue.Size);
            Assert.AreEqual(8, dequeued);

            dequeued = queue.DequeueMin();

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length - 12, queue.Size);
            Assert.AreEqual(9, dequeued);

            dequeued = queue.DequeueMin();

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length - 13, queue.Size);
            Assert.AreEqual(11, dequeued);

            dequeued = queue.DequeueMin();

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length - 14, queue.Size);
            Assert.AreEqual(12, dequeued);

            dequeued = queue.DequeueMin();

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length - 15, queue.Size);
            Assert.AreEqual(13, dequeued);

            dequeued = queue.DequeueMin();

            Assert.IsFalse(queue.IsEmpty);
            Assert.AreEqual(testData.Length - 16, queue.Size);
            Assert.AreEqual(14, dequeued);

            dequeued = queue.DequeueMin();

            Assert.IsTrue(queue.IsEmpty);
            Assert.AreEqual(0, queue.Size);
            Assert.AreEqual(15, dequeued);
        }
Example #9
0
        public static void DoTest()
        {
            //
            // KEYED PRIORITY QUEUE
            PriorityQueue <int, int, int> keyedPriorityQueue = new PriorityQueue <int, int, int> (10);

            for (int i = 0; i < 20; ++i)
            {
                keyedPriorityQueue.Enqueue(i, i, (i / 3) + 1);
            }

            var keyedPQHighest = keyedPriorityQueue.Dequeue();

            Debug.Assert(keyedPQHighest == 18, "Wrong node!");

            //
            // Integer-index priority-queue
            string alphabet = "abcdefghijklmnopqrstuvwxyz";
            MinPriorityQueue <string, int> priorityQueue = new MinPriorityQueue <string, int> ((uint)alphabet.Length);

            for (int i = 0; i < alphabet.Length; ++i)
            {
                priorityQueue.Enqueue(alphabet[i].ToString(), (i / 3) + 1);
            }

            var PQMin = priorityQueue.DequeueMin();

            Debug.Assert(PQMin == "a", "Wrong node!");

            //
            // Processes with priorities
            MinPriorityQueue <Process, int> sysProcesses = new MinPriorityQueue <Process, int>();

            var process1 = new Process(
                id: 432654,
                action: new Action(() => System.Console.Write("I am Process #1.\r\n1 + 1 = " + (1 + 1))),
                desc: "Process 1");

            var process2 = new Process(
                id: 123456,
                action: new Action(() => System.Console.Write("Hello, World! I am Process #2")),
                desc: "Process 2");

            var process3 = new Process(
                id: 345098,
                action: new Action(() => System.Console.Write("I am Process #3")),
                desc: "Process 3");

            var process4 = new Process(
                id: 109875,
                action: new Action(() => System.Console.Write("I am Process #4")),
                desc: "Process 4");

            var process5 = new Process(
                id: 13579,
                action: new Action(() => System.Console.Write("I am Process #5")),
                desc: "Process 5");

            var process6 = new Process(
                id: 24680,
                action: new Action(() => System.Console.Write("I am Process #6")),
                desc: "Process 6");

            sysProcesses.Enqueue(process1, 1);
            sysProcesses.Enqueue(process2, 10);
            sysProcesses.Enqueue(process3, 5);
            sysProcesses.Enqueue(process4, 7);
            sysProcesses.Enqueue(process5, 3);
            sysProcesses.Enqueue(process6, 6);

            var leastPriorityProcess = sysProcesses.PeekAtMinPriority();

            Debug.Assert(leastPriorityProcess.Id == process1.Id, "Wrong process!");

            sysProcesses.DequeueMin();

            leastPriorityProcess = sysProcesses.PeekAtMinPriority();
            Debug.Assert(leastPriorityProcess.Id == process5.Id, "Wrong process!");

            sysProcesses.DequeueMin();

            leastPriorityProcess = sysProcesses.PeekAtMinPriority();
            Debug.Assert(leastPriorityProcess.Id == process3.Id, "Wrong process!");

            sysProcesses.DequeueMin();

            leastPriorityProcess = sysProcesses.PeekAtMinPriority();
            Debug.Assert(leastPriorityProcess.Id == process6.Id, "Wrong process!");

            leastPriorityProcess.Action();
        }