Beispiel #1
0
        /**
         * Computes a node whose sequence of recursive parents corresponds to a
         * sequence of actions which leads from the initial state of the original
         * problem to the state of node1 and then to the initial state of the
         * reverse problem, following reverse actions to parents of node2. Note that
         * both nodes must be linked to the same state. Success is not guaranteed if
         * some actions cannot be reversed.
         */
        private Node <S, A> getSolution(IProblem <S, A> orgP, ExtendedNode node1, ExtendedNode node2)
        {
            if (!node1.getState().Equals(node2.getState()))
            {
                throw new NotSupportedException("states not equal");
            }

            Node <S, A> orgNode = node1.getProblemIndex() == ORG_P_IDX ? node1 : node2;
            Node <S, A> revNode = node1.getProblemIndex() == REV_P_IDX ? node1 : node2;

            while (revNode.getParent() != null)
            {
                A action = getReverseAction(orgP, revNode);
                if (action != null)
                {
                    S      nextState = revNode.getParent().getState();
                    double stepCosts = orgP.getStepCosts(revNode.getState(), action, nextState);
                    orgNode = nodeExpander.createNode(nextState, orgNode, action, stepCosts);
                    revNode = revNode.getParent();
                }
                else
                {
                    return(null);
                }
            }
            metrics.set(METRIC_PATH_COST, orgNode.getPathCost());
            return(orgNode);
        }
Beispiel #2
0
        private ExtendedNode getCorrespondingNodeFromOtherProblem(ExtendedNode node)
        {
            ExtendedNode result = explored.Get(1 - node.getProblemIndex()).Get(node.getState());

            // Caution: The goal test of the original problem should always include
            // the root node of the reverse problem as that node might not yet have
            // been explored yet. This is important if the reverse problem does not
            // provide reverse actions for all original problem actions.
            if (result == null && node.getProblemIndex() == ORG_P_IDX && node.getState().Equals(goalStateNode.getState()))
            {
                result = goalStateNode;
            }
            return(result);
        }
Beispiel #3
0
        /**
         * Implements an approximation algorithm for bidirectional problems with
         * exactly one initial and one goal state. The algorithm guarantees the
         * following: If the queue is ordered by path costs (uniform cost search),
         * the path costs of the solution will be less or equal to the costs of the
         * best solution multiplied with two. Especially, if all step costs are
         * equal and the reverse problem provides reverse actions for all actions of
         * the original problem, the path costs of the result will exceed the
         * optimal path by the costs of one step at maximum.
         *
         * @param problem
         *            a bidirectional search problem
         * @param frontier
         *            the data structure to be used to decide which node to be
         *            expanded next
         *
         * @return a list of actions to the goal if the goal was found, a list
         *         containing a single NoOp Action if already at the goal, or an
         *         empty list if the goal could not be found.
         */
        public override Node <S, A> findNode(IProblem <S, A> problem, ICollection <Node <S, A> > frontier)
        {
            if (!(problem is IBidirectionalProblem <S, A>))
            {
                throw new IllegalArgumentException("problem is not a BidirectionalProblem<S, A>");
            }
            this.isCancelled = false;
            nodeExpander.useParentLinks(true); // bidirectional search needs parents!
            this.frontier = frontier;
            clearMetrics();
            explored.Get(ORG_P_IDX).Clear();
            explored.Get(REV_P_IDX).Clear();

            IProblem <S, A> orgP = ((IBidirectionalProblem <S, A>)problem).getOriginalProblem();
            IProblem <S, A> revP = ((IBidirectionalProblem <S, A>)problem).getReverseProblem();
            ExtendedNode    initStateNode;

            initStateNode = new ExtendedNode(nodeExpander.createRootNode(orgP.getInitialState()), ORG_P_IDX);
            goalStateNode = new ExtendedNode(nodeExpander.createRootNode(revP.getInitialState()), REV_P_IDX);

            if (orgP.getInitialState().Equals(revP.getInitialState()))
            {
                return(getSolution(orgP, initStateNode, goalStateNode));
            }

            // initialize the frontier using the initial state of the problem
            addToFrontier(initStateNode);
            addToFrontier(goalStateNode);

            while (!isFrontierEmpty() && !this.isCancelled)
            {
                // choose a leaf node and remove it from the frontier
                ExtendedNode nodeToExpand = (ExtendedNode)removeFromFrontier();
                ExtendedNode nodeFromOtherProblem;

                // if the node contains a goal state then return the
                // corresponding solution
                if (!earlyGoalTest && (nodeFromOtherProblem = getCorrespondingNodeFromOtherProblem(nodeToExpand)) != null)
                {
                    return(getSolution(orgP, nodeToExpand, nodeFromOtherProblem));
                }

                // expand the chosen node, adding the resulting nodes to the
                // frontier
                foreach (Node <S, A> s in nodeExpander.expand(nodeToExpand, problem))
                {
                    ExtendedNode successor = new ExtendedNode(s, nodeToExpand.getProblemIndex());
                    if (!isReverseActionTestEnabled || nodeToExpand.getProblemIndex() == ORG_P_IDX ||
                        getReverseAction(orgP, successor) != null)
                    {
                        if (earlyGoalTest &&
                            (nodeFromOtherProblem = getCorrespondingNodeFromOtherProblem(successor)) != null)
                        {
                            return(getSolution(orgP, successor, nodeFromOtherProblem));
                        }

                        addToFrontier(successor);
                    }
                }
            }
            // if the frontier is empty then return failure
            return(null);
        }
Beispiel #4
0
        private void setExplored(Node <S, A> node)
        {
            ExtendedNode eNode = (ExtendedNode)node;

            explored.Get(eNode.getProblemIndex()).Put(eNode.getState(), eNode);
        }
Beispiel #5
0
        private bool isExplored(Node <S, A> node)
        {
            ExtendedNode eNode = (ExtendedNode)node;

            return(explored.Get(eNode.getProblemIndex()).ContainsKey(eNode.getState()));
        }