/// <summary>Runs the Greedy search algorithm algorithm on a graph.</summary> /// <param name="start">The node to start at.</param> /// <param name="neighbors">Step function for all neigbors of a given node.</param> /// <param name="heuristic">Computes the heuristic value of a given node in a graph.</param> /// <param name="goal">Predicate for determining if we have reached the goal node.</param> /// <returns>Stepper of the shortest path or null if no path exists.</returns> public static Stepper <T> Greedy(T start, Neighbors neighbors, Heuristic heuristic, Goal goal) { // using a heap (aka priority queue) to store nodes based on their computed heuristic value Heap <Greedy_Node> fringe = new HeapArray <Greedy_Node>( // NOTE: I just reversed the order of left and right because smaller values are higher priority (Greedy_Node left, Greedy_Node right) => { return(Compute <Math> .Compare(right.Priority, left.Priority)); }); // push starting node Greedy_Node start_node = new Greedy_Node(null, start, default(Math)); fringe.Enqueue(start_node); // run the algorithm while (fringe.Count != 0) { Greedy_Node current = fringe.Dequeue(); if (goal(current.Value)) { return(Greedy_BuildPath(current)); } else { neighbors(current.Value, (T neighbor) => { Greedy_Node newNode = new Greedy_Node(current, neighbor, heuristic(neighbor)); fringe.Enqueue(newNode); }); } } return(null); // goal node was not reached (no path exists) }
// methods #region private static Stepper<T> Greedy_BuildPath(Greedy_Node node) /// <summary>Builds the path from resulting from the A* algorithm.</summary> /// <param name="node">The resulting final node fromt he A* algorithm.</param> /// <returns>A stepper function of the computed path frmo the A* algorithm.</returns> private static Stepper <T> Greedy_BuildPath(Greedy_Node node) { Greedy_PathNode end; Greedy_PathNode start = Greedy_BuildPath(node, out end); return((Step <T> step) => { Greedy_PathNode current = start; while (current != null) { step(current.Value); current = current.Next; } }); }
private static Greedy_PathNode Greedy_BuildPath(Greedy_Node currentNode, out Greedy_PathNode currentPathNode) { if (currentNode.Previous == null) { Greedy_PathNode start = new Greedy_PathNode(currentNode.Value); currentPathNode = start; return(start); } else { Greedy_PathNode previous; Greedy_PathNode start = Greedy_BuildPath(currentNode.Previous, out previous); currentPathNode = new Greedy_PathNode(currentNode.Value); previous.Next = currentPathNode; return(start); } }
public Greedy_Node(Greedy_Node previous, T value, Math priority) { this._previous = previous; this._value = value; this._priority = priority; }