source: branches/2931_OR-Tools_LP_MIP/HeuristicLab.MathematicalOptimization/3.3/LinearProgramming/Algorithms/LinearProgrammingAlgorithm.cs @ 16582

Last change on this file since 16582 was 16582, checked in by ddorfmei, 7 months ago

#2931: solved the issues found during the review

File size: 8.1 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 Google.OrTools.LinearSolver;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Optimization;
29using HeuristicLab.Parameters;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31
32namespace HeuristicLab.ExactOptimization.LinearProgramming {
33
34  [Item("Mixed-Integer Linear Programming (LP, MIP)", "Linear/mixed integer programming implemented in several solvers. " +
35    "See also https://dev.heuristiclab.com/trac.fcgi/wiki/Documentation/Reference/ExactOptimization")]
36  [Creatable(CreatableAttribute.Categories.ExactAlgorithms)]
37  [StorableClass]
38  public sealed class LinearProgrammingAlgorithm : BasicAlgorithm {
39
40    [Storable]
41    private readonly IFixedValueParameter<DoubleValue> dualToleranceParam;
42
43    [Storable]
44    private readonly IFixedValueParameter<BoolValue> presolveParam;
45
46    [Storable]
47    private readonly IFixedValueParameter<DoubleValue> primalToleranceParam;
48
49    [Storable]
50    private readonly IFixedValueParameter<PercentValue> relativeGapToleranceParam;
51
52    [Storable]
53    private readonly IFixedValueParameter<BoolValue> scalingParam;
54
55    [Storable]
56    private readonly IFixedValueParameter<TimeSpanValue> timeLimitParam;
57
58    [Storable]
59    private IConstrainedValueParameter<ILinearSolver> linearSolverParam;
60
61    #region Problem Properties
62
63    public new LinearProblem Problem {
64      get => (LinearProblem)base.Problem;
65      set => base.Problem = value;
66    }
67
68    public override Type ProblemType { get; } = typeof(LinearProblem);
69
70    #endregion
71    #region Parameter Properties
72
73    public IFixedValueParameter<DoubleValue> DualToleranceParameter => dualToleranceParam;
74    public IConstrainedValueParameter<ILinearSolver> LinearSolverParameter => linearSolverParam;
75    public IFixedValueParameter<BoolValue> PresolveParameter => presolveParam;
76    public IFixedValueParameter<DoubleValue> PrimalToleranceParameter => primalToleranceParam;
77    public IFixedValueParameter<PercentValue> RelativeGapToleranceParameter => relativeGapToleranceParam;
78    public IFixedValueParameter<BoolValue> ScalingParameter => scalingParam;
79    public IFixedValueParameter<TimeSpanValue> TimeLimitParameter => timeLimitParam;
80
81    #endregion
82    #region Properties
83
84    public double DualTolerance {
85      get => dualToleranceParam.Value.Value;
86      set => dualToleranceParam.Value.Value = value;
87    }
88
89    public ILinearSolver LinearSolver {
90      get => linearSolverParam.Value;
91      set => linearSolverParam.Value = value;
92    }
93
94    public bool Presolve {
95      get => presolveParam.Value.Value;
96      set => presolveParam.Value.Value = value;
97    }
98
99    public double PrimalTolerance {
100      get => primalToleranceParam.Value.Value;
101      set => primalToleranceParam.Value.Value = value;
102    }
103
104    public double RelativeGapTolerance {
105      get => relativeGapToleranceParam.Value.Value;
106      set => relativeGapToleranceParam.Value.Value = value;
107    }
108
109    public bool Scaling {
110      get => scalingParam.Value.Value;
111      set => scalingParam.Value.Value = value;
112    }
113
114    public override bool SupportsPause => LinearSolver.SupportsPause;
115    public override bool SupportsStop => LinearSolver.SupportsStop;
116
117    public TimeSpan TimeLimit {
118      get => timeLimitParam.Value.Value;
119      set => timeLimitParam.Value.Value = value;
120    }
121
122    #endregion
123
124    public LinearProgrammingAlgorithm() {
125      Parameters.Add(linearSolverParam =
126        new ConstrainedValueParameter<ILinearSolver>(nameof(LinearSolver), "The solver used to solve the model."));
127
128      ILinearSolver defaultSolver;
129      linearSolverParam.ValidValues.Add(defaultSolver = new CoinOrSolver());
130      linearSolverParam.ValidValues.Add(new CplexSolver());
131      linearSolverParam.ValidValues.Add(new GlopSolver());
132      linearSolverParam.ValidValues.Add(new GurobiSolver());
133      linearSolverParam.ValidValues.Add(new ScipSolver());
134      linearSolverParam.Value = defaultSolver;
135
136      Parameters.Add(relativeGapToleranceParam = new FixedValueParameter<PercentValue>(nameof(RelativeGapTolerance),
137        "Limit for relative MIP gap.", new PercentValue(SolverParameters.DefaultRelativeMipGap)));
138      Parameters.Add(timeLimitParam = new FixedValueParameter<TimeSpanValue>(nameof(TimeLimit),
139        "Limit for runtime. Set to zero for unlimited runtime.",
140        new TimeSpanValue(new TimeSpan(0, 1, 0))));
141      Parameters.Add(presolveParam =
142        new FixedValueParameter<BoolValue>(nameof(Presolve), "Advanced usage: presolve mode.",
143          new BoolValue(SolverParameters.DefaultPresolve == SolverParameters.PresolveValues.PresolveOn)) { Hidden = true });
144      Parameters.Add(dualToleranceParam = new FixedValueParameter<DoubleValue>(nameof(DualTolerance),
145        "Advanced usage: tolerance for dual feasibility of basic solutions.",
146        new DoubleValue(SolverParameters.DefaultDualTolerance)) { Hidden = true });
147      Parameters.Add(primalToleranceParam = new FixedValueParameter<DoubleValue>(nameof(PrimalTolerance),
148        "Advanced usage: tolerance for primal feasibility of basic solutions. " +
149        "This does not control the integer feasibility tolerance of integer " +
150        "solutions for MIP or the tolerance used during presolve.",
151        new DoubleValue(SolverParameters.DefaultPrimalTolerance)) { Hidden = true });
152      Parameters.Add(scalingParam = new FixedValueParameter<BoolValue>(nameof(Scaling),
153        "Advanced usage: enable or disable matrix scaling.", new BoolValue()) { Hidden = true });
154
155      Problem = new LinearProblem();
156    }
157
158    [StorableConstructor]
159    private LinearProgrammingAlgorithm(bool deserializing)
160      : base(deserializing) {
161    }
162
163    private LinearProgrammingAlgorithm(LinearProgrammingAlgorithm original, Cloner cloner)
164      : base(original, cloner) {
165      linearSolverParam = cloner.Clone(original.linearSolverParam);
166      relativeGapToleranceParam = cloner.Clone(original.relativeGapToleranceParam);
167      timeLimitParam = cloner.Clone(original.timeLimitParam);
168      presolveParam = cloner.Clone(original.presolveParam);
169      dualToleranceParam = cloner.Clone(original.dualToleranceParam);
170      primalToleranceParam = cloner.Clone(original.primalToleranceParam);
171      scalingParam = cloner.Clone(original.scalingParam);
172    }
173
174    public override IDeepCloneable Clone(Cloner cloner) => new LinearProgrammingAlgorithm(this, cloner);
175
176    public override void Pause() {
177      base.Pause();
178      LinearSolver.InterruptSolve();
179    }
180
181    public override void Prepare() {
182      base.Prepare();
183      Results.Clear();
184
185      foreach (var solver in linearSolverParam.ValidValues) {
186        solver.Reset();
187      }
188    }
189
190    public override void Stop() {
191      base.Stop();
192      LinearSolver.InterruptSolve();
193    }
194
195    protected override void Run(CancellationToken cancellationToken) {
196      LinearSolver.PrimalTolerance = PrimalTolerance;
197      LinearSolver.DualTolerance = DualTolerance;
198      LinearSolver.Presolve = Presolve;
199      LinearSolver.RelativeGapTolerance = RelativeGapTolerance;
200      LinearSolver.Scaling = Scaling;
201      LinearSolver.TimeLimit = TimeLimit;
202      LinearSolver.Solve(Problem.ProblemDefinition, Results, cancellationToken);
203    }
204  }
205}
Note: See TracBrowser for help on using the repository browser.