/// <summary> /// Executes a single method-run /// </summary> /// <param name="instanceFile">The path to the instance</param> /// <param name="configFile">The path to the config</param> /// <param name="outputDirectory">The directory to write the results to</param> /// <param name="seedNumber">The seed to use</param> public static void Execute(string instanceFile, string configFile, string outputDirectory, string seedNumber) { // Save parameters for the case of an exception ExInstanceName = instanceFile; ExConfigName = configFile; ExSeedNumber = seedNumber; // Read config Configuration config = Configuration.Read(configFile); Instance instance = Instance.ReadXML(instanceFile); // Create output dir if not already existing string exportationDir = Path.Combine(outputDirectory, instance.Name + "-" + config.Name + "-" + seedNumber); if (Directory.Exists(exportationDir)) { Directory.Delete(exportationDir, true); } // Wait for directory to be really deleted - nasty but necessary while (Directory.Exists(exportationDir)) { Thread.Sleep(100); } // Create a fresh directory Directory.CreateDirectory(exportationDir); // Catch unhandled exceptions if (!AppDomain.CurrentDomain.FriendlyName.EndsWith("vshost.exe")) { Console.WriteLine("Adding handler for unhandled exceptions ..."); AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(LogUnhandledException); } // Determine log file string logFile = Path.Combine(exportationDir, "output.txt"); // Write instance name using (StreamWriter sw = new StreamWriter(Path.Combine(exportationDir, FILENAME_INSTANCE_NAME))) sw.Write(instance.Name); // Write configuration name using (StreamWriter sw = new StreamWriter(Path.Combine(exportationDir, FILENAME_CONFIG_NAME))) sw.Write(config.Name); // Write all output using (StreamWriter outputWriter = new StreamWriter(logFile) { AutoFlush = true }) { // Write solution status over time using (StreamWriter statusWriter = new StreamWriter(Path.Combine(exportationDir, FILENAME_STATUS_OVER_TIME)) { AutoFlush = true }) { // Prepare Action <string> logger = (string s) => { outputWriter.Write(s); Console.Write(s); }; Action <string> loggerLine = (string s) => { outputWriter.Write(s + Environment.NewLine); Console.WriteLine(s); }; statusWriter.WriteLine("% time incumbent"); config.LogSolutionStatus = (double timeStamp, double incumbent) => { statusWriter.WriteLine(timeStamp.ToString(ExportationConstants.FORMATTER) + ExportationConstants.GNUPLOT_DELIMITER + incumbent.ToString(ExportationConstants.FORMATTER)); }; config.Log = logger; config.Seed = int.Parse(seedNumber); IMethod method = null; switch (config.Type) { case MethodType.FrontLeftBottomStyle: { method = new LinearModelFLB(instance, config); } break; case MethodType.TetrisStyle: { method = new LinearModelTetris(instance, config); } break; case MethodType.HybridStyle: { method = new LinearModelHybrid(instance, config); } break; case MethodType.SpaceIndexed: throw new NotImplementedException("Space indexed model not working for now."); case MethodType.ExtremePointInsertion: { method = new ExtremePointInsertionHeuristic(instance, config); } break; case MethodType.SpaceDefragmentation: { method = new SpaceDefragmentationHeuristic(instance, config); } break; case MethodType.PushInsertion: { method = new PushInsertion(instance, config); } break; case MethodType.ALNS: { method = new ALNS(instance, config); } break; default: throw new ArgumentException("Unknown method: " + config.Type.ToString()); } // Output some information before starting loggerLine("Welcome to SardineCan CLI"); loggerLine("Parameters: " + instanceFile + " " + configFile + " " + outputDirectory + " " + seedNumber); loggerLine("Initializing ..."); loggerLine("Instance: " + instance.Name); loggerLine("Config: " + config.Name); loggerLine("Seed: " + seedNumber); loggerLine("Config-details: "); LogConfigDetails(config, logger); loggerLine(""); // Execute logger("Executing ... "); PerformanceResult result = method.Run(); // Log some information to the console loggerLine("Finished!"); loggerLine(""); loggerLine("Result outline:"); loggerLine("Obj: " + result.ObjectiveValue.ToString(CultureInfo.InvariantCulture)); loggerLine("VolumeContained: " + result.Solution.VolumeContained.ToString(CultureInfo.InvariantCulture)); loggerLine("VolumeOfContainers: " + result.Solution.VolumeOfContainers.ToString(CultureInfo.InvariantCulture)); loggerLine("VolumeContainedRelative: " + (result.Solution.VolumeContainedRelative * 100).ToString(CultureInfo.InvariantCulture) + "%"); loggerLine("VolumeOfContainersInUse: " + result.Solution.VolumeOfContainersInUse.ToString(CultureInfo.InvariantCulture)); loggerLine("NumberOfContainersInUse: " + result.Solution.NumberOfContainersInUse.ToString(CultureInfo.InvariantCulture)); loggerLine("NumberOfPiecesPacked: " + result.Solution.NumberOfPiecesPacked.ToString(CultureInfo.InvariantCulture)); loggerLine("SolutionTime: " + result.SolutionTime.TotalSeconds.ToString(CultureInfo.InvariantCulture) + "s"); // Log performance information using (StreamWriter solutionInfoWriter = new StreamWriter(File.Open(Path.Combine(exportationDir, "result.txt"), FileMode.Create))) { solutionInfoWriter.WriteLine("Runtime: " + result.SolutionTime.ToString()); solutionInfoWriter.WriteLine("ObjectiveValue: " + result.ObjectiveValue.ToString(ExportationConstants.FORMATTER)); solutionInfoWriter.WriteLine("BestBound: " + result.BestBound.ToString(ExportationConstants.FORMATTER)); solutionInfoWriter.WriteLine("RemainingGap: " + result.Gap.ToString(ExportationConstants.FORMATTER)); result.Instance.OutputInfo(solutionInfoWriter); //result.Solution.out // TODO define output of solution info } // Log footprint using (StreamWriter sw = new StreamWriter(Path.Combine(exportationDir, FILENAME_FOOTPRINT))) sw.WriteLine( instance.Name + ExportationConstants.CSV_DELIMITER + config.Name + ExportationConstants.CSV_DELIMITER + seedNumber + ExportationConstants.CSV_DELIMITER + instance.Containers.Count + ExportationConstants.CSV_DELIMITER + instance.Pieces.Count + ExportationConstants.CSV_DELIMITER + instance.Containers.Sum(c => c.VirtualPieces.Count).ToString(CultureInfo.InvariantCulture) + ExportationConstants.CSV_DELIMITER + instance.Containers.Sum(c => c.Slants.Count).ToString(CultureInfo.InvariantCulture) + ExportationConstants.CSV_DELIMITER + result.ObjectiveValue.ToString(CultureInfo.InvariantCulture) + ExportationConstants.CSV_DELIMITER + result.Solution.VolumeContained.ToString(CultureInfo.InvariantCulture) + ExportationConstants.CSV_DELIMITER + result.Solution.VolumeOfContainers.ToString(CultureInfo.InvariantCulture) + ExportationConstants.CSV_DELIMITER + (result.Solution.VolumeContainedRelative * 100).ToString(CultureInfo.InvariantCulture) + ExportationConstants.CSV_DELIMITER + result.Solution.VolumeOfContainersInUse.ToString(CultureInfo.InvariantCulture) + ExportationConstants.CSV_DELIMITER + result.Solution.NumberOfContainersInUse.ToString(CultureInfo.InvariantCulture) + ExportationConstants.CSV_DELIMITER + result.Solution.NumberOfPiecesPacked.ToString(CultureInfo.InvariantCulture) + ExportationConstants.CSV_DELIMITER + result.SolutionTime.TotalSeconds.ToString(CultureInfo.InvariantCulture)); // Write instance-solution as xml if (instance.Solutions.Any()) { instance.WriteXML(Path.Combine(exportationDir, "solution.xinst")); } } } }
/// <summary> /// Executes a single method-run /// </summary> /// <param name="exportationDir">The exportation dir to export the results to</param> /// <param name="logFilename">The name of the log-files</param> /// <param name="timeOut">A timeout in milliseconds</param> private void Execute(string exportationDir, string logFilename, int timeOut) { // Prepare IMethod method = null; switch (_methodToUse) { case MethodType.FrontLeftBottomStyle: { method = new LinearModelFLB(_instance, Config); } break; case MethodType.TetrisStyle: { method = new LinearModelTetris(_instance, Config); } break; case MethodType.HybridStyle: { method = new LinearModelHybrid(_instance, Config); } break; case MethodType.SpaceIndexed: throw new NotImplementedException("Space indexed model not working for now."); case MethodType.ExtremePointInsertion: { method = new ExtremePointInsertionHeuristic(_instance, Config); } break; case MethodType.SpaceDefragmentation: { method = new SpaceDefragmentationHeuristic(_instance, Config); } break; case MethodType.PushInsertion: { method = new PushInsertion(_instance, Config); } break; case MethodType.ALNS: { method = new ALNS(_instance, Config); } break; default: throw new ArgumentException("Unknown method: " + _methodToUse.ToString()); } // Write instance-solution as xml string xmlInstanceFile = logFilename + ".xinst"; if (!File.Exists(xmlInstanceFile)) { _instance.WriteXML(Path.Combine(exportationDir, xmlInstanceFile)); } _method = method; // Execute _startSingleSolveAction.Invoke(); PerformanceResult result = null; bool executionSuccess = Helper.TryExecute(method.Run, timeOut, out result); _finishSingleSolveAction.Invoke(); string solutionFile = logFilename + "_Solution.txt"; using (StreamWriter solutionInfoWriter = new StreamWriter(File.Open(Path.Combine(exportationDir, solutionFile), FileMode.Create))) { solutionInfoWriter.WriteLine("Runtime: " + ((executionSuccess) ? result.SolutionTime.ToString() : "timeout")); solutionInfoWriter.WriteLine("ObjectiveValue: " + ((executionSuccess) ? result.ObjectiveValue.ToString(ExportationConstants.FORMATTER) : "timeout")); solutionInfoWriter.WriteLine("BestBound: " + ((executionSuccess) ? result.BestBound.ToString(ExportationConstants.FORMATTER) : "timeout")); solutionInfoWriter.WriteLine("RemainingGap: " + ((executionSuccess) ? result.Gap.ToString(ExportationConstants.FORMATTER) : "timeout")); if (executionSuccess) { result.Instance.OutputInfo(solutionInfoWriter); } //result.Solution.out // TODO define output of solution info } // Log information if (executionSuccess) { _timeConsumed.Add(result.SolutionTime); _evaluationValues.Add(result.ObjectiveValue); _bestBounds.Add(result.BestBound); _gaps.Add(result.Gap); } else { _timeConsumed.Add(TimeSpan.FromMilliseconds(timeOut)); _evaluationValues.Add(0); _bestBounds.Add(double.NaN); _gaps.Add(double.NaN); } // Write statistics using (StreamWriter statisticsWriter = new StreamWriter(File.Open(Path.Combine(exportationDir, _statisticsFile), FileMode.Append))) { statisticsWriter.WriteLine( _instance.GetIdent() + ExportationConstants.CSV_DELIMITER + ((executionSuccess) ? result.SolutionTime.TotalSeconds.ToString(ExportationConstants.EXPORT_FORMAT_SHORT, ExportationConstants.FORMATTER) : TimeSpan.FromMilliseconds(timeOut).TotalSeconds.ToString(ExportationConstants.EXPORT_FORMAT_SHORT, ExportationConstants.FORMATTER)) + ExportationConstants.CSV_DELIMITER + ((executionSuccess) ? result.ObjectiveValue.ToString(ExportationConstants.EXPORT_FORMAT_SHORT, ExportationConstants.FORMATTER) : (0.0).ToString(ExportationConstants.EXPORT_FORMAT_SHORT, ExportationConstants.FORMATTER)) + ExportationConstants.CSV_DELIMITER + ((executionSuccess) ? result.BestBound.ToString(ExportationConstants.EXPORT_FORMAT_SHORT, ExportationConstants.FORMATTER) : double.NaN.ToString(ExportationConstants.EXPORT_FORMAT_SHORT, ExportationConstants.FORMATTER)) + ExportationConstants.CSV_DELIMITER + ((executionSuccess) ? result.Gap.ToString(ExportationConstants.EXPORT_FORMAT_SHORT, ExportationConstants.FORMATTER) : double.NaN.ToString(ExportationConstants.EXPORT_FORMAT_SHORT, ExportationConstants.FORMATTER))); } // Write instance-solution as xml if (_instance.Solutions.Any()) { _instance.WriteXML(Path.Combine(exportationDir, logFilename + "_Solution.xinst")); } // Draw visuals if (_method.HasSolution) { _submitAction(method.Solution, _method.HasSolution, exportationDir, logFilename); } // Wait a bit Thread.Sleep(5000); }
public static PerformanceResult Execute(Instance instance, Configuration config, Action <string> logger) { // Prepare logging void loggerLine(string msg) { logger?.Invoke(msg + Environment.NewLine); } config.Log = logger; // Init method IMethod method; switch (config.Type) { case MethodType.FrontLeftBottomStyle: { method = new LinearModelFLB(instance, config); } break; case MethodType.TetrisStyle: { method = new LinearModelTetris(instance, config); } break; case MethodType.HybridStyle: { method = new LinearModelHybrid(instance, config); } break; case MethodType.SpaceIndexed: throw new NotImplementedException("Space indexed model not working for now."); case MethodType.ExtremePointInsertion: { method = new ExtremePointInsertionHeuristic(instance, config); } break; case MethodType.SpaceDefragmentation: { method = new SpaceDefragmentationHeuristic(instance, config); } break; case MethodType.PushInsertion: { method = new PushInsertion(instance, config); } break; case MethodType.ALNS: { method = new ALNS(instance, config); } break; default: throw new ArgumentException("Unknown method: " + config.Type.ToString()); } // Output some information before starting loggerLine($">>> Welcome to SardineCan"); loggerLine($"Initializing ..."); loggerLine($"Instance: {instance.Name}"); loggerLine($"Config: {config.Name}"); loggerLine($"Seed: {config.Seed}"); loggerLine($"Config-details: "); LogConfigDetails(config, logger); logger?.Invoke(Environment.NewLine); // Execute loggerLine($"Executing ... "); PerformanceResult result = method.Run(); // Log some information to the console loggerLine($"Finished!"); loggerLine($"Result outline:"); loggerLine($"Obj: {result.ObjectiveValue.ToString(CultureInfo.InvariantCulture)}"); loggerLine($"VolumeContained: {result.Solution.VolumeContained.ToString(CultureInfo.InvariantCulture)}"); loggerLine($"VolumeOfContainers: {result.Solution.VolumeOfContainers.ToString(CultureInfo.InvariantCulture)}"); loggerLine($"VolumeContainedRelative: {(result.Solution.VolumeContainedRelative * 100).ToString(CultureInfo.InvariantCulture)}%"); loggerLine($"VolumeOfContainersInUse: {result.Solution.VolumeOfContainersInUse.ToString(CultureInfo.InvariantCulture)}"); loggerLine($"NumberOfContainersInUse: {result.Solution.NumberOfContainersInUse.ToString(CultureInfo.InvariantCulture)}"); loggerLine($"NumberOfPiecesPacked: {result.Solution.NumberOfPiecesPacked.ToString(CultureInfo.InvariantCulture)}"); loggerLine($"SolutionTime: {result.SolutionTime.TotalSeconds.ToString(CultureInfo.InvariantCulture)}s"); // We're done here return(result); }