/// <summary> /// Runs a single instance, imported from a given filename. /// </summary> /// <param name="fileName"></param> public bool RunInstance(string fileName) { ProblemInstance instance; try { instance = ProblemInstance.Import(Directory.GetCurrentDirectory() + "\\Instances\\" + fileName); } catch (Exception e) { Console.WriteLine(String.Format("Skipping bad problem instance {0}. Error: {1}", fileName, e.Message)); return(false); } Run runner = new Run(); if (runner.m_mapFileName == "") { runner.m_mapFileName = "Grid" + instance.GetMaxX() + "x" + instance.GetMaxY(); } bool resultsFileExisted = File.Exists(RESULTS_FILE_NAME); runner.OpenResultsFile(RESULTS_FILE_NAME); if (resultsFileExisted == false) { runner.PrintResultsFileHeader(); } bool success; success = runner.SolveGivenProblem(instance); runner.CloseResultsFile(); return(success); }
/// <summary> /// Simplest run possible with a randomly generated problem instance. /// </summary> public void SimpleRun() { Run runner = new Run(); runner.OpenResultsFile(RESULTS_FILE_NAME); runner.PrintResultsFileHeader(); ProblemInstance instance = runner.GenerateProblemInstance(10, 3, 10); instance.Export("Test.instance"); runner.SolveGivenProblem(instance); runner.CloseResultsFile(); }
/// <summary> /// Runs a single instance, imported from a given filename. /// </summary> /// <param name="fileName"></param> public void RunInstance(string fileName) { Run runner = new Run(); bool resultsFileExisted = File.Exists(RESULTS_FILE_NAME); runner.OpenResultsFile(RESULTS_FILE_NAME); if (resultsFileExisted == false) { runner.PrintResultsFileHeader(); } ProblemInstance instance = ProblemInstance.Import(Directory.GetCurrentDirectory() + "\\Instances\\" + fileName); runner.SolveGivenProblem(instance); runner.CloseResultsFile(); }
/// <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; 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 = Directory.GetCurrentDirectory() + "\\Instances\\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; } for (int gs = 0; gs < gridSizes.Length; gs++) { for (int obs = 0; obs < obstaclesProbs.Length; obs++) { runner.ResetOutOfTimeCounters(); for (int ag = 0; ag < agentListSizes.Length; ag++) { if (gridSizes[gs] * gridSizes[gs] * (1 - obstaclesProbs[obs] / 100) < agentListSizes[ag]) // Probably not enough room for all agents { continue; } for (int i = 0; i < instances; i++) { if (continueFromLastRun) //set the latest problem { gs = int.Parse(LastProblemDetails[0]); obs = int.Parse(LastProblemDetails[1]); ag = 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[gs] + "-" + obstaclesProbs[obs] + "-" + agentListSizes[ag] + "-" + i; try { instance = ProblemInstance.Import(Directory.GetCurrentDirectory() + "\\Instances\\" + instanceName); instance.instanceId = i; } catch (Exception importException) { if (onlyReadInstances) { Console.WriteLine("File " + instanceName + " dosen't exist"); return; } instance = runner.GenerateProblemInstance(gridSizes[gs], agentListSizes[ag], obstaclesProbs[obs] * gridSizes[gs] * gridSizes[gs] / 100); instance.ComputeSingleAgentShortestPaths(); instance.instanceId = i; instance.Export(instanceName); } runner.SolveGivenProblem(instance); // Save the latest problem if (File.Exists(currentProblemFileName)) { File.Delete(currentProblemFileName); } var lastProblemFile = new StreamWriter(currentProblemFileName); lastProblemFile.Write("{0},{1},{2},{3}", gs, obs, ag, i); for (int j = 0; j < runner.outOfTimeCounters.Length; j++) { lastProblemFile.Write("," + runner.outOfTimeCounters[j]); } lastProblemFile.Close(); } } } } runner.CloseResultsFile(); }
/// <summary> /// Dragon Age experiment /// </summary> /// <param name="numInstances"></param> /// <param name="mapFileNames"></param> public void RunDragonAgeExperimentSet(int numInstances, string[] mapFileNames) { ProblemInstance instance; string instanceName; 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, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 250, 300 }; bool continueFromLastRun = false; string[] lineParts = null; string currentProblemFileName = Directory.GetCurrentDirectory() + "\\Instances\\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++) { for (int map = 0; map < mapFileNames.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++) { runner.outOfTimeCounters[j - 3] = int.Parse(lineParts[j]); } continueFromLastRun = false; continue; } if (runner.outOfTimeCounters.Sum() == runner.outOfTimeCounters.Length * 20) // All algs should be skipped { break; } string mapFileName = mapFileNames[map]; instanceName = Path.GetFileNameWithoutExtension(mapFileName) + "-" + agentListSizes[ag] + "-" + i; try { instance = ProblemInstance.Import(Directory.GetCurrentDirectory() + "\\Instances\\" + instanceName); } catch (Exception importException) { if (onlyReadInstances) { Console.WriteLine("File " + instanceName + " dosen't exist"); return; } instance = runner.GenerateDragonAgeProblemInstance(mapFileName, 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 File.Delete(currentProblemFileName); 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(); } } } runner.CloseResultsFile(); }
/// <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; ProblemInstance instanceForFirstAstar; ProblemInstance instanceForSecondReverseAstar; string instanceName; // build the run - with the defined solvers: 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 = Directory.GetCurrentDirectory() + "\\Instances\\current problem-" + Process.GetCurrentProcess().ProcessName; //# removed the last time check: /* * 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; * } */ // build the grid map: for (int gs = 0; gs < gridSizes.Length; gs++) { for (int obs = 0; obs < obstaclesProbs.Length; obs++) { runner.ResetOutOfTimeCounters(); for (int ag = 0; ag < agentListSizes.Length; ag++) { if (gridSizes[gs] * gridSizes[gs] * (1 - obstaclesProbs[obs] / 100) < agentListSizes[ag]) // Probably not enough room for all agents { continue; } for (int i = 0; i < instances; i++) { string allocation = Process.GetCurrentProcess().ProcessName.Substring(1); //if (i % 33 != Convert.ToInt32(allocation)) // grids! // continue; //if (i % 5 != 0) // grids! // continue; if (continueFromLastRun) //set the latest problem { gs = int.Parse(LastProblemDetails[0]); obs = int.Parse(LastProblemDetails[1]); ag = 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[gs] + "-" + obstaclesProbs[obs] + "-" + agentListSizes[ag] + "-" + i; try { // ******** Some of the project modifications: ******** // For building new map everytime - chose the line of "WRONG-PATH" numberOfRun = 1; // numberOfRun 1 is the first solver of the MAPF problem instance = ProblemInstance.Import(Directory.GetCurrentDirectory() + "\\Instances\\" + instanceName); //instance = ProblemInstance.Import(Directory.GetCurrentDirectory() + "\\WRONG-PATH-Instances\\" + instanceName); instance.instanceId = i; } catch (Exception importException) { if (onlyReadInstances) { Console.WriteLine("File " + instanceName + " dosen't exist"); return; } // ubild the problem instance: instance = runner.GenerateProblemInstance(gridSizes[gs], agentListSizes[ag], obstaclesProbs[obs] * gridSizes[gs] * gridSizes[gs] / 100); instance.ComputeSingleAgentShortestPaths(); // REMOVE FOR GENERATOR instance.instanceId = i; // save the problem instance to a local file: instance.Export(instanceName); } // ******** Some of the project modifications: ******** int numberOfAgents = instance.m_vAgents.Count(); // the number of agents in the MAPF problem // If you chose to run the automated algorithm to find the middle positions if (sloveWithAutomatedSingleAgentMiddlePosition) { for (int j = 0; j < numberOfAgents; j++) { onlySingleAgentsInstances[j].ComputeSingleAgentShortestPaths(); runner.SolveGivenProblem(onlySingleAgentsInstances[j]); } } // Finished solving the separated single agents Console.WriteLine("#################################################"); if (sloveWithAutomatedSingleAgentMiddlePosition) { // Printing the new calculated middle positions of our MAPF problem Console.WriteLine("Here are the new caculated middle positions from the separeted single agents solutions:"); for (int j = 0; j < numberOfAgents; j++) { Console.Write("|({1},{2})", j, middlePosition[j][0], middlePosition[j][1]); } Console.WriteLine("|"); Console.WriteLine("Great, you executed the automated middle positions algorithm!"); } // This is the call for solving the source problem with the regular full Astar solver runner.SolveGivenProblem(instance); // Finished the regular full Astar solution and printing the middle positions from the middle of it Console.WriteLine("-----------> Finished the regular A*star solution <-----------\n"); Console.WriteLine("The middle stage of the plan from full Astar on all the agents together:\n{0}", positionsOfMiddleStage); numberOfRun = 2; // numberOfRun 2 is the second run of the solver -> on the first half of the problem (from the start until the middle positions) // Creating new problem instances that will be solve // Load the same MAPF problem map instanceForFirstAstar = ProblemInstance.Import(Directory.GetCurrentDirectory() + "\\Instances\\" + instanceName); instanceForFirstAstar.instanceId = i + 1; instanceForFirstAstar.instanceId = i + numberOfAgents + 1; // If the solver calculated the middle position in the automating method - it will printed it and you can see the differences in the output if (sloveWithAutomatedSingleAgentMiddlePosition) { Console.WriteLine("Here are the new caculated middle positions from the separeted single agents solutions:"); } // Changing the goal states of the new instance, the new goal state will be the middle state from the source problem for (int j = 0; j < numberOfAgents; j++) { int[] tempPosition = { 0, 0 }; tempPosition[0] = instance.m_vAgents[j].agent.Goal.x; tempPosition[1] = instance.m_vAgents[j].agent.Goal.y; realGoals.Add(tempPosition); trueMiddlePosition.Add(middlePosition[j]); instanceForFirstAstar.m_vAgents[j].agent.Goal.x = middlePosition[j][0]; instanceForFirstAstar.m_vAgents[j].agent.Goal.y = middlePosition[j][1]; // Printing the middle positions of the new first half problem that is going to be solved Console.WriteLine("Middle position for agent {0}: {1},{2}", j, instanceForFirstAstar.m_vAgents[j].agent.Goal.x, instanceForFirstAstar.m_vAgents[j].agent.Goal.y); } Console.WriteLine(""); // Compute the ComputeSingleAgentShortestPaths for the new half instance (required before starting solving the instance) instanceForFirstAstar.ComputeSingleAgentShortestPaths(); // Solving the new first half problem instance runner.SolveGivenProblem(instanceForFirstAstar); Console.WriteLine("-----------> Finished first half of A*star <-----------\n"); // Start building the second half of the MAPF problem instanceForSecondReverseAstar = ProblemInstance.Import(Directory.GetCurrentDirectory() + "\\Instances\\" + instanceName); instanceForSecondReverseAstar.instanceId = i + numberOfAgents + 2; // Changing the new starting positions to be the middle positions that were calculated before, the goal state is remaining the same as the source problem if (secondPartIsReverse) { for (int j = 0; j < numberOfAgents; j++) { instanceForSecondReverseAstar.m_vAgents[j].agent.Goal.x = trueMiddlePosition[j][0]; instanceForSecondReverseAstar.m_vAgents[j].agent.Goal.y = trueMiddlePosition[j][1]; instanceForSecondReverseAstar.m_vAgents[j].lastMove.x = realGoals[j][0]; instanceForSecondReverseAstar.m_vAgents[j].lastMove.y = realGoals[j][1]; } } else { for (int j = 0; j < numberOfAgents; j++) { instanceForSecondReverseAstar.m_vAgents[j].lastMove.x = trueMiddlePosition[j][0]; instanceForSecondReverseAstar.m_vAgents[j].lastMove.y = trueMiddlePosition[j][1]; } } // NumberOfRun 3 is the third run of the solver -> on the second half of the problem (from the end goal state backward to the middle positions state) numberOfRun = 3; // Compute the ComputeSingleAgentShortestPaths for the new half instance (required before starting solving the instance) instanceForSecondReverseAstar.ComputeSingleAgentShortestPaths(); // Solving the new second half problem instance runner.SolveGivenProblem(instanceForSecondReverseAstar); if (secondPartIsReverse) { Console.WriteLine("-----------> Finished the second reverse A*star <-----------\n"); Console.WriteLine("\n########################################################################\n************************************************************************\n"); Console.WriteLine("You solved the problem using Bi-Directional algorithm - with Forward and Reverse solvers"); } else { Console.WriteLine("-----------> Finished the second forward A*star <-----------\n"); Console.WriteLine("\n########################################################################\n************************************************************************\n"); Console.WriteLine("You solved the problem using the splitted Forward-Forward algorithm - both of the parts were solved using forward search solver"); } // Here all the three main solvers (the regular full Astar and the two halves) were finished // Starting to print the final results // Printing the middle positions that were used by the algorithm to solve the MAPF problem Console.WriteLine("\n########################################################################\n************************************************************************\n"); Console.WriteLine("The middle position of the plan from full Astar on all the agents together:\n{0}", positionsOfMiddleStage); if (sloveWithAutomatedSingleAgentMiddlePosition) { Console.WriteLine("Here are the new caculated middle positions from the separeted single agents solutions:"); for (int j = 0; j < numberOfAgents; j++) { Console.Write("|({1},{2})", j, instanceForFirstAstar.m_vAgents[j].agent.Goal.x, instanceForFirstAstar.m_vAgents[j].agent.Goal.y); } Console.WriteLine("|"); Console.WriteLine("Great, you executed the automated middle positions algorithm!!"); } else { Console.WriteLine("The solution was made using this middle positions from the true middle of the real full Astar solver"); } // Writing the final results - with all the sum-up statistics Console.WriteLine("\n#################################################"); Console.WriteLine(" Final Results!:\n" + "#################################################"); Console.WriteLine("---------------------------------------------------\n" + "Total cost full regular A*star = {0}\n" + "Total cost Bi - Directional A* star = {1}\n" + "Bi - Directional details:\n" + "Total cost starting half A* star = {2}\n" + "Total cost reverse half A* star = {3}", costFullAstar, costBiDirectionalAstar, costStartingAstar, costReverseAstar); Console.WriteLine("---------------------------------------------------\n" + "Total time full regular A*star = {0}\n" + "Total time Bi - Directional A* star = {1}\n" + "Bi - Directional details:\n" + "Total time starting half A* star = {2}\n" + "Total time reverse half A* star = {3}", timeFullAstar, timeBiDirectionalAstar, timeStartingAstar, timeReverseAstar); /*Console.WriteLine("---------------------------------------------------\n" + * "Total expanded nodes full regular A* star = {0}\n" + * "Total expanded nodes Bi-Directional A* star = {1}\n" + * "Bi - Directional details:\n" + * "Total expanded nodes starting half A*star = {2}\n" + * "Total expanded nodes reverse half A*star = {3}", expandedNodesFullAstar, expandedNodesBiDirectionalAstar, expandedNodesStartingAstar, expandedNodesReverseAstar); */Console.WriteLine("--------------------------------------------------\n" + "Total generated nodes full regular A*star = {0}\n" + "Total generated nodes Bi-Directional A* star = {1}\n" + "Bi - Directional details:\n" + "Total generated nodes starting half A*star = {2}\n" + "Total generated nodes reverse half A*star = {3}\n" + "--------------------------------------------------", generatedNodesFullAstar, generatedNodesBiDirectionalAstar, generatedNodesStartingAstar, generatedNodesReverseAstar); Console.WriteLine("Total opened nodes full regular A*star = {0}\n" + "Total opened nodes Bi-Directional A* star = {1}\n" + "Bi - Directional details:\n" + "Total opened nodes starting half A*star = {2}\n" + "Total opened nodes reverse half A*star = {3}\n" + "--------------------------------------------------", numberOpenNodesFullAstar, numberOpenNodesBiDirectionalAstar, numberOpenNodesStartingAstar, numberOpenNodesReverseAstar); // Save the latest problem if (File.Exists(currentProblemFileName)) { File.Delete(currentProblemFileName); } var lastProblemFile = new StreamWriter(currentProblemFileName); lastProblemFile.Write("{0},{1},{2},{3}", gs, obs, ag, i); for (int j = 0; j < runner.outOfTimeCounters.Length; j++) { lastProblemFile.Write("," + runner.outOfTimeCounters[j]); } lastProblemFile.Close(); } } } } // end of building the grid map runner.CloseResultsFile(); }