// Kruskal's algorithm is (get the min weight edge from PQ and keep adding to tree if it does not cause a cycle // repeat until v-1 edges are added to the tree or until all edges are exhausted. private void Kruskal(EdgeWeightedGraph <V> graph) { PriorityQueueHeap <Edge <V> > _pq = new PriorityQueueHeap <Edge <V> >(); foreach (Edge <V> edge in graph.Edges()) { _pq.Insert(edge); } DisjointSets_UnionFind uf = new DisjointSets_UnionFind(); // This should be extractMin (but we can subtract the weight from 100 or something // such that the min weight becomes the max item while (!_pq.IsEmpty && _queue.Count < graph.TotalVertices() - 1) { var item = _pq.Extract(); V start = item.Either; V end = item.Other; var startHash = ModedHash(start.GetHashCode()); var endHash = ModedHash(end.GetHashCode()); // Union find works in iterated logarithm since path compression helps move the children // near the root or parent of the tree. if (!uf.Connected(startHash, endHash)) { uf.MakeSet(startHash); uf.MakeSet(endHash); uf.Union(startHash, endHash); _queue.Enqueue(item); } } }
private void LazyPrimVisit(EdgeWeightedGraph <V> graph, V either, Boolean[] marked, PriorityQueueHeap <Edge <V> > pq) { marked[ModedHash(either.GetHashCode())] = true; foreach (var edge in graph.Adjacency(either)) { if (!marked[ModedHash(edge.GetHashCode())]) { pq.Insert(edge); } } }
public List <SearchNode> Search(TData root, float costLimit = float.MaxValue) { NextCostLimitThreshhold = float.MaxValue; var priorityQueue = new PriorityQueueHeap <SearchNode>(); // Start at root var rootNode = new SearchNode { Data = root, Action = default(TAction), Parent = null, Cost = 0, EstimatedRemainingCost = Config.HeuristicFunc(root), }; priorityQueue.Insert(rootNode.EstimatedTotalCost, rootNode); while (!priorityQueue.IsEmpty) { CurrentNode = priorityQueue.ExtractTop(); if (Config.IsGoalFunc(CurrentNode)) { return(ReconstructPath(CurrentNode)); } var actions = Config.ActionsListFunc(CurrentNode); foreach (var action in actions) { var newNode = new SearchNode { Parent = CurrentNode, Data = Config.ActionApplierFunc(CurrentNode, action), Action = action, Cost = CurrentNode.Cost + Config.ActionCostFunc(CurrentNode, action), }; newNode.EstimatedRemainingCost = Config.HeuristicFunc(newNode.Data); if (newNode.Cost <= costLimit) { priorityQueue.Insert(newNode.EstimatedTotalCost, newNode); OnNodeGenerated(); } else { if (newNode.Cost < NextCostLimitThreshhold) { NextCostLimitThreshhold = newNode.Cost; } } } OnNodeExpanded(); NodesRetainedCount = priorityQueue.Count; } return(null); }