public void Test_Update_Max_Throws_Argument()
        {
            IndexedHeap <string> heap = new IndexedHeap <string>(HeapMode.MaxHeap, 1);

            heap.Add("test");

            Assert.Throws <ArgumentException>(() => heap.Update(1, "not test"));
        }
        public void Test_ExtractTop_Max_Remove_From_Index()
        {
            IndexedHeap <byte> heap = (IndexedHeap <byte>) this.CreateFullIHeap(HeapMode.MaxHeap);

            byte value = heap.ExtractTop();

            Assert.Throws <ArgumentException>(() => heap.GetIndex(value));
        }
Example #3
0
        public List <Edge> DijkstraShortestPath(Vertex source, Vertex destination = default)
        {
            var sp = new Dictionary <Vertex, Edge>();

            if (!adjacencyList.Any())
            {
                return(sp.Values.ToList());
            }

            var vertexToPathCost = new Dictionary <Vertex, PathCost>();

            // Min Heap storing accumulated min cost for reaching target node greedily
            var minHeapNodes = new IndexedHeap <PathCost>(
                new List <PathCost> {
                (vertexToPathCost[source] = new PathCost(source, 0))
            },
                compareFunc: (p1, p2) => p1.cost.CompareTo(p2.cost));

            foreach (var vertex in adjacencyList.Keys)
            {
                if (vertex == source)
                {
                    continue;
                }

                minHeapNodes.Push(vertexToPathCost[vertex] = new PathCost(vertex, int.MaxValue));
            }

            // Greedy strategy: Select the path that minimized the accumulated cost up to this node
            // Traverse the node by min cost
            while (minHeapNodes.Any())
            {
                var minNode = minHeapNodes.Pop();

                // Visit all the neighbors and update the corresponding cost
                foreach (var edge in adjacencyList[minNode.vertex])
                {
                    // Check that the current cost of reaching the adjacent node is less than the current one
                    if (minHeapNodes.Contains(vertexToPathCost[edge.destination]) && minNode.cost + edge.weight < vertexToPathCost[edge.destination].cost)
                    {
                        vertexToPathCost[edge.destination].cost = minNode.cost + edge.weight;
                        sp[edge.destination] = edge;

                        // Sift up the heap starting from the current index (log n)
                        minHeapNodes.SiftUp(fromIndex: minHeapNodes.IndexOf(vertexToPathCost[edge.destination]));
                    }
                }

                if (minNode.vertex.Equals(destination))
                {
                    break;
                }
            }

            return(sp.Values.ToList());
        }
        public void Test_GetIndex_Max()
        {
            IndexedHeap <byte> heap = (IndexedHeap <byte>) this.CreateInstance(HeapMode.MaxHeap, 5);

            heap.Add(10);
            heap.Add(20);
            heap.Add(30);
            heap.Add(40);
            heap.Add(50);

            Assert.Equal(1, heap.GetIndex(50));
        }
        public void Test_Update_Min()
        {
            IndexedHeap <byte> heap = (IndexedHeap <byte>) this.CreateInstance(HeapMode.MinHeap, 5);

            heap.Add(10);
            heap.Add(20);
            heap.Add(30);
            heap.Add(40);
            heap.Add(50);

            int index = heap.GetIndex(40);

            heap.Update(index, 5);

            Assert.Equal(1, heap.GetIndex(5));
            Assert.Equal(2, heap.GetIndex(10));
        }
Example #6
0
        public List <Edge> PrimsMinimumSpanningTree()
        {
            var mst = new Dictionary <Vertex, Edge>();

            if (!adjacencyList.Any())
            {
                return(mst.Values.ToList());
            }

            var vertexToMinCost = new Dictionary <Vertex, PathCost>();

            // Min Heap storing min cost of the spanning tree
            var minHeapNodes = new IndexedHeap <PathCost>(
                new List <PathCost> {
                (vertexToMinCost[adjacencyList.Keys.First()] = new PathCost(adjacencyList.Keys.First(), 0))
            }, (p1, p2) => p1.cost.CompareTo(p2.cost));

            foreach (var vertex in adjacencyList.Keys.Skip(1))
            {
                minHeapNodes.Push(vertexToMinCost[vertex] = new PathCost(vertex, int.MaxValue));
            }

            // Traverse the node by min cost
            // Greedy strategy: Select the edge that minimize the cost for reaching node from its neighbors
            while (minHeapNodes.Any())
            {
                var minNode = minHeapNodes.Pop();

                // Visit all the neighbors and update the corresponding cost
                foreach (var edge in adjacencyList[minNode.vertex])
                {
                    // Check that the current cost of reaching the adjacent node is less than the current one
                    if (minHeapNodes.Contains(vertexToMinCost[edge.destination]) && edge.weight < vertexToMinCost[edge.destination].cost)
                    {
                        vertexToMinCost[edge.destination].cost = edge.weight;
                        mst[edge.destination] = edge;

                        // Sift up the heap starting from the current index (log n)
                        minHeapNodes.SiftUp(fromIndex: minHeapNodes.IndexOf(vertexToMinCost[edge.destination]));
                    }
                }
            }

            return(mst.Values.ToList());
        }
        public void Test_Update_Max_Throws_ArgumentOutOfRange()
        {
            IndexedHeap <byte> heap = (IndexedHeap <byte>) this.CreateInstance(HeapMode.MaxHeap, 1);

            Assert.Throws <ArgumentOutOfRangeException>(() => heap.Update(100, default));
        }
        public void Test_GetIndex_Max_Throws_Argument()
        {
            IndexedHeap <byte> heap = (IndexedHeap <byte>) this.CreateInstance(HeapMode.MaxHeap, 1);

            Assert.Throws <ArgumentException>(() => heap.GetIndex(255));
        }