Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2931_OR-Tools_LP_MIP/HeuristicLab.Problems.Programmable/3.3/ProblemDefinitionScript.cs @ 16172

Last change on this file since 16172 was 16172, checked in by ddorfmei, 6 years ago

#2931:

  • created LinearProgrammingAlgorithm
    • created definitions for all LP/MIP solvers supported by OR-Tools
  • created LinearProgrammingProblem
    • created classes required for scripting: LinearProgrammingProblemDefinition, LinearProgrammingProblemDefinitionScript, CompiledLinearProgrammingProblemDefinition
    • created views: LinearProgrammingProblemView, LinearProgrammingProblemDefinitionScriptView
  • updated OR-Tools version in ExtLibs to 6.9
File size: 5.4 KB
RevLine 
[11484]1#region License Information
[16172]2
[11484]3/* HeuristicLab
[15583]4 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[11484]5 *
6 * This file is part of HeuristicLab.
7 *
8 * HeuristicLab is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * HeuristicLab is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 */
21
[16172]22#endregion License Information
23
[11484]24using System;
25using System.Linq;
26using System.Reflection;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
[11949]29using HeuristicLab.Optimization;
[11484]30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31using HeuristicLab.Scripting;
32
33namespace HeuristicLab.Problems.Programmable {
[16172]34
[11484]35  [Item("ProblemDefinitionScript", "Script that defines the parameter vector and evaluates the solution for a programmable problem.")]
36  [StorableClass]
[11739]37  public abstract class ProblemDefinitionScript : Script, IProblemDefinition {
[11484]38    protected bool SuppressEvents { get; set; }
39
40    [Storable]
41    private VariableStore variableStore;
[16172]42
[11484]43    public VariableStore VariableStore {
44      get { return variableStore; }
45    }
46
[11944]47    [Storable]
48    private bool codeChanged;
49
[11484]50    [StorableConstructor]
[11739]51    protected ProblemDefinitionScript(bool deserializing) : base(deserializing) { }
[16172]52
[11739]53    protected ProblemDefinitionScript(ProblemDefinitionScript original, Cloner cloner)
[11484]54      : base(original, cloner) {
55      variableStore = cloner.Clone(original.variableStore);
[11944]56      codeChanged = original.codeChanged;
[11484]57    }
[16172]58
[11753]59    protected ProblemDefinitionScript()
60      : base() {
[11484]61      variableStore = new VariableStore();
62    }
[16172]63
[13218]64    protected ProblemDefinitionScript(string code)
65      : base(code) {
66      variableStore = new VariableStore();
67    }
[11484]68
[11739]69    IEncoding IProblemDefinition.Encoding {
[11753]70      get { return CompiledProblemDefinition.Encoding; }
[11739]71    }
72
[11900]73    private readonly object compileLock = new object();
[11739]74    private volatile IProblemDefinition compiledProblemDefinition;
[16172]75
[11739]76    protected IProblemDefinition CompiledProblemDefinition {
[11484]77      get {
[11900]78        // double checked locking pattern
79        if (compiledProblemDefinition == null) {
80          lock (compileLock) {
81            if (compiledProblemDefinition == null) {
[11944]82              if (codeChanged) throw new ProblemDefinitionScriptException("The code has been changed, but was not recompiled.");
[11900]83              Compile(false);
84            }
85          }
86        }
[11739]87        return compiledProblemDefinition;
[11484]88      }
89    }
[16172]90
[15120]91    public dynamic Instance {
92      get { return compiledProblemDefinition; }
93    }
[11484]94
[11900]95    public sealed override Assembly Compile() {
96      return Compile(true);
97    }
98
[11944]99    private Assembly Compile(bool fireChanged) {
[11484]100      var assembly = base.Compile();
101      var types = assembly.GetTypes();
[11885]102      if (!types.Any(x => typeof(CompiledProblemDefinition).IsAssignableFrom(x)))
103        throw new ProblemDefinitionScriptException("The compiled code doesn't contain a problem definition." + Environment.NewLine + "The problem definition must be a subclass of CompiledProblemDefinition.");
104      if (types.Count(x => typeof(CompiledProblemDefinition).IsAssignableFrom(x)) > 1)
105        throw new ProblemDefinitionScriptException("The compiled code contains multiple problem definitions." + Environment.NewLine + "Only one subclass of CompiledProblemDefinition is allowed.");
106
107      CompiledProblemDefinition inst;
[11484]108      try {
[11885]109        inst = (CompiledProblemDefinition)Activator.CreateInstance(types.Single(x => typeof(CompiledProblemDefinition).IsAssignableFrom(x)));
110      } catch (Exception e) {
111        compiledProblemDefinition = null;
112        throw new ProblemDefinitionScriptException("Instantiating the problem definition failed." + Environment.NewLine + "Check your default constructor.", e);
113      }
114
115      try {
[11484]116        inst.vars = new Variables(VariableStore);
117        inst.Initialize();
[11885]118      } catch (Exception e) {
119        compiledProblemDefinition = null;
120        throw new ProblemDefinitionScriptException("Initializing the problem definition failed." + Environment.NewLine + "Check your Initialize() method.", e);
121      }
122
123      try {
[11900]124        compiledProblemDefinition = inst;
125        if (fireChanged) OnProblemDefinitionChanged();
[11880]126      } catch (Exception e) {
[11739]127        compiledProblemDefinition = null;
[11885]128        throw new ProblemDefinitionScriptException("Using the problem definition in the problem failed." + Environment.NewLine + "Examine this error message carefully (often there is an issue with the defined encoding).", e);
[11739]129      }
[11885]130
[11944]131      codeChanged = false;
[11484]132      return assembly;
133    }
134
135    protected override void OnCodeChanged() {
136      base.OnCodeChanged();
[11739]137      compiledProblemDefinition = null;
[11944]138      codeChanged = true;
[11484]139    }
140
[11739]141    public event EventHandler ProblemDefinitionChanged;
[16172]142
[11739]143    protected virtual void OnProblemDefinitionChanged() {
144      var handler = ProblemDefinitionChanged;
[11484]145      if (handler != null) handler(this, EventArgs.Empty);
146    }
147  }
[16172]148}
Note: See TracBrowser for help on using the repository browser.