public long solve(CFMAStar.CostFunction costFunction) { // Independence Detection List <List <TimedMove> > nonConflictsPaths = null; IndependentDetection id = new IndependentDetection(this.problemInstance, this.goalState); MAM_AgentState[] newStartPositions = id.Detect(out nonConflictsPaths); if (newStartPositions.Length != 0) { this.problemInstance = problemInstance.ReplanProblem(newStartPositions); this.reducer = new CFMAM_MCMF_Reducer(this.problemInstance, this.goalState); reducer.reduce(costFunction); if (reducer.outputProblem == null) { return(-1); } MinCostMaxFlow mcmfSolver = new MinCostMaxFlow(reducer.outputProblem); timer = Stopwatch.StartNew(); solution = mcmfSolver.SolveMinCostFlow(); List <TimedMove>[] partialPlan = this.reducer.GetCFMAMSolution(this.solution, this.mcmfTime, true); if (costFunction == CFMAStar.CostFunction.MakeSpan) { while (!isPathForEachAgent(partialPlan)) { this.reducer.addNetworkLayer(); mcmfSolver = new MinCostMaxFlow(reducer.outputProblem); solution = mcmfSolver.SolveMinCostFlow(); partialPlan = this.reducer.GetCFMAMSolution(this.solution, this.mcmfTime, true); } } timer.Stop(); this.plan = mergePlans(partialPlan, nonConflictsPaths); this.mcmfTime = timer.ElapsedMilliseconds; this.solutionCost = calculateCost(this.plan, costFunction); } else { this.plan = nonConflictsPaths; this.solutionCost = calculateCost(this.plan, costFunction); } return(this.solutionCost); }
/// <summary> /// Generates a problem instance based on a DAO map file. /// TODO: Fix code dup with GenerateProblemInstance and Import later. /// </summary> /// <param name="agentsNum"></param> /// <returns></returns> public ProblemInstance GenerateDragonAgeProblemInstance ( string mapFileName, int agentsNum ) { m_mapFileName = mapFileName; m_agentNum = agentsNum; TextReader input = new StreamReader(mapFileName); string[] lineParts; string line; line = input.ReadLine(); Debug.Assert(line.StartsWith("type octile")); // Read grid dimensions line = input.ReadLine(); lineParts = line.Split(' '); Debug.Assert(lineParts[0].StartsWith("height")); int maxX = int.Parse(lineParts[1]); line = input.ReadLine(); lineParts = line.Split(' '); Debug.Assert(lineParts[0].StartsWith("width")); int maxY = int.Parse(lineParts[1]); line = input.ReadLine(); Debug.Assert(line.StartsWith("map")); bool[][] grid = new bool[maxX][]; 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; } } } int x; int y; MAM_AgentState[] aStart = new MAM_AgentState[agentsNum]; bool[][] starts = new bool[maxX][]; for (int i = 0; i < maxX; i++) { starts[i] = new bool[maxY]; } // Choose random valid unclaimed goal locations for (int i = 0; i < agentsNum; i++) { x = rand.Next(maxX); y = rand.Next(maxY); if (starts[x][y] || grid[x][y]) { i--; } else { starts[x][y] = true; aStart[i] = new MAM_AgentState(x, y, i, 0); } } ProblemInstance problem = new ProblemInstance(); problem.parameters[ProblemInstance.GRID_NAME_KEY] = Path.GetFileNameWithoutExtension(mapFileName); problem.Init(aStart, grid); IndependentDetection id = new IndependentDetection(problem, problem.m_vAgents[0].lastMove); List <List <TimedMove> > connectionCheck = new List <List <TimedMove> >(); if (id.bfsToStartPositions(problem.m_vAgents[0].lastMove).Count != problem.m_vAgents.Length) { problem = GenerateDragonAgeProblemInstance(mapFileName, agentsNum); } return(problem); }
/// <summary> /// Generates a problem instance, including a board, start and goal locations of desired number of agents /// and desired precentage of obstacles /// TODO: Refactor to use operators. /// </summary> /// <param name="gridSize"></param> /// <param name="agentsNum"></param> /// <param name="obstaclesNum"></param> /// <returns></returns> public ProblemInstance GenerateProblemInstance ( int gridSize, int agentsNum, int obstaclesNum ) { m_mapFileName = "GRID" + gridSize + "X" + gridSize; m_agentNum = agentsNum; if (agentsNum + obstaclesNum > gridSize * gridSize) { throw new Exception("Not enough room for " + agentsNum + ", " + obstaclesNum + " and one empty space in a " + gridSize + "x" + gridSize + "map."); } int x; int y; MAM_AgentState[] aStart = new MAM_AgentState[agentsNum]; bool[][] grid = new bool[gridSize][]; bool[][] starts = new bool[gridSize][]; // Generate a random grid for (int i = 0; i < gridSize; i++) { grid[i] = new bool[gridSize]; starts[i] = new bool[gridSize]; } for (int i = 0; i < obstaclesNum; i++) { x = rand.Next(gridSize); y = rand.Next(gridSize); if (grid[x][y]) // Already an obstacle { i--; } grid[x][y] = true; } // Choose random start locations for (int i = 0; i < agentsNum; i++) { x = rand.Next(gridSize); y = rand.Next(gridSize); if (starts[x][y] || grid[x][y]) { i--; } else { starts[x][y] = true; aStart[i] = new MAM_AgentState(x, y, i, 0); } } ProblemInstance problem = new ProblemInstance(); problem = new ProblemInstance(); problem.Init(aStart, grid); IndependentDetection id = new IndependentDetection(problem, problem.m_vAgents[0].lastMove); List <List <TimedMove> > connectionCheck = new List <List <TimedMove> >(); if (id.bfsToStartPositions(problem.m_vAgents[0].lastMove).Count != problem.m_vAgents.Length) { problem = GenerateProblemInstance(gridSize, agentsNum, obstaclesNum); } return(problem); }