コード例 #1
0
 /// <summary>
 /// Merges two prescriptions. The general prescription behaves as default values that can be overriden by the
 /// specific prescription.
 /// </summary>
 /// <param name="general">The general prescription.</param>
 /// <param name="specific">The specific prescription.</param>
 /// <returns>The merged prescription.</returns>
 public static PrescriptionSolverConfig Merge(PrescriptionSolverConfig general, PrescriptionSolverConfig specific)
 {
     return(new PrescriptionSolverConfig
     {
         RandomSeed = specific == null || specific.RandomSeed.HasValue == false ?
                      general.RandomSeed : specific.RandomSeed.Value,
         TimeLimit = specific == null || specific.TimeLimit.HasValue == false ?
                     general.TimeLimit : specific.TimeLimit.Value,
         NumWorkers = specific == null || specific.NumWorkers.HasValue == false ?
                      general.NumWorkers : specific.NumWorkers.Value,
         PresolveLevel = specific == null || specific.PresolveLevel.HasValue == false ?
                         general.PresolveLevel : specific.PresolveLevel.Value,
     });
 }
コード例 #2
0
        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);
        }