Пример #1
0
        /// <summary>
        /// Setup the relevant data structures for a run (possibly under CBS).
        /// </summary>
        /// <param name="problemInstance"></param>
        /// <param name="minTimeStep"></param>
        /// <param name="runner"></param>
        /// <param name="CAT"></param>
        /// <param name="constraints"></param>
        /// <param name="positiveConstraints"></param>
        /// <param name="minCost"></param>
        /// <param name="maxCost"></param>
        /// <param name="mdd">FIXME: Not taken into account, just added to comply with ICbsSolver</param>
        public virtual void Setup(ProblemInstance problemInstance, int minTimeStep, Run runner,
                                  ConflictAvoidanceTable CAT       = null,
                                  ISet <CbsConstraint> constraints = null, ISet <CbsConstraint> positiveConstraints = null,
                                  int minCost = -1, int maxCost = int.MaxValue, MDD mdd = null)
        {
            this.minConflictsNotAvoided = int.MaxValue;
            this.survivedPruningHL      = 0;
            this.goalTestSkipped        = 0;
            this.generatedHL            = 1;
            this.expandedHL             = 1;
            this.generatedLL            = 0;
            this.expandedLL             = 0;
            this.totalCost = Constants.TIMEOUT_COST;

            this.problem = problemInstance;
            this.runner  = runner;

            closedList = new HashSet <CostTreeNode>();
            openList   = new Queue <CostTreeNode>();
            int[] costs = new int[problem.GetNumOfAgents()];
            for (int i = 0; i < problem.GetNumOfAgents(); i++)
            {
                costs[i] = Math.Max(problem.GetSingleAgentOptimalCost(problem.agents[i]), minTimeStep);  // TODO: Use the time of the latest constraint on each agent!
            }

            openList.Enqueue(new CostTreeNode(costs));          // The root
            this.initialEstimate = openList.Peek().costs.Sum(); // TODO: Support other cost functions

            // Store parameters used by the Independence Detection algorithm
            this.maxCost = maxCost;
            this.minCost = minCost;

            this.CAT = CAT;
        }
Пример #2
0
 public override void Setup(ProblemInstance problemInstance, int minTimeStep, Run runner,
                            ConflictAvoidanceTable CAT, ISet <CbsConstraint> constraints, ISet <CbsConstraint> positiveConstraints,
                            int minCost, int maxCost, MDD mdd)
 {
     base.Setup(problemInstance, minTimeStep, runner, CAT, constraints, positiveConstraints, minCost, maxCost, mdd);
     this.generatedAndDiscarded = 0;
     this.expandedFullStates    = 0;
 }
Пример #3
0
 public override void Setup(ProblemInstance problemInstance, int minDepth, Run runner,
                            ConflictAvoidanceTable CAT       = null,
                            ISet <CbsConstraint> constraints = null, ISet <CbsConstraint> positiveConstraints = null,
                            int minCost = -1, int maxCost = int.MaxValue, MDD mdd = null)
 {
     base.Setup(problemInstance, minDepth, runner, CAT, constraints, positiveConstraints,
                minCost, maxCost, mdd);
     this.expandedFullStates = 0;
 }
Пример #4
0
 public override void Setup(ProblemInstance problemInstance, int minTimeStep, Run runner,
                            ConflictAvoidanceTable CAT       = null,
                            ISet <CbsConstraint> constraints = null, ISet <CbsConstraint> positiveConstraints = null,
                            int minCost = -1, int maxCost = int.MaxValue, MDD mdd = null)
 {
     edgesMatrix        = new int[problemInstance.agents.Length, problemInstance.GetMaxX() * problemInstance.GetMaxY() + problemInstance.GetMaxY(), Move.NUM_NON_DIAG_MOVES];
     edgesMatrixCounter = 0;
     base.Setup(problemInstance, minTimeStep, runner, CAT, constraints, positiveConstraints, minCost, maxCost, mdd);
 }
Пример #5
0
 public MDDNode(TimedMove move, int numOfAgents, MDD mdd, bool supportPruning = true)
 {
     this.move = move;
     this.mdd  = mdd;
     children  = new LinkedList <MDDNode>();
     parents   = new LinkedList <MDDNode>();
     if (supportPruning)
     {
         coexistingNodesFromOtherMdds = new HashSet <MDDNode> [numOfAgents];
         for (int i = 0; i < numOfAgents; i++)
         {
             coexistingNodesFromOtherMdds[i] = new HashSet <MDDNode>(5);  // Each level is small
         }
     }
 }
Пример #6
0
 public MDD(MDD other, CbsConstraint newConstraint)
     : this(other)
 {
     List <MDDNode> toDelete = new List <MDDNode>();
     foreach (MDDNode mddNode in this.levels[newConstraint.time])
     {
         if (newConstraint.move.Equals(mddNode.move))
         {
             toDelete.Add(mddNode);
         }
     }
     Trace.Assert(toDelete.Count > 0);
     foreach (MDDNode mddNode in toDelete)
     {
         mddNode.delete();
     }
 }
Пример #7
0
 public MDD(MDD other, ISet <TimedMove> reserved) : this(other)
 {
     ISet <int> times_of_reservations = reserved.Select(move => move.time).ToHashSet();
     var        toDelete = new List <MDDNode>();
     foreach (int time in times_of_reservations)
     {
         foreach (MDDNode mddNode in this.levels[time])
         {
             if (mddNode.move.IsColliding(reserved))
             {
                 toDelete.Add(mddNode);
             }
         }
         foreach (MDDNode mddNode in toDelete)
         {
             mddNode.delete();
         }
         toDelete.Clear();
     }
 }
Пример #8
0
        public override SinglePlan[] Solve(ConflictAvoidanceTable CAT)
        {
            MDD[] match      = new MDD[2];
            bool  Converging = true;

            int[] changed          = new int[allMDDs.Length];
            int   currentIteration = 0;

            MDD.PruningDone conflictStatus = MDD.PruningDone.NOTHING;

            while (Converging)
            {
                currentIteration++;
                Converging = false;

                for (int i = allMDDs.Length - 1; i >= 0; i--)
                {
                    for (int j = i + 1; j < allMDDs.Length; j++)
                    {
                        if (changed[i] >= currentIteration - 1 || changed[j] >= currentIteration - 1) // If at least one of the two MDDs was changed during the last iteration
                        {
                            int matchCounterIncrement;
                            (conflictStatus, matchCounterIncrement) = allMDDs[i].SyncMDDs(allMDDs[j], this.syncSize == 3);
                            this.matchCounter += matchCounterIncrement;

                            if (conflictStatus == MDD.PruningDone.EVERYTHING)
                            {
                                return(null);
                            }

                            else if (conflictStatus == MDD.PruningDone.SOME)
                            {
                                changed[i] = currentIteration;
                                Converging = true;
                            }

                            (conflictStatus, matchCounterIncrement) = allMDDs[i].SyncMDDs(allMDDs[j], this.syncSize == 3);
                            this.matchCounter += matchCounterIncrement;

                            if (conflictStatus == MDD.PruningDone.EVERYTHING)
                            {
                                return(null);
                            }

                            else if (conflictStatus == MDD.PruningDone.SOME)
                            {
                                changed[i] = currentIteration;
                                Converging = true;
                            }
                        }
                    }
                }
            }
            this.solver.survivedPruningHL++;
            if (allMDDs[0].levels == null)
            {
                return(null);
            }
            A_Star_MDDs findSolution = new A_Star_MDDs(allMDDs, runner, CAT);

            SinglePlan[] ans = findSolution.Solve();
            generated           = findSolution.generated;
            expanded            = findSolution.expanded;
            conflictsNotAvoided = findSolution.conflictCount;
            return(ans);
        }
Пример #9
0
        public override SinglePlan[] Solve(ConflictAvoidanceTable CAT)
        {
            A_Star_MDDs findSolution;

            SinglePlan[]     subCheck;
            MDD[]            match;
            MddMatchAndPrune matcher = new MddMatchAndPrune(runner, this);

            foreach (MDD checkValid in allMDDs)
            {
                if (checkValid.levels == null)
                {
                    return(null);
                }
            }

            if (maxGroupChecked >= 2)
            {
                match = new MDD[2];
                for (int i = allMDDs.Length - 1; i >= 0; i--)
                {
                    for (int j = i + 1; j < allMDDs.Length; j++)
                    {
                        match[0] = allMDDs[i];
                        match[1] = allMDDs[j];
                        //matcher.initialize(match);

                        //if (matcher.pruneMDDs() == false)
                        findSolution = new A_Star_MDDs(match, runner, CAT);

                        subCheck = findSolution.Solve();
                        if (subCheck == null || subCheck[0] == null)
                        {
                            return(null);
                        }
                    }
                }
            }
            if (maxGroupChecked >= 3)
            {
                match = new MDD[3];
                for (int i = allMDDs.Length - 2; i >= 0; i--)
                {
                    for (int j = i + 1; j < allMDDs.Length - 1; j++)
                    {
                        for (int t = j + 1; t < allMDDs.Length; t++)
                        {
                            match[0] = allMDDs[i];
                            match[1] = allMDDs[j];
                            match[2] = allMDDs[t];
                            //matcher.initialize(match);

                            //if (matcher.pruneMDDs() == false)
                            findSolution = new A_Star_MDDs(match, runner, CAT);

                            subCheck = findSolution.Solve();
                            if (subCheck == null || subCheck[0] == null)
                            {
                                return(null);
                            }
                        }
                    }
                }
            }
            if (maxGroupChecked >= 4)
            {
                match = new MDD[4];
                for (int i = allMDDs.Length - 3; i >= 0; i--)
                {
                    for (int j = i + 1; j < allMDDs.Length - 2; j++)
                    {
                        for (int t = j + 1; t < allMDDs.Length - 1; t++)
                        {
                            for (int m = t + 1; m < allMDDs.Length; m++)
                            {
                                match[0] = allMDDs[i];
                                match[1] = allMDDs[j];
                                match[2] = allMDDs[t];
                                match[3] = allMDDs[m];
                                //matcher.initialize(match);

                                //if (matcher.pruneMDDs() == false)
                                findSolution = new A_Star_MDDs(match, runner, CAT);

                                subCheck = findSolution.Solve();
                                if (subCheck == null || subCheck[0] == null)
                                {
                                    return(null);
                                }
                            }
                        }
                    }
                }
            }
            this.solver.survivedPruningHL++;
            if (allMDDs[0].levels == null)
            {
                return(null);
            }
            findSolution = new A_Star_MDDs(allMDDs, runner, CAT);
            SinglePlan[] ans = findSolution.Solve();
            generated           = findSolution.generated;
            expanded            = findSolution.expanded;
            conflictsNotAvoided = findSolution.conflictCount;
            conflictCounts      = findSolution.GetExternalConflictCounts();
            conflictTimes       = findSolution.GetConflictTimes();
            return(ans);
        }
Пример #10
0
        /// <summary>
        /// Match and prune MDD according to another MDD.
        /// </summary>
        /// <param name="other"></param>
        /// <param name="checkTriples">If true, use the "3E" method.</param>
        /// <returns>How much pruning was done, and by how much the matchCounter should be incremented</returns>
        public (PruningDone, int) SyncMDDs(MDD other, bool checkTriples)
        {
            int         matchCounter = 0;
            PruningDone pruningDone  = PruningDone.NOTHING;

            if (this.levels == null || other.levels == null) // Either of the MDDs was already completely pruned already
            {
                return(PruningDone.EVERYTHING, matchCounter);
            }

            // Cheaply find the coexisting nodes on level zero - all nodes coexist because agent starting points never collide
            var coexistingNodesForLevelZero = new HashSet <MDDNode>()
            {
                other.levels[0].First.Value
            };

            levels[0].First.Value.SetCoexistingNodes(coexistingNodesForLevelZero, other.mddNum);

            for (int i = 1; i < levels.Length; i++)
            {
                LinkedListNode <MDDNode> linkedListNode = levels[i].First;
                while (linkedListNode != null && linkedListNode.List != null)
                {
                    var node = linkedListNode.Value;
                    linkedListNode = linkedListNode.Next;  // Must be before any potential deletions!

                    var coexistingForNode = new HashSet <MDDNode>();

                    // Go over all the node's parents and test their coexisting nodes' children for coexistance with this node
                    LinkedListNode <MDDNode> parentLinkedListNode = node.parents.First;
                    while (parentLinkedListNode != null)
                    {
                        var  parent      = parentLinkedListNode.Value;
                        bool validParent = false;
                        foreach (MDDNode parentCoexistingNode in parent.coexistingNodesFromOtherMdds[other.mddNum])
                        {
                            foreach (MDDNode childOfParentCoexistingNode in parentCoexistingNode.children)
                            {
                                if (node.move.IsColliding(childOfParentCoexistingNode.move) == false)
                                {
                                    if (checkTriples == false ||
                                        node.IsCoexistingWithOtherMDDs(childOfParentCoexistingNode, other.mddNum)) // The "3" part
                                    {
                                        validParent = true;

                                        if (coexistingForNode.Add(childOfParentCoexistingNode))
                                        {
                                            matchCounter++;
                                        }
                                    }
                                }
                                else
                                {
                                }
                            }
                        }

                        parentLinkedListNode = parentLinkedListNode.Next;  // Must be before any potential deletions!
                        if (!validParent)
                        {
                            node.removeParent(parent); // And continue up the levels if necessary
                            pruningDone = PruningDone.SOME;
                        }
                    }
                    node.SetCoexistingNodes(coexistingForNode, other.mddNum);
                    if (node.getCoexistingNodesCount(other.mddNum) == 0)
                    {
                        node.delete();
                        pruningDone = PruningDone.SOME;
                    }
                }
                if (levels == null || levels[0].Count == 0)
                {
                    return(PruningDone.EVERYTHING, matchCounter);
                }
            }
            return(pruningDone, matchCounter);
        }
Пример #11
0
        public MDD(MDD other)
        {
            this.problem        = other.problem;
            this.mddNum         = other.mddNum;
            this.agentNum       = other.agentNum;
            this.numOfAgents    = other.numOfAgents;
            this.cost           = other.cost;
            this.supportPruning = other.supportPruning;
            if (other.levels == null)
            {
                this.levels = null;
                return;
            }
            this.levels = new LinkedList <MDDNode> [other.levels.Length];
            int numOfLevels = other.levels.Length - 1;  // Level zero not counted

            for (int i = 0; i < levels.Length; i++)
            {
                levels[i] = new LinkedList <MDDNode>();
            }
            Dictionary <MDDNode, MDDNode> originals = new Dictionary <MDDNode, MDDNode>();
            Dictionary <MDDNode, MDDNode> copies    = new Dictionary <MDDNode, MDDNode>();
            MDDNode copiedRoot = new MDDNode(new TimedMove(other.levels[0].First.Value.move),
                                             numOfAgents, this, supportPruning); // Root
            LinkedListNode <MDDNode> llNode = new LinkedListNode <MDDNode>(copiedRoot);

            copiedRoot.setMyNode(llNode);
            llNode.Value.startOrGoal = true;
            levels[0].AddFirst(llNode);
            originals.Add(copiedRoot, other.levels[0].First.Value);
            copies.Add(other.levels[0].First.Value, copiedRoot);

            for (int i = 0; i < numOfLevels; i++) // For each level, populate the _next_ level
            {
                foreach (MDDNode copiedNode in levels[i])
                {
                    foreach (MDDNode originalChildNode in originals[copiedNode].children)
                    {
                        MDDNode copiedChild;
                        if (copies.ContainsKey(originalChildNode) == false)
                        {
                            copiedChild = new MDDNode(originalChildNode.move, numOfLevels, this, supportPruning);
                            originals.Add(copiedChild, originalChildNode);
                            copies.Add(originalChildNode, copiedChild);
                            llNode = new LinkedListNode <MDDNode>(copiedChild);
                            copiedChild.setMyNode(llNode);
                            levels[i + 1].AddLast(llNode);
                        }
                        else
                        {
                            copiedChild = copies[originalChildNode];
                        }
                        copiedNode.addChild(copiedChild);  // forward edge
                        copiedChild.addParent(copiedNode); // backward edge
                    }
                }
            }

            originals.Clear();
            copies.Clear();

            foreach (MDDNode goal in levels[numOfLevels]) // The goal may be reached in more than one direction
            {
                goal.startOrGoal = true;
            }
        }