Exemple #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="problemInstance"></param>
        /// <param name="minDepth"></param>
        /// <param name="runner"></param>
        /// <param name="minCost">Not taken into account</param>
        public virtual void Setup(ProblemInstance problemInstance, int minDepth, MAM_Run runner, int minCost = -1)
        {
            this.instance = problemInstance;
            this.runner   = runner;
            this.ClearPrivateStatistics();
            this.totalCost            = 0;
            this.solutionDepth        = -1;
            this.targetCost           = int.MaxValue;
            this.lowLevelGeneratedCap = int.MaxValue;
            this.milliCap             = int.MaxValue;
            this.goalNode             = null;
            this.solution             = null;

            this.maxCost = int.MaxValue;
            //this.topMost = this.SetGlobals();

            this.minDepth = minDepth;
            CFMCbsNode root = new CFMCbsNode(instance.m_vAgents.Length, this); // Problem instance and various strategy data is all passed under 'this'.
            // Solve the root node - Solve with MMStar, and find conflicts
            bool solved = root.Solve();

            if (solved && root.totalCost <= this.maxCost)
            {
                this.openList.Add(root);
                this.highLevelGenerated++;
                this.closedList.Add(root, root);
            }
        }
 public CFMCbsNode(int numberOfAgents, CFM_CBS cbs, ushort[] agentsGroupAssignment = null)
 {
     this.cbs            = cbs;
     mamPlan             = null;
     mamCost             = -1;
     allSingleAgentCosts = new int[numberOfAgents];
     countsOfInternalAgentsThatConflict = new int[numberOfAgents];
     this.nodeConflicts = null;
     if (agentsGroupAssignment == null)
     {
         this.agentsGroupAssignment = new ushort[numberOfAgents];
         for (ushort i = 0; i < numberOfAgents; i++)
         {
             this.agentsGroupAssignment[i] = i;
         }
     }
     else
     {
         this.agentsGroupAssignment = agentsGroupAssignment.ToArray <ushort>();
     }
     agentNumToIndex = new Dictionary <int, int>();
     for (int i = 0; i < numberOfAgents; i++)
     {
         agentNumToIndex[this.cbs.GetProblemInstance().m_vAgents[i].agentIndex] = i;
     }
     depth                  = 0;
     replanSize             = 1;
     agentAExpansion        = ExpansionState.NOT_EXPANDED;
     agentBExpansion        = ExpansionState.NOT_EXPANDED;
     this.prev              = null;
     this.constraint        = null;
     this.solver            = solver;
     this.singleAgentSolver = singleAgentSolver;
 }
        /// <summary>
        /// Solves the entire node - finds a plan for every agent group.
        /// Since this method is only called for the root of the constraint tree, every agent is in its own group.
        /// </summary>
        /// <param name="depthToReplan"></param>
        /// <returns></returns>
        public bool Solve()
        {
            this.totalCost = 0;
            ProblemInstance            problem        = this.cbs.GetProblemInstance();
            HashSet <CFMCbsConstraint> newConstraints = this.GetConstraints(); // Probably empty as this is probably the root of the CT.

            // Constraints initiated with the problem instance
            //var constraints = (HashSet_U<CbsConstraint>)problem.parameters[MAPF_CBS.CONSTRAINTS];

            var constraints = new HashSet_U <CFMCbsConstraint>();


            Dictionary <int, int> agentsWithConstraints = null;

            if (constraints.Count != 0)
            {
                int maxConstraintTimeStep = constraints.Max <CFMCbsConstraint>(constraint => constraint.time);
                agentsWithConstraints = constraints.Select <CFMCbsConstraint, int>(constraint => constraint.agentNum).Distinct().ToDictionary <int, int>(x => x); // ToDictionary because there's no ToSet...
            }


            constraints.Join(newConstraints);

            // This mechanism of adding the constraints to the possibly pre-existing constraints allows having
            // layers of CBS solvers, each one adding its own constraints and respecting those of the solvers above it.

            // Solve using MMMStar

            HashSet <MMStarConstraint> mConstraints = importCBSConstraintsToMMStarConstraints(constraints);

            this.cbs.runner.SolveGivenProblem(problem, mConstraints);
            this.mamPlan = this.cbs.runner.plan;
            this.mamCost = this.cbs.runner.solutionCost;

            // Gather conflicts

            this.nodeConflicts = gatherConflicts();



            //if(MAM_Run.toPrint)
            //    printConflicts(allSingleAgentPlans);


            this.isGoal = this.nodeConflicts.Count == 0;
            return(true);
        }
Exemple #4
0
        /// <summary>
        /// Write to file a given instance
        /// </summary>
        /// <param name="instance">The instance to execute</param>
        public void WriteGivenProblem
        (
            ProblemInstance instance,
            MAM_ISolver solver,
            MAM_Plan currentPlan = null)
        {
            string initialH;

            if (solver.GetHeuristicCalculator().GetInitialH() == 0)
            {
                initialH = 0.ToString();
            }
            else if (solver.GetCostFunction() == CostFunction.SOC)
            {
                Tuple <double, int> bestInitH = solver.GetHeuristicCalculatorInitialH();
                double bestH      = bestInitH.Item1;
                double bestAgents = bestInitH.Item2;
                initialH = bestH.ToString();
            }
            else
            {
                Tuple <double, int> bestInitH = solver.GetHeuristicCalculatorInitialH();
                double bestH      = bestInitH.Item1;
                int    bestAgents = bestInitH.Item2;
                initialH = (bestH / bestAgents).ToString();
            }

            writeToFile(
                solver.GetName(),                               // solver name
                planningTime.ToString(),                        // planning time
                costFunctionToString(solver.GetCostFunction()), // cost function
                solver.GetSolutionSOCCost().ToString(),         // solution SOC cost
                solver.GetSolutionMakeSpanCost().ToString(),    // solution MakeSpan cost
                instanceId.ToString(),                          // instanceId
                instance.fileName,                              // file Name
                instance.m_vAgents.Length.ToString(),           // #Agents
                m_mapFileName,                                  // Map name
                solver.IsSolved().ToString(),                   // Success
                instance.m_nObstacles,                          // Obstacles
                solver.GetExpanded().ToString(),                // Expansions
                solver.GetGenerated().ToString(),               // Generates
                preprocessingTime.ToString(),                   // preprocessing time
                solver.GetHeuristicCalculator().GetName(),      // Heuristic Name
                initialH);                                      // Initial h value
        }
Exemple #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="problemInstance"></param>
        /// <param name="minDepth"></param>
        /// <param name="runner"></param>
        /// <param name="minCost">Not taken into account</param>
        public virtual void Setup
        (
            ProblemInstance problemInstance,
            int minDepth,
            MAM_Run runner,
            int minCost = -1,
            HashSet <MMStarConstraint> constraints = null
        )
        {
            this.instance = problemInstance;
            this.runner   = runner;
            this.ClearPrivateStatistics();
            this.totalCost        = 0;
            this.solutionDepth    = -1;
            this.milliCap         = int.MaxValue;
            this.goalLocation     = null;
            this.solution         = null;
            this.bestMakeSpanCost = int.MaxValue;
            this.bestSOCCost      = int.MaxValue;
            this.bestCostLocation = null;
            this.meetFlag         = false;
            this.success          = false;
            this.openList         = new MAM_OpenList(this);
            if (constraints != null)
            {
                this.constraints = constraints;
            }
            else
            {
                this.constraints = new HashSet <MMStarConstraint>();
            }

            AddSubSetHeuristics();
            foreach (MAM_AgentState agent in this.instance.m_vAgents)
            {
                agent.numOfAgentsInBestHeuristic = this.instance.m_vAgents.Length;
                CalculateH(agent, null);
                CalculateF(agent);
                closed(agent);
                openList.Add(agent);
            }
        }
Exemple #6
0
 public virtual MAM_Plan GetPlan()
 {
     if (this.solution == null)
     {
         if (bestCostLocation == null)
         {
             return(null);
         }
         Dictionary <int, Dictionary <int, MAM_AgentState> > solutionAgentsStatesDictionaries = closedList[bestCostLocation];
         Dictionary <int, MAM_AgentState> solutionAgentsStates = new Dictionary <int, MAM_AgentState>();
         foreach (int agent in solutionAgentsStatesDictionaries.Keys)
         {
             int            bestTimeForGivenAgent  = solutionAgentsStatesDictionaries[agent].Keys.Min();
             MAM_AgentState bestStateForGivenAgent = solutionAgentsStatesDictionaries[agent][bestTimeForGivenAgent];
             solutionAgentsStates.Add(agent, bestStateForGivenAgent);
         }
         this.solution = new MAM_Plan(solutionAgentsStates.Values.ToList());
     }
     return(this.solution);
 }
        /// <summary>
        /// Child from merge action constructor. FIXME: Code dup with previous constructor.
        /// </summary>
        /// <param name="father"></param>
        /// <param name="mergeGroupA"></param>
        /// <param name="mergeGroupB"></param>
        public CFMCbsNode(CFMCbsNode father, int mergeGroupA, int mergeGroupB)
        {
            mamPlan = null;
            mamCost = -1;
            this.allSingleAgentCosts = father.allSingleAgentCosts.ToArray <int>();
            this.countsOfInternalAgentsThatConflict = father.countsOfInternalAgentsThatConflict.ToArray <int>();
            this.nodeConflicts = null;

            this.agentsGroupAssignment = father.agentsGroupAssignment.ToArray <ushort>();
            this.agentNumToIndex       = father.agentNumToIndex;
            this.prev              = father;
            this.constraint        = null;
            this.depth             = (ushort)(this.prev.depth + 1);
            this.agentAExpansion   = ExpansionState.NOT_EXPANDED;
            this.agentBExpansion   = ExpansionState.NOT_EXPANDED;
            this.replanSize        = 1;
            this.solver            = father.solver;
            this.singleAgentSolver = father.singleAgentSolver;
            this.cbs = father.cbs;
        }
Exemple #8
0
        public bool Solve()
        {
            //this.SetGlobals(); // Again, because we might be resuming a search that was stopped.

            int initialEstimate = 0;

            if (openList.Count > 0)
            {
                initialEstimate = ((CFMCbsNode)openList.Peek()).totalCost;
            }

            int currentCost = -1;

            Console.WriteLine("maxTime: " + Constants.MAX_TIME);
            this.startTime = this.ElapsedMillisecondsTotal();

            while (openList.Count > 0)
            {
                //Console.WriteLine(this.ElapsedMilliseconds() / 10);
                //Console.WriteLine(openList.Count);
                //Console.WriteLine(closedList.Count);

                // Check if max time has been exceeded
                if (this.ElapsedMilliseconds() > Constants.MAX_TIME)
                {
                    this.totalCost = Constants.TIMEOUT_COST;
                    Console.WriteLine("Out of time");
                    this.solutionDepth = ((CFMCbsNode)openList.Peek()).totalCost - initialEstimate; // A minimum estimate
                    this.Clear();                                                                   // Total search time exceeded - we're not going to resume this search.
                    //this.CleanGlobals();
                    return(false);
                }

                var currentNode = (CFMCbsNode)openList.Remove();


                this.addToGlobalConflictCount(currentNode.GetConflict()); // TODO: Make CBS_GlobalConflicts use nodes that do this automatically after choosing a conflict

                if (debug)
                {
                    currentNode.Print();
                }

                if (currentNode.totalCost > currentCost) // Needs to be here because the goal may have a cost unseen before
                {
                    currentCost = currentNode.totalCost;
                    this.nodesExpandedWithGoalCost = 0;
                }
                else if (currentNode.totalCost == currentCost) // check needed because macbs node cost isn't exactly monotonous
                {
                    this.nodesExpandedWithGoalCost++;
                }

                // Check if node is the goal
                if (currentNode.GoalTest())
                {
                    //Debug.Assert(currentNode.totalCost >= maxExpandedNodeCostPlusH, "CBS goal node found with lower cost than the max cost node ever expanded: " + currentNode.totalCost + " < " + maxExpandedNodeCostPlusH);
                    // This is subtle, but MA-CBS may expand nodes in a non non-decreasing order:
                    // If a node with a non-optimal constraint is expanded and we decide to merge the agents,
                    // the resulting node can have a lower cost than before, since we ignore the non-optimal constraint
                    // because the conflict it addresses is between merged nodes.
                    // The resulting lower-cost node will have other constraints, that will raise the cost of its children back to at least its original cost,
                    // since the node with the non-optimal constraint was only expanded because its competitors that had an optimal
                    // constraint to deal with the same conflict apparently found the other conflict that I promise will be found,
                    // and so their cost was not smaller than this sub-optimal node.
                    // To make MA-CBS costs non-decreasing, we can choose not to ignore constraints that deal with conflicts between merged nodes.
                    // That way, the sub-optimal node will find a sub-optimal merged solution and get a high cost that will push it deep into the open list.
                    // But the cost would be to create a possibly sub-optimal merged solution where an optimal solution could be found instead, and faster,
                    // since constraints make the low-level heuristic perform worse.
                    // For an example for this subtle case happening, see problem instance 63 of the random grid with 4 agents,
                    // 55 grid cells and 9 obstacles.

                    if (debug)
                    {
                        Debug.WriteLine("-----------------");
                    }
                    this.totalCost     = (int)currentNode.mamCost;
                    this.solution      = currentNode.CalculateJointPlan();
                    this.solutionDepth = this.totalCost - initialEstimate;
                    this.goalNode      = currentNode; // Saves the single agent plans and costs
                    // The joint plan is calculated on demand.
                    this.Clear();                     // Goal found - we're not going to resume this search
                    //this.CleanGlobals();
                    this.solved = true;
                    return(true);
                }

                currentNode.ChooseConflict();

                // Expand
                bool wasUnexpandedNode = (currentNode.agentAExpansion == CFMCbsNode.ExpansionState.NOT_EXPANDED &&
                                          currentNode.agentBExpansion == CFMCbsNode.ExpansionState.NOT_EXPANDED);
                Expand(currentNode);
                if (wasUnexpandedNode)
                {
                    highLevelExpanded++;
                }
                // Consider moving the following into Expand()
                if (currentNode.agentAExpansion == CFMCbsNode.ExpansionState.EXPANDED &&
                    currentNode.agentBExpansion == CFMCbsNode.ExpansionState.EXPANDED) // Fully expanded
                {
                    currentNode.Clear();
                }
            }

            this.totalCost = Constants.NO_SOLUTION_COST;
            this.Clear(); // unsolvable problem - we're not going to resume it
            //this.CleanGlobals();
            return(false);
        }
Exemple #9
0
        /// <summary>
        /// Construct with chosen algorithms.
        /// </summary>
        public MAM_Run()
        {
            this.watch = Stopwatch.StartNew();


            // Preparing the solvers:
            solvers = new List <MAM_ISolver>();

            // FastMap Heuristic

            /*
             * //ISolver
             * MAM_ISolver MMStar_FastMapH_Makespan = new MM_Star(MM_Star.CostFunction.MakeSpan);
             * MAM_ISolver MMStar_FastMapH_SOC = new MM_Star(MM_Star.CostFunction.SOC);
             * MAM_HeuristicCalculator FastMapHCalculator = new FastMapHCalculator();
             * //MMStar_FastMapH_Makespan.SetHeuristic(FastMapHCalculator);
             * MMStar_FastMapH_SOC.SetHeuristic(FastMapHCalculator);
             */

            // Median Heuristic
            //ISolver
            MAM_ISolver             MMStar_MedianH_Makespan = new MM_Star(MM_Star.CostFunction.MakeSpan);
            MAM_ISolver             MMStar_MedianH_SOC      = new MM_Star(MM_Star.CostFunction.SOC);
            MAM_HeuristicCalculator MedianHCalculator       = new MedianHCalculator();

            MMStar_MedianH_Makespan.SetHeuristic(MedianHCalculator);
            //MMStar_MedianH_SOC.SetHeuristic(MedianHCalculator);

            // Clique Heuristic

            //ISolver
            MAM_ISolver             MMStar_CliqueH_Makespan = new MM_Star(MM_Star.CostFunction.MakeSpan);
            MAM_ISolver             MMStar_CliqueH_SOC      = new MM_Star(MM_Star.CostFunction.SOC);
            MAM_HeuristicCalculator CliqueHeuristic         = new CliqueHCalculator();

            MMStar_CliqueH_Makespan.SetHeuristic(CliqueHeuristic);
            //MMStar_CliqueH_SOC.SetHeuristic(CliqueHeuristic);


            // No Heuristic

            //ISolver
            MAM_ISolver             MMStar_ZeroH_Makespan = new MM_Star(MM_Star.CostFunction.MakeSpan);
            MAM_ISolver             MMStar_ZeroeH_SOC     = new MM_Star(MM_Star.CostFunction.SOC);
            MAM_HeuristicCalculator ZeroHeuristic         = new ZeroHCalculator();

            MMStar_ZeroH_Makespan.SetHeuristic(ZeroHeuristic);
            //MMStar_ZeroeH_SOC.SetHeuristic(ZeroHeuristic);


            //MAM_ISolver MMStar_LPH_Makespan = new MM_Star(MM_Star.CostFunction.MakeSpan);
            //MAM_HeuristicCalculator LPHCalculator = new LPHCalculator();
            //MMStar_LPH_Makespan.SetHeuristic(LPHCalculator);

            // *****  Makespan Solvers  *****
            //solvers.Add(MMStar_FastMapH_Makespan);
            //solvers.Add(MMStar_MedianH_Makespan);
            solvers.Add(MMStar_CliqueH_Makespan);
            //solvers.Add(MMStar_ZeroH_Makespan);

            // *****  SOC Solvers  *****
            //solvers.Add(MMStar_FastMapH_SOC);
            //solvers.Add(MMStar_MedianH_SOC);
            //solvers.Add(MMStar_CliqueH_SOC);
            //solvers.Add(MMStar_ZeroeH_SOC);


            outOfTimeCounters = new int[solvers.Count];
            for (int i = 0; i < outOfTimeCounters.Length; i++)
            {
                outOfTimeCounters[i] = 0;
            }

            this.plan = null;
        }
Exemple #10
0
        /// <summary>
        /// Solve given instance with a list of algorithms
        /// </summary>
        /// <param name="instance">The instance to solve</param>
        public bool SolveGivenProblem
        (
            ProblemInstance instance,
            HashSet <MMStarConstraint> constraints = null
        )
        {
            instanceId += 1;
            bool success = true;

            List <uint> agentList = Enumerable.Range(0, instance.m_vAgents.Length).Select <int, uint>(x => (uint)x).ToList <uint>(); // FIXME: Must the heuristics really receive a list of uints?

            // Solve using the different algorithms
            //Debug.WriteLine("Solving " + instance);

            MAM_AgentState[] vAgents = new MAM_AgentState[instance.GetNumOfAgents()];
            for (int agentIndex = 0; agentIndex < instance.GetNumOfAgents(); agentIndex++)
            {
                vAgents[agentIndex] = new MAM_AgentState(instance.m_vAgents[agentIndex]);
            }
            for (int i = 0; i < solvers.Count; i++)
            {
                solutionCost = -1;
                if (outOfTimeCounters[i] < Constants.MAX_FAIL_COUNT)
                {
                    GC.Collect();
                    GC.WaitForPendingFinalizers();

                    preprocessingTime = 0;
                    if (solvers[i].GetHeuristicCalculator().GetName() == "FastMap H")
                    {
                        this.startTime = this.ElapsedMillisecondsTotal();
                        solvers[i].GetHeuristicCalculator().init(instance);
                        solvers[i].GetHeuristicCalculator().preprocessing();
                        preprocessingTime = this.ElapsedMilliseconds();
                        Console.WriteLine("Preprocessing time in milliseconds: {0}", preprocessingTime);
                    }

                    this.run(solvers[i], instance, constraints);
                    MAM_AgentState[] vAgents2 = new MAM_AgentState[vAgents.Count()];
                    for (int agentIndex = 0; agentIndex < vAgents.Count(); agentIndex++)
                    {
                        vAgents2[agentIndex] = new MAM_AgentState(vAgents[agentIndex]);
                    }
                    instance.m_vAgents = vAgents2;

                    if (solvers[i].GetCostFunction() == CostFunction.MakeSpan)
                    {
                        solutionCost = solvers[i].GetSolutionMakeSpanCost();
                    }
                    else if (solvers[i].GetCostFunction() == CostFunction.SOC)
                    {
                        solutionCost = solvers[i].GetSolutionSOCCost();
                    }

                    MAM_Plan plan = null;
                    if (solvers[i].IsSolved()) // Solved successfully
                    {
                        plan = solvers[i].GetPlan();
                        if (toPrint)
                        {
                            Console.WriteLine();
                            plan.ToString();
                            Console.WriteLine();
                        }
                        outOfTimeCounters[i] = 0;
                        //Console.WriteLine("+SUCCESS+ (:");
                        this.plan = plan;
                    }
                    else
                    {
                        outOfTimeCounters[i]++;
                        Console.WriteLine("-FAILURE- ):");
                    }
                    planningTime = elapsedTime;
                }
                else if (toPrint)
                {
                    PrintNullStatistics(solvers[i]);
                }
            }
            return(true);
        }
 /// <summary>
 /// Worth doing because the node may always be in the closed list
 /// </summary>
 public void Clear()
 {
     this.mamPlan             = null;
     this.allSingleAgentCosts = null;
 }