Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/Problems/UserDefinedProblem.cs @ 17695

Last change on this file since 17695 was 17695, checked in by abeham, 4 years ago

#2521:

  • Moving solution creator parameter from problems to algorithms (breaking wiring in some HeuristicOptimizationProblems)
  • Disallowing evaluator or encoding changes in encoding-specific base problems (to avoid confusion in derived problems whether this needs to be handled or not)
  • Added private set to ReferenceParameter property (serialization)
File size: 10.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 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.Collections.Generic;
24using System.Drawing;
25using System.Linq;
26using System.Threading;
27using HEAL.Attic;
28using HeuristicLab.Collections;
29using HeuristicLab.Common;
30using HeuristicLab.Core;
31using HeuristicLab.Data;
32using HeuristicLab.Parameters;
33using HeuristicLab.PluginInfrastructure;
34
35namespace HeuristicLab.Optimization {
36  /// <summary>
37  /// A problem which can be defined by the user.
38  /// </summary>
39  [Item("User-Defined Problem", "A problem which can be defined by the user.")]
40  [Creatable(CreatableAttribute.Categories.Problems, Priority = 120)]
41  [StorableType("9F18A098-A8B8-4F70-93CF-79FF1496AC8A")]
42  public sealed class UserDefinedProblem : Problem, ISingleObjectiveHeuristicOptimizationProblem, IStorableContent {
43
44    public static new Image StaticItemImage {
45      get { return HeuristicLab.Common.Resources.VSImageLibrary.Type; }
46    }
47    public new ParameterCollection Parameters {
48      get { return base.Parameters; }
49    }
50    IKeyedItemCollection<string, IParameter> IParameterizedItem.Parameters {
51      get { return Parameters; }
52    }
53
54    #region Parameters
55    public IValueParameter<ISingleObjectiveEvaluator> EvaluatorParameter {
56      get { return (IValueParameter<ISingleObjectiveEvaluator>)Parameters["Evaluator"]; }
57    }
58    public ValueParameter<BoolValue> MaximizationParameter {
59      get { return (ValueParameter<BoolValue>)Parameters["Maximization"]; }
60    }
61    IParameter ISingleObjectiveHeuristicOptimizationProblem.MaximizationParameter {
62      get { return MaximizationParameter; }
63    }
64    IParameter IHeuristicOptimizationProblem.EvaluatorParameter {
65      get { return EvaluatorParameter; }
66    }
67    public OptionalValueParameter<DoubleValue> BestKnownQualityParameter {
68      get { return (OptionalValueParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
69    }
70    IParameter ISingleObjectiveHeuristicOptimizationProblem.BestKnownQualityParameter {
71      get { return BestKnownQualityParameter; }
72    }
73    public OptionalValueParameter<IScope> BestKnownSolutionParameter {
74      get { return (OptionalValueParameter<IScope>)Parameters["BestKnownSolution"]; }
75    }
76    public ValueParameter<ItemList<IItem>> OperatorsParameter {
77      get { return (ValueParameter<ItemList<IItem>>)Parameters["Operators"]; }
78    }
79    #endregion
80
81    #region Properties
82    public BoolValue Maximization {
83      get { return MaximizationParameter.Value; }
84      set { MaximizationParameter.Value = value; }
85    }
86    public ISingleObjectiveEvaluator Evaluator {
87      get { return EvaluatorParameter.Value; }
88      set { EvaluatorParameter.Value = value; }
89    }
90    ISingleObjectiveEvaluator ISingleObjectiveHeuristicOptimizationProblem.Evaluator {
91      get { return EvaluatorParameter.Value; }
92    }
93    IEvaluator IHeuristicOptimizationProblem.Evaluator {
94      get { return EvaluatorParameter.Value; }
95    }
96    public DoubleValue BestKnownQuality {
97      get { return BestKnownQualityParameter.Value; }
98      set { BestKnownQualityParameter.Value = value; }
99    }
100    public IEnumerable<IItem> Operators {
101      get { return OperatorsParameter.Value; }
102    }
103
104    public IEnumerable<IParameterizedItem> ExecutionContextItems {
105      get { yield return this; }
106    }
107    #endregion
108
109    [StorableConstructor]
110    private UserDefinedProblem(StorableConstructorFlag _) : base(_) { }
111    [StorableHook(HookType.AfterDeserialization)]
112    private void AfterDeserialization() {
113      // BackwardsCompatibility3.3
114      #region Backwards compatible code, remove with 3.4
115      if (Parameters.ContainsKey("Operators") && Parameters["Operators"] is ValueParameter<ItemList<IOperator>>) {
116        ItemList<IOperator> tmp = ((ValueParameter<ItemList<IOperator>>)Parameters["Operators"]).Value;
117        Parameters.Remove("Operators");
118        Parameters.Add(new ValueParameter<ItemList<IItem>>("Operators", "The operators and items that the problem provides to the algorithms.", new ItemList<IItem>(tmp)) { GetsCollected = false });
119      }
120      #endregion
121
122      RegisterEventHandlers();
123    }
124    public UserDefinedProblem()
125      : base() {
126      Parameters.Add(new ValueParameter<ISingleObjectiveEvaluator>("Evaluator", "The evaluator that collects the values to exchange.", new EmptyUserDefinedProblemEvaluator()));
127      Parameters.Add(new ValueParameter<BoolValue>("Maximization", "Set to false as most test functions are minimization problems.", new BoolValue(false)));
128      Parameters.Add(new OptionalValueParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this problem."));
129      Parameters.Add(new OptionalValueParameter<IScope>("BestKnownSolution", "The best known solution for this external evaluation problem."));
130      Parameters.Add(new ValueParameter<ItemList<IItem>>("Operators", "The operators and items that the problem provides to the algorithms.", new ItemList<IItem>()));
131
132      RegisterEventHandlers();
133    }
134
135    private UserDefinedProblem(UserDefinedProblem original, Cloner cloner)
136      : base(original, cloner) {
137      RegisterEventHandlers();
138    }
139    public override IDeepCloneable Clone(Cloner cloner) {
140      return new UserDefinedProblem(this, cloner);
141    }
142
143    #region Events
144    public event EventHandler EvaluatorChanged;
145    private void OnEvaluatorChanged() {
146      EventHandler handler = EvaluatorChanged;
147      if (handler != null) handler(this, EventArgs.Empty);
148    }
149    public event EventHandler OperatorsChanged;
150    private void OnOperatorsChanged() {
151      EventHandler handler = OperatorsChanged;
152      if (handler != null) handler(this, EventArgs.Empty);
153    }
154    #endregion
155
156    #region Event handlers
157    private void EvaluatorParameter_ValueChanged(object sender, EventArgs e) {
158      if (Evaluator != null)
159        Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
160      ParameterizeOperators();
161      OnEvaluatorChanged();
162    }
163    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
164      ParameterizeOperators();
165    }
166    private void OperatorsParameter_ValueChanged(object sender, EventArgs e) {
167      OnOperatorsChanged();
168    }
169    private void OperatorsParameter_Value_ItemsAdded(object sender, EventArgs e) {
170      OnOperatorsChanged();
171    }
172    private void OperatorsParameter_Value_ItemsRemoved(object sender, EventArgs e) {
173      OnOperatorsChanged();
174    }
175    private void OperatorsParameter_Value_CollectionReset(object sender, EventArgs e) {
176      OnOperatorsChanged();
177    }
178    #endregion
179
180    #region Helpers
181    private void RegisterEventHandlers() {
182      EvaluatorParameter.ValueChanged += new EventHandler(EvaluatorParameter_ValueChanged);
183      if (Evaluator != null)
184        Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
185      OperatorsParameter.ValueChanged += new EventHandler(OperatorsParameter_ValueChanged);
186      OperatorsParameter.Value.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IItem>>(OperatorsParameter_Value_ItemsAdded);
187      OperatorsParameter.Value.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<IItem>>(OperatorsParameter_Value_ItemsRemoved);
188      OperatorsParameter.Value.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<IItem>>(OperatorsParameter_Value_CollectionReset);
189    }
190
191    private void ParameterizeOperators() {
192      // A best effort approach to wiring
193      if (Evaluator != null) {
194        string qualityName = Evaluator.QualityParameter.ActualName;
195        foreach (IOperator op in OperatorsParameter.Value.OfType<IOperator>()) {
196          foreach (ILookupParameter<DoubleValue> param in op.Parameters.OfType<ILookupParameter<DoubleValue>>()) {
197            if (param.Name.Equals("Quality")) param.ActualName = qualityName;
198          }
199          foreach (IScopeTreeLookupParameter<DoubleValue> param in op.Parameters.OfType<IScopeTreeLookupParameter<DoubleValue>>()) {
200            if (param.Name.Equals("Quality")) param.ActualName = qualityName;
201          }
202        }
203      }
204    }
205    #endregion
206
207    [Item("EmptyUserDefinedProblemEvaluator", "A dummy evaluator that will throw an exception when executed.")]
208    [StorableType("E27E4145-6D44-4A9D-B15A-B0E0528ECD0D")]
209    [NonDiscoverableType]
210    private sealed class EmptyUserDefinedProblemEvaluator : ParameterizedNamedItem, ISingleObjectiveEvaluator {
211
212      [StorableConstructor]
213      private EmptyUserDefinedProblemEvaluator(StorableConstructorFlag _) : base(_) { }
214      private EmptyUserDefinedProblemEvaluator(EmptyUserDefinedProblemEvaluator original, Cloner cloner)
215        : base(original, cloner) {
216      }
217      public override IDeepCloneable Clone(Cloner cloner) {
218        return new EmptyUserDefinedProblemEvaluator(this, cloner);
219      }
220
221      #region ISingleObjectiveEvaluator Members
222
223      public ILookupParameter<DoubleValue> QualityParameter {
224        get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
225      }
226
227      #endregion
228
229      public EmptyUserDefinedProblemEvaluator() {
230        Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The solution quality."));
231      }
232
233      #region IOperator Members
234
235      public bool Breakpoint { get; set; }
236
237      public IOperation Execute(IExecutionContext context, CancellationToken cancellationToken) {
238        throw new InvalidOperationException("Please choose an appropriate evaluation operator.");
239      }
240
241#pragma warning disable 67
242      public event EventHandler BreakpointChanged;
243
244      public event EventHandler Executed;
245#pragma warning restore 67
246
247      #endregion
248
249      public static new Image StaticItemImage {
250        get { return HeuristicLab.Common.Resources.VSImageLibrary.Method; }
251      }
252    }
253  }
254}
Note: See TracBrowser for help on using the repository browser.