public void Setup(ProblemInstance problemInstance, Run runner) { this.equivalenceWasOn = AgentState.EquivalenceOverDifferentTimes == true; AgentState.EquivalenceOverDifferentTimes = false; globalConflictsCounter = new int[problemInstance.agents.Length][]; for (int i = 0; i < globalConflictsCounter.Length; i++) { globalConflictsCounter[i] = new int[i]; for (int j = 0; j < i; j++) { globalConflictsCounter[i][j] = 0; } } this.instance = problemInstance; this.runner = runner; //root = new CbsNode(instance.agents.Length, problemInstance, this.solver, this.lowLevelSolver, this); // FIXME! this.highLevelExpanded = 0; this.highLevelGenerated = 1; maxSizeGroup = 1; this.totalCost = 0; if (problemInstance.parameters.ContainsKey(IndependenceDetection.MAX_COST_KEY)) { this.maxCost = (int)(problemInstance.parameters[IndependenceDetection.MAX_COST_KEY]); } else { this.maxCost = int.MaxValue; } if (problemInstance.parameters.ContainsKey(CBS.CAT) == false) // Top-most CBS only { problemInstance.parameters[CBS.CAT] = new HashSet_U <TimedMove>(); problemInstance.parameters[CBS.CONSTRAINTS] = new HashSet_U <CbsConstraint>(); problemInstance.parameters[CBS.MUST_CONSTRAINTS] = new List <CbsConstraint>(); this.topMost = true; } else { this.topMost = false; } minDepth = 0; }
public void RunNathanExperimentSet(String scenMapFileName) { try { ProblemInstance.Import(Path.Combine(Directory.GetCurrentDirectory(), scenMapFileName)); } catch (Exception e) { StringBuilder sb = new StringBuilder(); sb.Append("ERROR! occured at: " + DateTime.Now.ToString()); sb.Append(e); // flush every 20 seconds as you do it File.AppendAllText("log.txt", sb.ToString()); sb.Clear(); Console.WriteLine(String.Format("Skipping bad problem instance {0}. Error: {1}", scenMapFileName, e.Message)); return; } }
} // Nonsense values until Init, just allocate move public CbsConstraint(CbsConflict conflict, ProblemInstance instance, bool agentA) { Move move; int agentNum; if (agentA) { move = conflict.agentAmove; agentNum = instance.agents[conflict.agentAIndex].agent.agentNum; } else { move = conflict.agentBmove; agentNum = instance.agents[conflict.agentBIndex].agent.agentNum; } this.agentNum = (byte)agentNum; this.move = new TimedMove(move, conflict.timeStep); if (conflict.isVertexConflict) { this.move.direction = Move.Direction.NO_DIRECTION; } }
public override (ProblemInstance, ISet <CbsConstraint>) ToProblemInstance(ProblemInstance initial) { WorldState state = this; if (this.agentTurn != 0) { // CBS doesn't handle partially expanded nodes well. // Use the last fully expanded node and add the additional moves as must conds: state = this.prevStep; // Points to the last fully expanded node. } ProblemInstance subproblem = initial.Subproblem(state.allAgentsState); // Can't use base's method because we're operating on a different object var positiveConstraints = new HashSet <CbsConstraint>(); if (this.agentTurn != 0) { for (int i = 0; i < this.agentTurn; ++i) { positiveConstraints.Add(new CbsConstraint(this.allAgentsState[i].agent.agentNum, this.allAgentsState[i].lastMove)); } } return(subproblem, positiveConstraints); }
public abstract CostTreeNodeSolver CreateNodeSolver(ProblemInstance instance, Run runner);
public CostTreeNodeSolverRepeatedMatching(ProblemInstance problem, Run runner, CostTreeSearchSolver solver) : base(problem, runner, solver) { }
public CostTreeNodeSolverDDBF(ProblemInstance problem, Run runner, CostTreeSearchSolver solver) : base(problem, runner, solver) { }
public void Init(ProblemInstance pi, List <uint> agentsToConsider) { this.first.Init(pi, agentsToConsider); this.second.Init(pi, agentsToConsider); }
public void Init(ProblemInstance pi, List <uint> agents) { }
public void Init(ProblemInstance pi, List <uint> agentsToConsider) { }
/// <summary> /// Dragon Age experiment /// </summary> /// <param name="numInstances"></param> /// <param name="mapFilePaths"></param> public void RunDragonAgeExperimentSet(int numInstances, string[] mapFilePaths) { ProblemInstance instance; string instanceName; using (Run runner = new Run()) { bool resultsFileExisted = File.Exists(RESULTS_FILE_NAME); runner.OpenResultsFile(RESULTS_FILE_NAME); if (resultsFileExisted == false) { runner.PrintResultsFileHeader(); } // FIXME: Code dup with RunExperimentSet TextWriter output; int[] agentListSizes = { 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100 }; //int[] agentListSizes = { 60, 65, 70, 75, 80, 85, 90, 95, 100 }; //int[] agentListSizes = { 100 }; bool continueFromLastRun = false; string[] lineParts = null; string currentProblemFileName = Path.Combine( Directory.GetCurrentDirectory(), $"current-problem-{Process.GetCurrentProcess().ProcessName}"); if (File.Exists(currentProblemFileName)) //if we're continuing running from last time { TextReader input = new StreamReader(currentProblemFileName); lineParts = input.ReadLine().Split(','); //get the last problem input.Close(); continueFromLastRun = true; } for (int ag = 0; ag < agentListSizes.Length; ag++) { for (int i = 0; i < numInstances; i++) { //string name = Process.GetCurrentProcess().ProcessName.Substring(1); //if (i % 33 != Convert.ToInt32(name)) // DAO! // continue; for (int map = 0; map < mapFilePaths.Length; map++) { if (continueFromLastRun) // Set the latest problem { ag = int.Parse(lineParts[0]); i = int.Parse(lineParts[1]); map = int.Parse(lineParts[2]); for (int j = 3; j < lineParts.Length && j - 3 < runner.outOfTimeCounters.Length; j++) { runner.outOfTimeCounters[j - 3] = int.Parse(lineParts[j]); } continueFromLastRun = false; continue; // We write the details of the last problem that was solved, no need to solve it again } if (runner.outOfTimeCounters.Sum() == runner.outOfTimeCounters.Length * 20) // All algs should be skipped { break; } string mapFilePath = mapFilePaths[map]; instanceName = $"{Path.GetFileNameWithoutExtension(mapFilePath)}-{agentListSizes[ag]}-{i}"; try { instance = ProblemInstance.Import(Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "Instances", instanceName)); } catch (Exception importException) { if (onlyReadInstances) { Console.WriteLine($"File {instanceName} dosen't exist"); return; } instance = runner.GenerateDragonAgeProblemInstance(mapFilePath, agentListSizes[ag]); instance.ComputeSingleAgentShortestPaths(); // Consider just importing the generated problem after exporting it to remove the duplication of this line from Import() instance.instanceId = i; instance.Export(instanceName); } runner.SolveGivenProblem(instance); //save the latest problem try { output = new StreamWriter(currentProblemFileName); } catch (Exception e) { System.Threading.Thread.Sleep(1000); output = new StreamWriter(currentProblemFileName); } output.Write("{0},{1},{2}", ag, i, map); for (int j = 0; j < runner.outOfTimeCounters.Length; j++) { output.Write($",{runner.outOfTimeCounters[j]}"); } output.Close(); } } } } }
public void Clear() { this.instance = null; this.solver.Clear(); }
public override CostTreeNodeSolver CreateNodeSolver(ProblemInstance instance, Run runner) { return(new CostTreeNodeSolverRepeatedMatching(problem, runner, this)); }
public virtual void Setup(ProblemInstance problemInstance, Run runner) { Setup(problemInstance, 0, runner, null); }
public override void Setup(ProblemInstance problemInstance, Run runner) { Setup(problemInstance, 0, runner); }
/// <summary> /// Builds an MDD by first performing a BFS from start_pos to the agent's goal, /// then deleting all nodes which don't lead to the goal at the given cost. /// </summary> /// <param name="mddNum"></param> /// <param name="agentNum"></param> /// <param name="start_pos"></param> /// <param name="cost">The MDD must be of this cost</param> /// <param name="numOfLevels"> /// The MDD must be of this number of levels, not counting level zero. /// If higher than cost, the extra levels will be WAITs at the goal. /// </param> /// <param name="numOfAgents">Used for initializng coexistence lists</param> /// <param name="instance"></param> /// <param name="ignoreConstraints"></param> /// <param name="supportPruning"></param> public MDD(int mddNum, int agentNum, Move start_pos, int cost, int numOfLevels, int numOfAgents, ProblemInstance instance, bool ignoreConstraints = false, bool supportPruning = true, ISet <TimedMove> reserved = null) { // numOfLevels >= cost this.problem = instance; this.mddNum = mddNum; this.agentNum = agentNum; this.numOfAgents = numOfAgents; this.cost = cost; this.levels = new LinkedList <MDDNode> [numOfLevels + 1]; this.supportPruning = supportPruning; ISet <CbsConstraint> constraints = null; Dictionary <int, TimedMove>[] mustConstraints = null; if (ignoreConstraints == false && instance.parameters.ContainsKey(CBS.CONSTRAINTS) && ((HashSet_U <CbsConstraint>)instance.parameters[CBS.CONSTRAINTS]).Count != 0) { this.queryConstraint = new CbsConstraint(); this.queryConstraint.queryInstance = true; constraints = (ISet <CbsConstraint>)instance.parameters[CBS.CONSTRAINTS]; } if (ignoreConstraints == false && instance.parameters.ContainsKey(CBS.MUST_CONSTRAINTS) && ((HashSet_U <CbsConstraint>)instance.parameters[CBS.MUST_CONSTRAINTS]).Count != 0) { // TODO: Code dup with A_Star's constructor var musts = (HashSet_U <CbsConstraint>)instance.parameters[CBS.MUST_CONSTRAINTS]; mustConstraints = new Dictionary <int, TimedMove> [musts.Max(con => con.GetTimeStep()) + 1]; // To have index MAX, array needs MAX + 1 places. foreach (CbsConstraint con in musts) { int timeStep = con.GetTimeStep(); if (mustConstraints[timeStep] == null) { mustConstraints[timeStep] = new Dictionary <int, TimedMove>(); } mustConstraints[timeStep][con.agentNum] = con.move; } } var perLevelClosedList = new Dictionary <MDDNode, MDDNode>(); var toDelete = new List <MDDNode>(); for (int i = 0; i < levels.Length; i++) { levels[i] = new LinkedList <MDDNode>(); } MDDNode root = new MDDNode(new TimedMove(start_pos, 0), numOfAgents, this, supportPruning); // Root LinkedListNode <MDDNode> llNode = new LinkedListNode <MDDNode>(root); root.setMyNode(llNode); llNode.Value.startOrGoal = true; levels[0].AddFirst(llNode); for (int i = 0; i < numOfLevels; i++) // For each level, populate the _next_ level { int heuristicBound = cost - i - 1; // We want g+h <= cost, so h <= cost-g. -1 because it's the bound of the _children_. if (heuristicBound < 0) { heuristicBound = 0; } // Go over each MDDNode in this level foreach (MDDNode currentMddNode in levels[i]) // Since we're not deleting nodes in this method, we can use the simpler iteration method :) { List <MDDNode> children = this.GetAllChildren(currentMddNode, heuristicBound, numOfAgents, constraints, mustConstraints, reserved); if (children.Count == 0) // Heuristic wasn't perfect because of constraints, illegal moves or other reasons { toDelete.Add(currentMddNode); } foreach (MDDNode child in children) { MDDNode toAdd = child; // The compiler won't let me assign to the foreach variable... if (perLevelClosedList.ContainsKey(child)) { toAdd = perLevelClosedList[child]; } else { perLevelClosedList.Add(toAdd, toAdd); llNode = new LinkedListNode <MDDNode>(toAdd); toAdd.setMyNode(llNode); levels[i + 1].AddLast(llNode); } currentMddNode.addChild(toAdd); // forward edge toAdd.addParent(currentMddNode); // backward edge } } perLevelClosedList.Clear(); } foreach (MDDNode goal in levels[numOfLevels]) // The goal may be reached in more than one direction { goal.startOrGoal = true; } foreach (MDDNode remove in toDelete) { remove.delete(); } }
/// <summary> /// This is the starting point of the program. /// </summary> static void Main(string[] args) { Program me = new Program(); Program.RESULTS_FILE_NAME = Process.GetCurrentProcess().ProcessName + ".csv"; if (System.Diagnostics.Debugger.IsAttached) { Constants.MAX_TIME = int.MaxValue; Debug.WriteLine("Debugger attached - running without a timeout!!"); } if (Directory.Exists(Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "Instances")) == false) { Directory.CreateDirectory(Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "Instances")); } Program.onlyReadInstances = false; int instances = 100; bool runGrids = false; bool runDragonAge = false; bool runMazesWidth1 = false; bool runSpecific = false; bool runPaperProblems = false; bool runPaperProblemsIncrementally = false; // Turn on for CA* if (runGrids == true) { //int[] gridSizes = new int[] { 8, }; //int[] agentListSizes = new int[] { 2, 3, 4 }; //int[] gridSizes = new int[] { 6, }; //int[] agentListSizes = new int[] { /*2,*/ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 }; // Note that success rate drops almost to zero for EPEA* and A*+OD/SIC on 40 agents. int[] gridSizes = new int[] { 20, }; //int[] agentListSizes = new int[] { 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, /*60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150*/ }; int[] agentListSizes = new int[] { 40, 60, 80, 100 }; //int[] obstaclesPercents = new int[] { 20, }; //int[] obstaclesPercents = new int[] { /*0, 5, 10, 15, 20, 25, 30, 35, */20, 30, 40}; int[] obstaclesPercents = new int[] { /*0, 5, 10,*/ 15, /*20, 25, 30, 35, 20, 30, 40*/ }; me.RunExperimentSet(gridSizes, agentListSizes, obstaclesPercents, instances); } else if (runDragonAge == true) { me.RunDragonAgeExperimentSet(instances, Program.daoMapPaths); // Obstacle percents and grid sizes built-in to the maps. } else if (runMazesWidth1 == true) { me.RunDragonAgeExperimentSet(instances, Program.mazeMapPaths); // Obstacle percents and grid sizes built-in to the maps. } else if (runSpecific == true) { ProblemInstance instance; try { if (args[0].EndsWith(".dll")) { instance = ProblemInstance.Import(args[2], args[1]); } else { instance = ProblemInstance.Import(args[1], args[0]); } } catch (Exception e) { Console.WriteLine($"Bad problem instance {args[1]}. Error: {e.Message}"); return; } Run runner = new Run(); // instantiates stuff unnecessarily runner.startTime = runner.ElapsedMillisecondsTotal(); IHeuristicCalculator <WorldState> lowLevelHeuristic = new SumIndividualCosts(); List <uint> agentList = Enumerable.Range(0, instance.agents.Length).Select(x => (uint)x).ToList(); // FIXME: Must the heuristics really receive a list of uints? lowLevelHeuristic.Init(instance, agentList); ICbsSolver lowLevel = new A_Star(lowLevelHeuristic); ILazyHeuristic <CbsNode> highLevelHeuristic = new MvcHeuristicForCbs(); highLevelHeuristic.Init(instance, agentList); // ISolver solver = new CBS(lowLevel, lowLevel, // bypassStrategy: CBS.BypassStrategy.FIRST_FIT_LOOKAHEAD, // conflictChoice: CBS.ConflictChoice.CARDINAL_MDD, // heuristic: highLevelHeuristic, // cacheMdds: true, // useOldCost: true, // replanSameCostWithMdd: true // ); //ISolver solver = new IndependenceDetection(lowLevel, new EPEA_Star(lowLevelHeuristic)); //ISolver solver = new IndependenceDetection(lowLevel, new CostTreeSearchSolverOldMatching(3)); ISolver solver = new IndependenceDetection(lowLevel, new A_Star_WithOD(lowLevelHeuristic)); solver.Setup(instance, runner); bool solved = solver.Solve(); if (solved == false) { Console.WriteLine("Failed to solve"); return; } Plan plan = solver.GetPlan(); plan.PrintPlan(); //me.RunInstance("Instance-5-15-3-792"); //me.RunInstance("Instance-5-15-3-792-4rows"); //me.RunInstance("Instance-5-15-3-792-3rows"); //me.RunInstance("Instance-5-15-3-792-2rows"); //me.RunInstance("corridor1"); //me.RunInstance("corridor2"); //me.RunInstance("corridor3"); //me.RunInstance("corridor4"); return; } else if (runPaperProblems) { foreach (var dirName in scenDirs) { foreach (var scenPath in Directory.GetFiles(dirName)) { var problem = ProblemInstance.Import(scenPath); foreach (var numAgents in Enumerable.Range(1, problem.agents.Length)) { var subProblem = problem.Subproblem(problem.agents.Take(numAgents).ToArray()); // don't create a subproblem, just feed time adding one agent and report the sum of times so far Run runner = new Run(); using (runner) { bool resultsFileExisted = File.Exists(RESULTS_FILE_NAME); runner.OpenResultsFile(RESULTS_FILE_NAME); if (resultsFileExisted == false) { runner.PrintResultsFileHeader(); } bool success = runner.SolveGivenProblem(subProblem); if (success == false) { break; } } } } } } else if (runPaperProblemsIncrementally) { foreach (var dirName in scenDirs) { foreach (var scenPath in Directory.GetFiles(dirName)) { var problem = ProblemInstance.Import(scenPath); CooperativeAStar castar = new CooperativeAStar(); Run runner = new Run(); using (runner) { bool resultsFileExisted = File.Exists(RESULTS_FILE_NAME); runner.OpenResultsFile(RESULTS_FILE_NAME); if (resultsFileExisted == false) { runner.PrintResultsFileHeader(); } runner.SolveGivenProblemIncrementally(problem); } } } } // A function to be used by Eric's PDB code //me.runForPdb(); Console.WriteLine("*********************THE END**************************"); Console.ReadLine(); }
/// <summary> /// Runs a set of experiments. /// This function will generate a random instance (or load it from a file if it was already generated) /// </summary> public void RunExperimentSet(int[] gridSizes, int[] agentListSizes, int[] obstaclesProbs, int instances) { ProblemInstance instance; string instanceName; using (Run runner = new Run()) { bool resultsFileExisted = File.Exists(RESULTS_FILE_NAME); runner.OpenResultsFile(RESULTS_FILE_NAME); if (resultsFileExisted == false) { runner.PrintResultsFileHeader(); } bool continueFromLastRun = false; string[] LastProblemDetails = null; string currentProblemFileName = Path.Combine( Directory.GetCurrentDirectory(), $"current-problem-{Process.GetCurrentProcess().ProcessName}"); if (File.Exists(currentProblemFileName)) //if we're continuing running from last time { var lastProblemFile = new StreamReader(currentProblemFileName); LastProblemDetails = lastProblemFile.ReadLine().Split(','); //get the last problem lastProblemFile.Close(); continueFromLastRun = true; } string allocation = Process.GetCurrentProcess().ProcessName.Substring(1); // When executable names are of the form "g###" for (int gridSizeIndex = 0; gridSizeIndex < gridSizes.Length; gridSizeIndex++) { for (int obstaclePercentageIndex = 0; obstaclePercentageIndex < obstaclesProbs.Length; obstaclePercentageIndex++) { runner.ResetOutOfTimeCounters(); for (int numOfAgentsIndex = 0; numOfAgentsIndex < agentListSizes.Length; numOfAgentsIndex++) { if (gridSizes[gridSizeIndex] * gridSizes[gridSizeIndex] * (1 - obstaclesProbs[obstaclePercentageIndex] / 100) < agentListSizes[numOfAgentsIndex]) // Probably not enough room for all agents { continue; } for (int i = 0; i < instances; i++) { //if (i % 33 != Convert.ToInt32(allocation)) // grids! // continue; //if (i % 5 != 0) // grids! // continue; if (continueFromLastRun) //set the latest problem { gridSizeIndex = int.Parse(LastProblemDetails[0]); obstaclePercentageIndex = int.Parse(LastProblemDetails[1]); numOfAgentsIndex = int.Parse(LastProblemDetails[2]); i = int.Parse(LastProblemDetails[3]); for (int j = 4; j < LastProblemDetails.Length; j++) { runner.outOfTimeCounters[j - 4] = int.Parse(LastProblemDetails[j]); } continueFromLastRun = false; continue; // "current problem" file describes last solved problem, no need to solve it again } if (runner.outOfTimeCounters.Length != 0 && runner.outOfTimeCounters.Sum() == runner.outOfTimeCounters.Length * Constants.MAX_FAIL_COUNT) // All algs should be skipped { break; } instanceName = $"Instance-{gridSizes[gridSizeIndex]}-{obstaclesProbs[obstaclePercentageIndex]}-{agentListSizes[numOfAgentsIndex]}-{i}"; try { instance = ProblemInstance.Import(Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "Instances", instanceName)); instance.instanceId = i; } catch (Exception importException) { if (onlyReadInstances) { Console.WriteLine($"File {instanceName} dosen't exist"); return; } instance = runner.GenerateProblemInstance(gridSizes[gridSizeIndex], agentListSizes[numOfAgentsIndex], obstaclesProbs[obstaclePercentageIndex] * gridSizes[gridSizeIndex] * gridSizes[gridSizeIndex] / 100); instance.ComputeSingleAgentShortestPaths(); // REMOVE FOR GENERATOR instance.instanceId = i; instance.Export(instanceName); } runner.SolveGivenProblem(instance); // Save the latest problem StreamWriter lastProblemFile; try { lastProblemFile = new StreamWriter(currentProblemFileName); } catch (Exception) { System.Threading.Thread.Sleep(1000); lastProblemFile = new StreamWriter(currentProblemFileName); } lastProblemFile.Write("{0},{1},{2},{3}", gridSizeIndex, obstaclePercentageIndex, numOfAgentsIndex, i); for (int j = 0; j < runner.outOfTimeCounters.Length; j++) { lastProblemFile.Write($",{runner.outOfTimeCounters[j]}"); } lastProblemFile.Close(); lastProblemFile = null; } } } } } }
/// <summary> /// Initializes the pattern database by storing references to the /// problem instance and also the subset of agents that the pattern /// database pertains to. /// </summary> /// <param name="pi">The problem instance.</param> /// <param name="agentsToConsider">The agents that the pattern database should keep track of.</param> public virtual void Init(ProblemInstance pi, List <uint> agentsToConsider) { problem = pi; this.agentsToConsider = new List <uint>(agentsToConsider); this.agentsToConsider.Sort(); }
/// <summary> /// Imports a problem instance from a given file /// </summary> /// <param name="filePath"></param> /// <param name="mapFilePath"></param> /// <returns></returns> public static ProblemInstance Import(string filePath, string mapFilePath = null) { if (filePath.EndsWith(".agents")) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath); int instanceId = 0; try { instanceId = int.Parse(filePath.Split('_').Last()); } catch (Exception) {} string mapfileNameWithoutExtension; if (mapFilePath == null) { mapfileNameWithoutExtension = fileNameWithoutExtension.Substring(0, length: fileNameWithoutExtension.LastIndexOf('_')) + ".map"; // Passing a length parameter is like specifying a non-inclusive end index mapFilePath = Path.Combine(Path.GetDirectoryName(filePath), "..", "maps", mapfileNameWithoutExtension); } else { mapfileNameWithoutExtension = Path.GetFileNameWithoutExtension(mapFilePath); } bool[][] grid = readMapFile(mapFilePath); string line; string[] lineParts; AgentState[] states; using (TextReader input = new StreamReader(filePath)) { // Read the number of agents line = input.ReadLine(); int numOfAgents = int.Parse(line); // Read the agents' start and goal states states = new AgentState[numOfAgents]; AgentState state; Agent agent; int goalX; int goalY; int startX; int startY; for (int i = 0; i < numOfAgents; i++) { line = input.ReadLine(); lineParts = line.Split(EXPORT_DELIMITER); goalX = int.Parse(lineParts[0]); goalY = int.Parse(lineParts[1]); startX = int.Parse(lineParts[2]); startY = int.Parse(lineParts[3]); agent = new Agent(goalX, goalY, i); state = new AgentState(startX, startY, agent); states[i] = state; } } // Generate the problem instance ProblemInstance instance = new ProblemInstance(); instance.Init(states, grid); instance.instanceId = instanceId; instance.parameters[ProblemInstance.GRID_NAME_KEY] = mapfileNameWithoutExtension; instance.parameters[ProblemInstance.INSTANCE_NAME_KEY] = fileNameWithoutExtension + ".agents"; instance.ComputeSingleAgentShortestPaths(); return(instance); } else if (filePath.EndsWith(".scen")) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath); int instanceId = int.Parse(fileNameWithoutExtension.Split('-').Last()); string mapfileName = fileNameWithoutExtension.Substring(0, length: fileNameWithoutExtension.LastIndexOf('-')); // Passing a length parameter is like specifying a non-inclusive end index if (mapFilePath == null) { mapFilePath = Path.Combine(Path.GetDirectoryName(filePath), "..", "..", "..", "maps", mapfileName); } bool[][] grid = readMapFile(mapFilePath); string line; string[] lineParts; List <AgentState> stateList = new List <AgentState>(); using (TextReader input = new StreamReader(filePath)) { // Read the format version number line = input.ReadLine(); lineParts = line.Split(' '); Trace.Assert(lineParts[0].Equals("version")); int version = int.Parse(lineParts[1]); Trace.Assert(version == 1, "Only version 1 is currently supported"); // Read the agents' start and goal states AgentState state; Agent agent; int agentNum = 0; int block; int goalX; int goalY; int startX; int startY; string mapFileName; int mapRows; int mapCols; double optimalCost; // Assuming diagonal moves are allowed and cost sqrt(2) while (true) { line = input.ReadLine(); if (string.IsNullOrWhiteSpace(line)) { break; } lineParts = line.Split('\t'); block = int.Parse(lineParts[0]); mapFileName = lineParts[1]; mapRows = int.Parse(lineParts[2]); Trace.Assert(mapRows == grid.GetLength(0)); mapCols = int.Parse(lineParts[3]); Trace.Assert(mapCols == grid.GetLength(1)); startY = int.Parse(lineParts[4]); startX = int.Parse(lineParts[5]); goalY = int.Parse(lineParts[6]); goalX = int.Parse(lineParts[7]); optimalCost = double.Parse(lineParts[8]); agent = new Agent(goalX, goalY, agentNum); state = new AgentState(startX, startY, agent); stateList.Add(state); agentNum++; } } // Generate the problem instance ProblemInstance instance = new ProblemInstance(); instance.Init(stateList.ToArray(), grid); instance.instanceId = instanceId; instance.parameters[ProblemInstance.GRID_NAME_KEY] = mapfileName; instance.parameters[ProblemInstance.INSTANCE_NAME_KEY] = fileNameWithoutExtension + ".scen"; instance.ComputeSingleAgentShortestPaths(); return(instance); } else // Combined map and scenario, no suffix { using (TextReader input = new StreamReader(filePath)) { string[] lineParts; string line; int instanceId = 0; string gridName = "Random Grid"; // The default line = input.ReadLine(); if (line.StartsWith("Grid:") == false) { lineParts = line.Split(','); instanceId = int.Parse(lineParts[0]); if (lineParts.Length > 1) { gridName = lineParts[1]; } line = input.ReadLine(); } // First/second line is Grid: Trace.Assert(line.StartsWith("Grid:")); // Read grid dimensions line = input.ReadLine(); lineParts = line.Split(','); int maxX = int.Parse(lineParts[0]); int maxY = int.Parse(lineParts[1]); bool[][] grid = new bool[maxX][]; // Read grid char cell; for (int i = 0; i < maxX; i++) { grid[i] = new bool[maxY]; line = input.ReadLine(); for (int j = 0; j < maxY; j++) { cell = line[j]; if (cell == '@' || cell == 'O' || cell == 'T' || cell == 'W' /* Water isn't traversable from land */) { grid[i][j] = true; } else { grid[i][j] = false; } } } // Next line is Agents: line = input.ReadLine(); Trace.Assert(line.StartsWith("Agents:")); // Read the number of agents line = input.ReadLine(); int numOfAgents = int.Parse(line); // Read the agents' start and goal states AgentState[] states = new AgentState[numOfAgents]; AgentState state; Agent agent; int agentNum; int goalX; int goalY; int startX; int startY; for (int i = 0; i < numOfAgents; i++) { line = input.ReadLine(); lineParts = line.Split(EXPORT_DELIMITER); agentNum = int.Parse(lineParts[0]); goalX = int.Parse(lineParts[1]); goalY = int.Parse(lineParts[2]); startX = int.Parse(lineParts[3]); startY = int.Parse(lineParts[4]); agent = new Agent(goalX, goalY, agentNum); state = new AgentState(startX, startY, agent); states[i] = state; } // Generate the problem instance ProblemInstance instance = new ProblemInstance(); instance.Init(states, grid); instance.instanceId = instanceId; instance.parameters[ProblemInstance.GRID_NAME_KEY] = gridName; instance.parameters[ProblemInstance.INSTANCE_NAME_KEY] = Path.GetFileName(filePath); instance.ComputeSingleAgentShortestPaths(); return(instance); } } }
/// <summary> /// The initialization function accepts a problem instance describing /// the original full problem, and a list of agents for which this /// pattern database will be responsible for. This must be called prior /// to a call to build the pattern database. /// </summary> /// <param name="pi">A description of the problem instance.</param> /// <param name="agentsToConsider">The agents that we should be responsible for. /// Each entry in the list is an index to ProblemInstance.agents /// pointing to which agents we care about.</param> public override void Init(ProblemInstance pi, List <uint> agentsToConsider) { base.Init(pi, agentsToConsider); computePermutations(); }
public static ProblemInstance ImportFromScenFile(string fileName) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName); int instanceId = int.Parse(fileNameWithoutExtension.Split('-').Last()); //string scen_type = ""; string mapfileName = ""; int scen_type_seperator_index = 0; if (fileNameWithoutExtension.Split('-')[0].Contains("empty")) //empty map { scen_type_seperator_index = 2; } else if (fileNameWithoutExtension.Split('-')[0].Contains("maze") || fileNameWithoutExtension.Split('-')[0].Contains("random") || fileNameWithoutExtension.Split('-')[0].Contains("room")) { scen_type_seperator_index = 3; } else if (fileNameWithoutExtension.Split('-')[0].Contains("warehouse")) { scen_type_seperator_index = 5; } mapfileName = fileNameWithoutExtension.Substring(0, length: IndexOfNth(fileNameWithoutExtension, "-", scen_type_seperator_index)); Console.WriteLine(mapfileName); string mapFilePath = Path.Combine(Path.GetDirectoryName(fileName), @"..", @"..", "maps", mapfileName + ".map"); Console.WriteLine("map file path {0} {1}", Path.GetDirectoryName(fileName), mapFilePath); bool[][] grid; string line; string[] lineParts; int maxX; int maxY; using (TextReader input = new StreamReader(mapFilePath)) { // Read grid dimensions line = input.ReadLine(); Debug.Assert(line.StartsWith("type octile")); line = input.ReadLine(); lineParts = line.Split(' '); Trace.Assert(lineParts.Length == 2); //Trace.Assert(lineParts[0].Equals("height")); maxY = int.Parse(lineParts[1]); // The height is the number of rows line = input.ReadLine(); lineParts = line.Split(' '); Trace.Assert(lineParts.Length == 2); //Trace.Assert(lineParts[0].Equals("width")); maxX = int.Parse(lineParts[1]); // The width is the number of columns grid = new bool[maxY][]; line = input.ReadLine(); Trace.Assert(line.StartsWith("map")); char cell; // Read grid for (int i = 0; i < maxY; i++) { grid[i] = new bool[maxX]; line = input.ReadLine(); for (int j = 0; j < maxX; j++) { cell = line[j]; if (cell == '@' || cell == 'O' || cell == 'T' || cell == 'W' /* Water isn't traversable from land */) { grid[i][j] = true; } else { grid[i][j] = false; } } } } List <AgentState> stateList = new List <AgentState>(); Run runner = new Run(); Console.WriteLine("Starting scen file {0}", fileName); var rnd = new Random(); var filename_without_extension = fileName.Substring(0, fileName.IndexOf(".scen")); var agents_fileName = filename_without_extension + ".agents"; var plan_fileName = filename_without_extension + ".plans"; //if (File.Exists(agents_fileName)) // File.Delete(agents_fileName); using (TextReader input = new StreamReader(fileName)) { // Read the format version number line = input.ReadLine(); lineParts = line.Split(' '); Debug.Assert(lineParts[0].Equals("version")); int version = int.Parse(lineParts[1]); Debug.Assert(version == 1, "Only version 1 is currently supported"); // Read the agents' start and goal states AgentState state; Agent agent; int agentNum = 0; int block; int goalX; int goalY; int startX; int startY; string mapFileName; int mapRows; int mapCols; double optimalCost; // Assuming diagonal moves are allowed and cost sqrt(2) List <string> lines = new List <string>(); ProblemInstance instance = new ProblemInstance(); while (true) { line = input.ReadLine(); if (string.IsNullOrWhiteSpace(line)) { break; } lines.Add(line); } Console.WriteLine("Found {0} agents", lines.Count); for (int i = 2; i < lines.Count + 1; i++) { agentNum = 0; if (i > 1000) { break; } stateList = new List <AgentState>(); //var rand_lines = lines.AsEnumerable().OrderBy(n => Guid.NewGuid()).Take(i).Cast<String>().ToList(); var rand_lines = lines.Take(i); if (File.Exists(agents_fileName)) { bool already_executed = File.ReadLines(agents_fileName) .Any(curr_line => curr_line.Contains("NumAgents: " + i)); if (already_executed) { Console.WriteLine("Skipping already solved problem with {0} agents", i); continue; } } var agents_writer = new StreamWriter(agents_fileName, true); agents_writer.WriteLine("NumAgents: {0}", i); foreach (String rand_line in rand_lines) { lineParts = rand_line.Split('\t'); block = int.Parse(lineParts[0]); mapFileName = lineParts[1]; mapRows = int.Parse(lineParts[2]); Debug.Assert(mapRows == maxX); mapCols = int.Parse(lineParts[3]); Debug.Assert(mapCols == maxY); startY = int.Parse(lineParts[4]); startX = int.Parse(lineParts[5]); goalY = int.Parse(lineParts[6]); goalX = int.Parse(lineParts[7]); optimalCost = double.Parse(lineParts[8]); agent = new Agent(goalX, goalY, agentNum); state = new AgentState(startX, startY, agent); stateList.Add(state); agents_writer.WriteLine("{0},{1},{2},{3}", startX, startY, goalX, goalY); agentNum++; } agents_writer.Close(); bool resultsFileExisted = File.Exists(Program.RESULTS_FILE_NAME); runner.OpenResultsFile(Program.RESULTS_FILE_NAME); if (resultsFileExisted == false) { runner.PrintResultsFileHeader(); } runner.CloseResultsFile(); agents_writer = new StreamWriter(agents_fileName, true); Console.WriteLine("Starting scen with {0} agents", i); // Generate the problem instance /////------------- Generate SAT file from scen+map var scen_files_dir = Directory.GetParent(filename_without_extension); var sat_mpf_fileName = Path.Combine(scen_files_dir.ToString(), "sat_files", Path.GetFileName(filename_without_extension) + String.Format("_a_{0}.mpf", i)); /////------------- Generate SAT file from scen+map if (instance.agents == null) //Should init the ProblemInstance { instance.Init(stateList.ToArray(), grid); instance.ComputeSingleAgentShortestPaths(); } else { instance.AddSingleAgent(stateList.Last()); } var lazyCbsAgentsFileName = Path.Combine(scen_files_dir.ToString(), "lazycbs", Path.GetFileName(filename_without_extension) + String.Format("_a_{0}.agents", i)); string lazyCbsMapFileName = Path.Combine(Path.GetDirectoryName(fileName), @"..", @"..", "maps", mapfileName + ".map.ecbs"); instance.parameters[ProblemInstance.SAT_FILE_NAME] = sat_mpf_fileName; instance.parameters[ProblemInstance.MAP_FILE_PATH] = mapFilePath; instance.parameters[ProblemInstance.SCEN_FILE] = fileName; instance.parameters[ProblemInstance.LAZY_CBS_AGENTS_FILE_NAME] = lazyCbsAgentsFileName; instance.parameters[ProblemInstance.LAZY_CBS_MAP_FILE_NAME] = lazyCbsMapFileName; instance.parameters[ProblemInstance.SCEN_DIR] = scen_files_dir; instance.parameters[ProblemInstance.N_AGENTS] = i; instance.instanceId = instanceId; instance.parameters[ProblemInstance.GRID_NAME_KEY] = mapfileName; instance.parameters[ProblemInstance.INSTANCE_NAME_KEY] = fileNameWithoutExtension + ".scen"; runner.OpenResultsFile(Program.RESULTS_FILE_NAME); Boolean solved = runner.SolveGivenProblem(instance, plan_fileName); runner.CloseResultsFile(); agents_writer.Close(); if (!solved) { break; } } } return(null); }
/// <summary> /// Calculates for each agent and each direction it can go, the effect of that move on F. Illegal moves get byte.MaxValue. /// Also calcs maxDeltaF. /// Implicitly uses the SIC heuristic. /// </summary> /// <param name="problem">For GetSingleAgentOptimalCost</param> /// <param name="isValid"></param> /// <returns></returns> public void calcSingleAgentDeltaFs(ProblemInstance problem, ValidityChecker isValid) { // Init this.singleAgentDeltaFs = new byte[allAgentsState.Length][]; for (int i = 0; i < singleAgentDeltaFs.Length; i++) { this.singleAgentDeltaFs[i] = new byte[Constants.NUM_ALLOWED_DIRECTIONS]; } int hBefore, hAfter; this.maxDeltaF = 0; // Set values for (int i = 0; i < allAgentsState.Length; i++) { hBefore = problem.GetSingleAgentOptimalCost(allAgentsState[i]); int singleAgentMaxLegalDeltaF = -1; foreach (TimedMove check in allAgentsState[i].lastMove.GetNextMoves()) { if (isValid(check, noMoves, this.makespan + 1, i, this, this) == false) // Is this move by itself invalid because of constraints or obstacles { singleAgentDeltaFs[i][(int)check.direction] = byte.MaxValue; } else { hAfter = problem.GetSingleAgentOptimalCost(allAgentsState[i].agent.agentNum, check); if (Constants.sumOfCostsVariant == Constants.SumOfCostsVariant.ORIG) { if (hBefore != 0) { singleAgentDeltaFs[i][(int)check.direction] = (byte)(hAfter - hBefore + 1); // h difference + g difference in this specific domain } else if (hAfter != 0) // If agent moved from its goal we must count and add all the steps it was stationed at the goal, since they're now part of its g difference { singleAgentDeltaFs[i][(int)check.direction] = (byte)(hAfter - hBefore + makespan - allAgentsState[i].arrivalTime + 1); } else { singleAgentDeltaFs[i][(int)check.direction] = 0; // This is a WAIT move at the goal. } } else if (Constants.sumOfCostsVariant == Constants.SumOfCostsVariant.WAITING_AT_GOAL_ALWAYS_FREE) { if (hBefore == 0 && hAfter == 0) { singleAgentDeltaFs[i][(int)check.direction] = 0; // This is a WAIT move at the goal. } else { singleAgentDeltaFs[i][(int)check.direction] = (byte)(hAfter - hBefore + 1); // h difference + g difference in this specific domain } } singleAgentMaxLegalDeltaF = Math.Max(singleAgentMaxLegalDeltaF, singleAgentDeltaFs[i][(int)check.direction]); } } if (singleAgentMaxLegalDeltaF == -1) // No legal action for this agent, so no legal children exist for this node { this.maxDeltaF = 0; // Can't make it negative without widening the field. break; } this.maxDeltaF += (byte)singleAgentMaxLegalDeltaF; } fLookup = new DeltaFAchievable[allAgentsState.Length][]; for (int i = 0; i < fLookup.Length; i++) { fLookup[i] = new DeltaFAchievable[this.maxDeltaF + 1]; // Towards the last agents most of the row will be wasted (the last one can do delta F of 0 or 1), // but it's easier than fiddling with array sizes } }
/// <summary> /// Imports a problem instance from a given file /// </summary> /// <param name="filePath"></param> /// <param name="mapFilePath"></param> /// <returns></returns> public static ProblemInstance Import(string filePath, string mapFilePath = null) { if (filePath.EndsWith(".agents")) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath); int instanceId = 0; string mapfileNameWithoutExtension; if (mapFilePath == null) { mapfileNameWithoutExtension = fileNameWithoutExtension.Substring(0, length: fileNameWithoutExtension.LastIndexOf('_')) + ".map"; // Passing a length parameter is like specifying a non-inclusive end index mapFilePath = Path.Combine(Path.GetDirectoryName(filePath), "..", "maps", mapfileNameWithoutExtension); instanceId = int.Parse(filePath.Split('_').Last()); } else { mapfileNameWithoutExtension = Path.GetFileNameWithoutExtension(mapFilePath); } bool[][] grid; string line; string[] lineParts; using (TextReader input = new StreamReader(mapFilePath)) { // Read grid dimensions line = input.ReadLine(); lineParts = line.Split(','); int maxX = int.Parse(lineParts[0]); int maxY = int.Parse(lineParts[1]); grid = new bool[maxX][]; char cell; // Read grid for (int i = 0; i < maxX; i++) { grid[i] = new bool[maxY]; line = input.ReadLine(); for (int j = 0; j < maxY; j++) { cell = line.ElementAt(j); if (cell == '1') { grid[i][j] = true; } else { grid[i][j] = false; } } } } AgentState[] states; using (TextReader input = new StreamReader(filePath)) { // Read the number of agents line = input.ReadLine(); int numOfAgents = int.Parse(line); // Read the agents' start and goal states states = new AgentState[numOfAgents]; AgentState state; Agent agent; int goalX; int goalY; int startX; int startY; for (int i = 0; i < numOfAgents; i++) { line = input.ReadLine(); lineParts = line.Split(EXPORT_DELIMITER); goalX = int.Parse(lineParts[0]); goalY = int.Parse(lineParts[1]); startX = int.Parse(lineParts[2]); startY = int.Parse(lineParts[3]); agent = new Agent(goalX, goalY, i); state = new AgentState(startX, startY, agent); states[i] = state; } } // Generate the problem instance ProblemInstance instance = new ProblemInstance(); instance.Init(states, grid); instance.instanceId = instanceId; instance.parameters[ProblemInstance.GRID_NAME_KEY] = mapfileNameWithoutExtension; instance.parameters[ProblemInstance.INSTANCE_NAME_KEY] = fileNameWithoutExtension + ".agents"; instance.ComputeSingleAgentShortestPaths(); return(instance); } else if (filePath.EndsWith(".scen")) { return(ImportFromScenFile(filePath)); } else // Combined map and scenario, no suffix { using (TextReader input = new StreamReader(filePath)) { string[] lineParts; string line; int instanceId = 0; string gridName = "Random Grid"; // The default line = input.ReadLine(); if (line.StartsWith("Grid:") == false) { lineParts = line.Split(','); instanceId = int.Parse(lineParts[0]); if (lineParts.Length > 1) { gridName = lineParts[1]; } line = input.ReadLine(); } // First/second line is Grid: Debug.Assert(line.StartsWith("Grid:")); // Read grid dimensions line = input.ReadLine(); lineParts = line.Split(','); int maxX = int.Parse(lineParts[0]); int maxY = int.Parse(lineParts[1]); bool[][] grid = new bool[maxX][]; // Read grid char cell; for (int i = 0; i < maxX; i++) { grid[i] = new bool[maxY]; line = input.ReadLine(); for (int j = 0; j < maxY; j++) { cell = line.ElementAt(j); if (cell == '@' || cell == 'O' || cell == 'T' || cell == 'W' /* Water isn't traversable from land */) { grid[i][j] = true; } else { grid[i][j] = false; } } } // Next line is Agents: line = input.ReadLine(); Debug.Assert(line.StartsWith("Agents:")); // Read the number of agents line = input.ReadLine(); int numOfAgents = int.Parse(line); // Read the agents' start and goal states AgentState[] states = new AgentState[numOfAgents]; AgentState state; Agent agent; int agentNum; int goalX; int goalY; int startX; int startY; for (int i = 0; i < numOfAgents; i++) { line = input.ReadLine(); lineParts = line.Split(EXPORT_DELIMITER); agentNum = int.Parse(lineParts[0]); goalX = int.Parse(lineParts[1]); goalY = int.Parse(lineParts[2]); startX = int.Parse(lineParts[3]); startY = int.Parse(lineParts[4]); agent = new Agent(goalX, goalY, agentNum); state = new AgentState(startX, startY, agent); states[i] = state; } // Generate the problem instance ProblemInstance instance = new ProblemInstance(); instance.Init(states, grid); instance.instanceId = instanceId; instance.parameters[ProblemInstance.GRID_NAME_KEY] = gridName; instance.parameters[ProblemInstance.INSTANCE_NAME_KEY] = Path.GetFileName(filePath); instance.ComputeSingleAgentShortestPaths(); return(instance); } } }
public CostTreeNodeSolverOldMatching(ProblemInstance problem, CostTreeNode costNode, Run runner, CostTreeSearchSolver solver, int syncSize, ISet <TimedMove> reserved) : base(problem, costNode, runner, solver, reserved) { this.syncSize = syncSize; }
/// <summary> /// Initializes the pattern database by storing references to the /// problem instance and also the subset of agents that the pattern /// database pertains to. /// </summary> /// <param name="pi">The problem instance.</param> /// <param name="vAgents">The agents that the pattern database should keep track of.</param> public virtual void Init(ProblemInstance pi, List <uint> vAgents) { }
public CostTreeNodeSolverDDBF(ProblemInstance problem, CostTreeNode costNode, Run runner, CostTreeSearchSolver solver, ISet <TimedMove> reserved) : base(problem, costNode, runner, solver, reserved) { }
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; } }
/// <summary> /// Automatically calls Setup with the given costsNode /// </summary> /// <param name="problem"></param> /// <param name="costNode">TODO: Maybe just pass the array of costs here?</param> /// <param name="runner"></param> /// <param name="solver"></param> public CostTreeNodeSolver(ProblemInstance problem, CostTreeNode costNode, Run runner, CostTreeSearchSolver solver, ISet <TimedMove> reserved) // Make sure agent numbers are in the correct order : this(problem, runner, solver) { this.Setup(costNode, reserved); }
/// <summary> /// For replanning groups to resolve a conflict under independence Detection /// </summary> /// <param name="problemInstance"></param> /// <param name="runner"></param> /// <param name="CAT"></param> /// <param name="targetCost">/// </param> /// <param name="illegalMoves"></param> public virtual void Setup(ProblemInstance problemInstance, Run runner, ConflictAvoidanceTable CAT, int targetCost, ISet <TimedMove> reserved) { this.reserved = reserved; Setup(problemInstance, 0, runner, CAT, minCost: targetCost, maxCost: targetCost); }