Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
12/12/18 14:23:45 (5 years ago)
Author:
ddorfmei
Message:

#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:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2931_OR-Tools_LP_MIP/HeuristicLab.MathematicalOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/IncrementalSolver.cs

    r16288 r16373  
    2323using System.Linq;
    2424using System.Threading;
    25 using Google.OrTools.LinearSolver;
    2625using HeuristicLab.Analysis;
    2726using HeuristicLab.Common;
     
    3534  [StorableClass]
    3635  public class IncrementalSolver : Solver, IIncrementalSolver {
    37 
    38     [Storable]
    39     protected readonly IValueParameter<BoolValue> incrementalityParam;
    4036
    4137    [Storable]
     
    5551
    5652    public IncrementalSolver() {
    57       Parameters.Add(incrementalityParam = new ValueParameter<BoolValue>(nameof(Incrementality),
    58         "Advanced usage: incrementality from one solve to the next.",
    59         new BoolValue(MPSolverParameters.kDefaultIncrementality == MPSolverParameters.INCREMENTALITY_ON)));
    6053      Parameters.Add(qualityUpdateIntervalParam =
    6154        new ValueParameter<TimeSpanValue>(nameof(QualityUpdateInterval),
    62           "Time interval before solver is paused, resuls are retrieved and solver is resumed.",
    63           new TimeSpanValue(new TimeSpan(0, 0, 10))));
    64 
    65       incrementalityParam.Value.ValueChanged += (sender, args) => {
    66         if (((BoolValue)sender).Value) {
    67           qualityUpdateIntervalParam.Value = new TimeSpanValue(qualityUpdateIntervalParam.Value.Value);
     55          "Time interval before solver is paused, results are retrieved and solver is resumed. " +
     56          "Set to zero for no intermediate results and faster solving.", new TimeSpanValue(new TimeSpan(0, 0, 10))));
     57      problemTypeParam.Value.ValueChanged += (sender, args) => {
     58        if (SupportsQualityUpdate) {
     59          if (!Parameters.Contains(qualityUpdateIntervalParam)) {
     60            Parameters.Add(qualityUpdateIntervalParam);
     61          }
    6862        } else {
    69           qualityUpdateIntervalParam.Value = (TimeSpanValue)qualityUpdateIntervalParam.Value.AsReadOnly();
     63          Parameters.Remove(qualityUpdateIntervalParam);
    7064        }
    7165      };
     
    7468    protected IncrementalSolver(IncrementalSolver original, Cloner cloner)
    7569        : base(original, cloner) {
    76       programmingTypeParam = cloner.Clone(original.programmingTypeParam);
     70      problemTypeParam = cloner.Clone(original.problemTypeParam);
    7771      qualityUpdateIntervalParam = cloner.Clone(original.qualityUpdateIntervalParam);
    78       incrementalityParam = cloner.Clone(original.incrementalityParam);
    7972      if (original.qualityPerClock != null)
    8073        qualityPerClock = cloner.Clone(original.qualityPerClock);
    8174    }
    8275
    83     public bool Incrementality {
    84       get => incrementalityParam.Value.Value;
    85       set => incrementalityParam.Value.Value = value;
    86     }
     76    public virtual bool SupportsQualityUpdate => true;
    8777
    8878    public TimeSpan QualityUpdateInterval {
     
    9181    }
    9282
     83    protected virtual TimeSpan TimeLimit => QualityUpdateInterval;
     84
    9385    public override void Solve(LinearProgrammingAlgorithm algorithm, CancellationToken cancellationToken) {
    94       if (!Incrementality) {
     86      if (!SupportsQualityUpdate || QualityUpdateInterval == TimeSpan.Zero) {
    9587        base.Solve(algorithm, cancellationToken);
    9688        return;
     
    10193
    10294      if (!unlimitedRuntime) {
    103         var wallTime = ((TimeSpanValue)algorithm.Results.SingleOrDefault(r => r.Name == "Wall Time")?.Value)?.Value;
    104         if (wallTime.HasValue) {
    105           timeLimit -= wallTime.Value;
    106         }
     95        timeLimit -= algorithm.ExecutionTime;
    10796      }
    10897
    10998      var iterations = (long)timeLimit.TotalMilliseconds / (long)QualityUpdateInterval.TotalMilliseconds;
    11099      var remaining = timeLimit - TimeSpan.FromMilliseconds(iterations * QualityUpdateInterval.TotalMilliseconds);
    111       var validResultStatuses = new[] { ResultStatus.NOT_SOLVED, ResultStatus.FEASIBLE };
     100      var validResultStatuses = new[] { ResultStatus.NotSolved, ResultStatus.Feasible };
    112101
    113102      while (unlimitedRuntime || iterations > 0) {
    114         base.Solve(algorithm, QualityUpdateInterval, true);
     103        if (cancellationToken.IsCancellationRequested)
     104          return;
     105
     106        base.Solve(algorithm, TimeLimit);
    115107        UpdateQuality(algorithm);
    116108
    117         var resultStatus = ((EnumValue<ResultStatus>)algorithm.Results["Result Status"].Value).Value;
    118         if (!validResultStatuses.Contains(resultStatus) || cancellationToken.IsCancellationRequested)
     109        var resultStatus = ((EnumValue<ResultStatus>)algorithm.Results[nameof(solver.ResultStatus)].Value).Value;
     110        if (!validResultStatuses.Contains(resultStatus))
    119111          return;
    120112
     
    124116
    125117      if (remaining > TimeSpan.Zero) {
    126         base.Solve(algorithm, remaining, true);
     118        base.Solve(algorithm, remaining);
    127119        UpdateQuality(algorithm);
    128120      }
     
    132124      if (!algorithm.Results.Exists(r => r.Name == "QualityPerClock")) {
    133125        qualityPerClock = new IndexedDataTable<double>("Quality per Clock");
    134         qpcRow = new IndexedDataRow<double>("First-hit Graph Objective");
    135         bpcRow = new IndexedDataRow<double>("First-hit Graph Bound");
     126        qpcRow = new IndexedDataRow<double>("Objective Value");
     127        bpcRow = new IndexedDataRow<double>("Bound");
    136128        algorithm.Results.AddOrUpdateResult("QualityPerClock", qualityPerClock);
    137129      }
    138130
    139       var resultStatus = ((EnumValue<ResultStatus>)algorithm.Results["Result Status"].Value).Value;
     131      var resultStatus = ((EnumValue<ResultStatus>)algorithm.Results[nameof(solver.ResultStatus)].Value).Value;
    140132
    141       if (new[] { ResultStatus.ABNORMAL, ResultStatus.NOT_SOLVED, ResultStatus.UNBOUNDED }.Contains(resultStatus))
     133      if (new[] { ResultStatus.Abnormal, ResultStatus.NotSolved, ResultStatus.Unbounded }.Contains(resultStatus))
    142134        return;
    143135
    144       var objective = ((DoubleValue)algorithm.Results["Best Objective Value"].Value).Value;
    145       var bound = ((DoubleValue)algorithm.Results["Best Objective Bound"].Value).Value;
     136      var objective = ((DoubleValue)algorithm.Results[$"Best{nameof(solver.ObjectiveValue)}"].Value).Value;
     137      var bound = solver.IsMip ? ((DoubleValue)algorithm.Results[$"Best{nameof(solver.ObjectiveBound)}"].Value).Value : double.NaN;
    146138      var time = algorithm.ExecutionTime.TotalSeconds;
    147139
     
    151143          qpcRow.Values.Add(Tuple.Create(time, objective));
    152144          qualityPerClock.Rows.Add(qpcRow);
    153           algorithm.Results.AddOrUpdateResult("Best Solution Found At", new TimeSpanValue(TimeSpan.FromSeconds(time)));
     145          algorithm.Results.AddOrUpdateResult($"Best{nameof(solver.ObjectiveValue)}FoundAt", new TimeSpanValue(TimeSpan.FromSeconds(time)));
    154146        }
    155147      } else {
     
    158150        if (!objective.IsAlmost(previousBest)) {
    159151          qpcRow.Values.Add(Tuple.Create(time, objective));
    160           algorithm.Results.AddOrUpdateResult("Best Solution Found At", new TimeSpanValue(TimeSpan.FromSeconds(time)));
     152          algorithm.Results.AddOrUpdateResult($"Best{nameof(solver.ObjectiveValue)}FoundAt", new TimeSpanValue(TimeSpan.FromSeconds(time)));
    161153        }
    162154      }
     155
     156      if (!solver.IsMip)
     157        return;
    163158
    164159      if (!bpcRow.Values.Any()) {
Note: See TracChangeset for help on using the changeset viewer.