private static SolverResult Solve(Config config, SolverConfig solverConfig, Instance instance) { var solver = new SolverFactory().Create(config.SolverName); Console.WriteLine($"Starting solver: {solver.GetType().Name}"); var solverResult = solver.Solve(solverConfig, instance); Console.WriteLine($"Solver finished."); if (solverResult.Status == Status.Heuristic || solverResult.Status == Status.Optimal) { Console.WriteLine($"Solution found, checking its feasibility."); var feasibilityChecker = new FeasibilityChecker(); var feasibilityCheckStatus = feasibilityChecker.Check( instance, solverResult.StartTimes, solverConfig, solverResult.Objective); if (feasibilityCheckStatus != FeasibilityChecker.FeasibilityStatus.Feasible) { throw new Exception($"Solution not feasible: {feasibilityCheckStatus}"); } Console.WriteLine($"Solution feasible."); } else { Console.WriteLine($"No solution found."); } return(solverResult); }
private static int Run(CmdOptions opts) { var prescriptionPath = ExperimentPrescriptionPath(opts); if (!File.Exists(prescriptionPath)) { Console.WriteLine($"Experiment prescription file {prescriptionPath} does not exist."); return(1); } var prescription = JsonConvert.DeserializeObject <Prescription>( File.ReadAllText(prescriptionPath), new JsonSerializerSettings() { DefaultValueHandling = DefaultValueHandling.Populate }); if (!Directory.Exists(Program.DatasetsPath(opts))) { Console.WriteLine($"Datasets directory {Program.DatasetsPath(opts)} does not exist."); return(1); } foreach (var datasetName in prescription.DatasetNames) { var datasetPath = DatasetPath(opts, datasetName); if (!Directory.Exists(datasetPath)) { Console.WriteLine($"Dataset directory {datasetPath} does not exist."); return(1); } } if (opts.FromScratch) { foreach (var datasetName in prescription.DatasetNames) { foreach (var solverPrescription in prescription.Solvers) { var solverResultsPath = ResultsExperimentDatasetSolverPath( opts, datasetName, solverPrescription.Id); if (Directory.Exists(solverResultsPath)) { Directory.Delete(solverResultsPath, true); } } } } // TODO: if (opts.NumThreads != 1) { Console.WriteLine($"Parallel instance solving is not currently supported due to:"); Console.WriteLine($"- optimal switching cost is computed in parallel and there is no option to disable this"); return(1); } var objectLock = new object(); foreach (var datasetName in prescription.DatasetNames) { var instancePaths = Directory.EnumerateFiles(DatasetPath(opts, datasetName)).ToList(); foreach (var solverPrescription in prescription.Solvers) { var prescriptionSolverConfig = PrescriptionSolverConfig.Merge( prescription.GlobalConfig, solverPrescription.Config); Parallel.ForEach( instancePaths, new ParallelOptions { MaxDegreeOfParallelism = opts.NumThreads }, (instancePath) => { try { Console.WriteLine($"Solving {instancePath} using {solverPrescription.Id}"); var resultPath = ResultPath( opts, datasetName, solverPrescription.Id, Path.GetFileName(instancePath)); if (opts.FromScratch == false && File.Exists(resultPath)) { Console.WriteLine($"{instancePath} using {solverPrescription.Id} already solved"); return; } var instance = new InputReader().ReadFromPath(instancePath); SolverConfig solverConfig; lock (objectLock) { solverConfig = prescriptionSolverConfig.ToSolverConfig(solverPrescription.SpecializedSolverConfig); } if (solverPrescription.InitStartTimesFrom != null) { var initStartTimesResultPath = ResultPath( opts, datasetName, solverPrescription.InitStartTimesFrom, Path.GetFileName(instancePath)); var initStartTimesResult = JsonConvert.DeserializeObject <Result>( File.ReadAllText(initStartTimesResultPath)); if (initStartTimesResult.Status == Status.Optimal || initStartTimesResult.Status == Status.Heuristic) { solverConfig.InitStartTimes = initStartTimesResult.StartTimes; } } if (solverPrescription.SubstractExtendedInstanceGenerationFromTimeLimit && solverConfig.TimeLimit.HasValue && instance.TimeForExtendedInstance.HasValue) { solverConfig.TimeLimit = new TimeSpan(Math.Max( 0, solverConfig.TimeLimit.Value.Ticks - instance.TimeForExtendedInstance.Value.Ticks)); } var solver = new SolverFactory().Create(solverPrescription.SolverName); var solverResult = solver.Solve(solverConfig, instance); if (solverResult.Status == Status.Optimal || solverResult.Status == Status.Heuristic) { var feasibilityChecker = new FeasibilityChecker(); var feasibilityStatus = feasibilityChecker.Check(instance, solverResult.StartTimes, solverConfig, solverResult.Objective); if (feasibilityStatus != FeasibilityChecker.FeasibilityStatus.Feasible) { throw new Exception($"Feasibility check failed: {feasibilityStatus}, {instancePath}, {solverPrescription.Id}"); } } lock (objectLock) { if (!Directory.Exists(Path.GetDirectoryName(resultPath))) { Directory.CreateDirectory(Path.GetDirectoryName(resultPath)); } } File.WriteAllText( resultPath, JsonConvert.SerializeObject(Result.FromSolverResult(solverResult))); } catch (Exception) { Console.WriteLine($"Error while solving {instancePath} using {solverPrescription.Id}"); throw; } }); } } return(0); }