public void Enqueue(T item) { RandomMeldablePriorityTree <T> node; if (_dictionary.TryGetValue(item, out node)) { _tree = _tree.DecreaseKey(node, item); } else { node = new RandomMeldablePriorityTree <T>(item); _tree = RandomMeldablePriorityTree <T> .Meld(_tree, node); } _dictionary[item] = node; }
/// <summary> /// Returns the best path. /// TPosition will be used as a dictionary key. /// </summary> /// <param name="getNeighbors">Given a position, return all the neighbors directly accessible from that position.</param> public static List <TNode> FindMinimalPath <TNode, TPosition>( TNode startingNode, Func <Dictionary <TPosition, RandomMeldablePriorityTree <TNode> >, TNode, bool> isDone, Func <TNode, IEnumerable <TNode> > getNeighbors) where TNode : SearchNodeBase <TPosition> { TNode best; var lookup = new Dictionary <TPosition, RandomMeldablePriorityTree <TNode> >(); var opens = new RandomMeldablePriorityTree <TNode>(startingNode); do { var lowest = opens.Element; // for dual direction, change this ending situation to be a lambda. // spawn two instances of the search method // in their lambda to see if they're done see if their position passed // exists in the lookup table here (and is open) // if that happens they are both done if (isDone.Invoke(lookup, lowest)) { best = lowest; break; } opens = opens.DeleteMin(); #if DEBUG if (opens != null && opens.Parent != null) { throw new InvalidOperationException("Expected opens to always point to the root."); } #endif lookup[lowest.Position] = null; // keep this below the isDone check foreach (var neighbor in getNeighbors.Invoke(lowest)) { RandomMeldablePriorityTree <TNode> existing; if (lookup.TryGetValue(neighbor.Position, out existing)) { if (existing == null) { continue; } opens = opens.DecreaseKey(existing, neighbor); } else { existing = new RandomMeldablePriorityTree <TNode>(neighbor); opens = RandomMeldablePriorityTree <TNode> .Meld(opens, existing); lookup[neighbor.Position] = existing; } } if (opens == null) { best = lowest; break; } } while (true); LastExpansionCount = lookup.Count; var ret = new List <TNode>(); while (best != null) { ret.Add(best); best = best.Parent as TNode; } ret.Reverse(); return(ret); }