source: branches/2931_OR-Tools_LP_MIP/HeuristicLab.MathematicalOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/Solver.cs @ 16373

Last change on this file since 16373 was 16373, checked in by ddorfmei, 3 months ago

#2931:

  • upgraded Google OR-Tools to version 6.10
  • added TextValue and TextValueView to be able to display and edit a multiline string
  • added parameter to set solver specific parameters for supported solvers
  • added support for the Protocol Buffers representation of models (import/export)
  • added import of MPS models
  • added pause/stop functionality to CplexSolver and GlpkSolver
  • refactored wrapper (LinearSolver and related enums)
  • added new algorithm category Exact for LinearProgrammingAlgorithm
File size: 5.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Threading;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27using HeuristicLab.Parameters;
28using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
29
30namespace HeuristicLab.MathematicalOptimization.LinearProgramming.Algorithms.Solvers.Base {
31
32  [StorableClass]
33  public class Solver : ParameterizedNamedItem, ISolver, IDisposable {
34
35    [Storable]
36    protected IValueParameter<EnumValue<ProblemType>> problemTypeParam;
37
38    protected LinearSolver solver;
39
40    [Storable]
41    protected IFixedValueParameter<TextValue> solverSpecificParametersParam;
42
43    public Solver() {
44      Parameters.Add(problemTypeParam =
45        new ValueParameter<EnumValue<ProblemType>>(nameof(ProblemType), new EnumValue<ProblemType>()));
46      Parameters.Add(solverSpecificParametersParam =
47        new FixedValueParameter<TextValue>(nameof(SolverSpecificParameters), new TextValue()));
48    }
49
50    [StorableConstructor]
51    protected Solver(bool deserializing)
52      : base(deserializing) {
53    }
54
55    protected Solver(Solver original, Cloner cloner)
56      : base(original, cloner) {
57      problemTypeParam = cloner.Clone(original.problemTypeParam);
58      solverSpecificParametersParam = cloner.Clone(original.solverSpecificParametersParam);
59    }
60
61    public ProblemType ProblemType {
62      get => problemTypeParam.Value.Value;
63      set => problemTypeParam.Value.Value = value;
64    }
65
66    public TextValue SolverSpecificParameters => solverSpecificParametersParam.Value;
67
68    public virtual bool SupportsPause => true;
69    public virtual bool SupportsStop => true;
70    protected virtual OptimizationProblemType OptimizationProblemType { get; }
71
72    public override IDeepCloneable Clone(Cloner cloner) => new Solver(this, cloner);
73
74    public void Dispose() => solver?.Dispose();
75
76    public bool InterruptSolve() => solver?.InterruptSolve() ?? false;
77
78    public virtual void Reset() {
79      solver?.Dispose();
80      solver = null;
81    }
82
83    public virtual void Solve(LinearProgrammingAlgorithm algorithm, CancellationToken cancellationToken) =>
84      Solve(algorithm);
85
86    public virtual void Solve(LinearProgrammingAlgorithm algorithm) =>
87      Solve(algorithm, algorithm.TimeLimit);
88
89    public virtual void Solve(LinearProgrammingAlgorithm algorithm, TimeSpan timeLimit) {
90      string libraryName = null;
91      if (this is IExternalSolver externalSolver)
92        libraryName = externalSolver.LibraryName;
93
94      if (solver == null) {
95        solver = new LinearSolver(OptimizationProblemType, s => algorithm.Problem.ProblemDefinition.BuildModel(s), Name,
96          libraryName);
97      }
98
99      solver.TimeLimit = timeLimit;
100      solver.RelativeGapTolerance = algorithm.RelativeGapTolerance;
101      solver.PrimalTolerance = algorithm.PrimalTolerance;
102      solver.DualTolerance = algorithm.DualTolerance;
103      solver.Presolve = algorithm.Presolve;
104      solver.Scaling = algorithm.Scaling;
105      solver.LpAlgorithm = algorithm.LpAlgorithm;
106      solver.Incrementality = true;
107
108      if (!solver.SetSolverSpecificParameters(SolverSpecificParameters.Value))
109        throw new ArgumentException("Solver specific parameters could not be set.");
110
111      solver.Solve();
112
113      algorithm.Problem.ProblemDefinition.Analyze(solver.Solver, algorithm.Results);
114      algorithm.Results.AddOrUpdateResult(nameof(solver.ResultStatus),
115        new EnumValue<ResultStatus>(solver.ResultStatus));
116      algorithm.Results.AddOrUpdateResult($"Best{nameof(solver.ObjectiveValue)}",
117        new DoubleValue(solver.ObjectiveValue ?? double.NaN));
118
119      if (solver.IsMip) {
120        algorithm.Results.AddOrUpdateResult($"Best{nameof(solver.ObjectiveBound)}",
121          new DoubleValue(solver.ObjectiveBound ?? double.NaN));
122        algorithm.Results.AddOrUpdateResult(nameof(solver.AbsoluteGap),
123          new DoubleValue(solver.AbsoluteGap ?? double.NaN));
124        algorithm.Results.AddOrUpdateResult(nameof(solver.RelativeGap),
125          new PercentValue(solver.RelativeGap ?? double.NaN));
126      }
127
128      algorithm.Results.AddOrUpdateResult(nameof(solver.NumberOfConstraints), new IntValue(solver.NumberOfConstraints));
129      algorithm.Results.AddOrUpdateResult(nameof(solver.NumberOfVariables), new IntValue(solver.NumberOfVariables));
130
131      if (solver.IsMip) {
132        algorithm.Results.AddOrUpdateResult(nameof(solver.NumberOfNodes), new DoubleValue(solver.NumberOfNodes));
133      }
134
135      algorithm.Results.AddOrUpdateResult(nameof(solver.Iterations), new DoubleValue(solver.Iterations));
136      algorithm.Results.AddOrUpdateResult(nameof(solver.SolverVersion), new StringValue(solver.SolverVersion));
137    }
138  }
139}
Note: See TracBrowser for help on using the repository browser.