Пример #1
0
        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;
        }
Пример #2
0
        /// <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);
        }