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, 9 months 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
Line 
1#region License Information
2
3/* HeuristicLab
4 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
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
22#endregion License Information
23
24using System;
25using System.Linq;
26using System.Reflection;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Optimization;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31using HeuristicLab.Scripting;
32
33namespace HeuristicLab.Problems.Programmable {
34
35  [Item("ProblemDefinitionScript", "Script that defines the parameter vector and evaluates the solution for a programmable problem.")]
36  [StorableClass]
37  public abstract class ProblemDefinitionScript : Script, IProblemDefinition {
38    protected bool SuppressEvents { get; set; }
39
40    [Storable]
41    private VariableStore variableStore;
42
43    public VariableStore VariableStore {
44      get { return variableStore; }
45    }
46
47    [Storable]
48    private bool codeChanged;
49
50    [StorableConstructor]
51    protected ProblemDefinitionScript(bool deserializing) : base(deserializing) { }
52
53    protected ProblemDefinitionScript(ProblemDefinitionScript original, Cloner cloner)
54      : base(original, cloner) {
55      variableStore = cloner.Clone(original.variableStore);
56      codeChanged = original.codeChanged;
57    }
58
59    protected ProblemDefinitionScript()
60      : base() {
61      variableStore = new VariableStore();
62    }
63
64    protected ProblemDefinitionScript(string code)
65      : base(code) {
66      variableStore = new VariableStore();
67    }
68
69    IEncoding IProblemDefinition.Encoding {
70      get { return CompiledProblemDefinition.Encoding; }
71    }
72
73    private readonly object compileLock = new object();
74    private volatile IProblemDefinition compiledProblemDefinition;
75
76    protected IProblemDefinition CompiledProblemDefinition {
77      get {
78        // double checked locking pattern
79        if (compiledProblemDefinition == null) {
80          lock (compileLock) {
81            if (compiledProblemDefinition == null) {
82              if (codeChanged) throw new ProblemDefinitionScriptException("The code has been changed, but was not recompiled.");
83              Compile(false);
84            }
85          }
86        }
87        return compiledProblemDefinition;
88      }
89    }
90
91    public dynamic Instance {
92      get { return compiledProblemDefinition; }
93    }
94
95    public sealed override Assembly Compile() {
96      return Compile(true);
97    }
98
99    private Assembly Compile(bool fireChanged) {
100      var assembly = base.Compile();
101      var types = assembly.GetTypes();
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;
108      try {
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 {
116        inst.vars = new Variables(VariableStore);
117        inst.Initialize();
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 {
124        compiledProblemDefinition = inst;
125        if (fireChanged) OnProblemDefinitionChanged();
126      } catch (Exception e) {
127        compiledProblemDefinition = null;
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);
129      }
130
131      codeChanged = false;
132      return assembly;
133    }
134
135    protected override void OnCodeChanged() {
136      base.OnCodeChanged();
137      compiledProblemDefinition = null;
138      codeChanged = true;
139    }
140
141    public event EventHandler ProblemDefinitionChanged;
142
143    protected virtual void OnProblemDefinitionChanged() {
144      var handler = ProblemDefinitionChanged;
145      if (handler != null) handler(this, EventArgs.Empty);
146    }
147  }
148}
Note: See TracBrowser for help on using the repository browser.