Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3133_ProblemModifiers/HeuristicLab.Problems.Modifiers/MultiObjectiveModifiedProblem.cs @ 18029

Last change on this file since 18029 was 18029, checked in by bwerth, 3 years ago

#3133 added implementation of problem modifiers

File size: 7.6 KB
Line 
1using System;
2using System.Linq;
3using HEAL.Attic;
4using HeuristicLab.Collections;
5using HeuristicLab.Common;
6using HeuristicLab.Core;
7using HeuristicLab.Data;
8using HeuristicLab.Encodings.IntegerVectorEncoding;
9using HeuristicLab.Optimization;
10using HeuristicLab.Parameters;
11
12namespace HeuristicLab.Problems.Modifiers {
13  [StorableType("903EE850-62D5-4F3E-8F0D-8D9D5415A5F1")]
14  [Creatable(CreatableAttribute.Categories.Problems, Priority = 90)]
15  [Item("MultiObjectiveModifiedProblem", "A wrapper problem for multi-objective problems that should be evaluated using Hive.")]
16  public class MultiObjectiveModifiedProblem : MultiObjectiveBasicProblem<IEncoding>, IStatefulItem {
17    private readonly MultiObjectiveEndPointProblemModifier<IEncoding> endPoint = new MultiObjectiveEndPointProblemModifier<IEncoding>();
18    private ProblemModifier activeStart; //this is to avoid attaching to multiple modifiers
19    public override bool[] Maximization => Parameters.ContainsKey("Maximization") ? MaximizationParameter.Value.CloneAsArray() : new[] { false, false };
20
21    #region Parameter Names
22    private const string ProblemParameterName = "Problem";
23    private const string ModifierParameterName = "Modifiers";
24    #endregion
25
26    #region Parameters
27    public IValueParameter<MultiObjectiveBasicProblem<IEncoding>> ProblemParameter => (IValueParameter<MultiObjectiveBasicProblem<IEncoding>>)Parameters[ProblemParameterName];
28
29    public IFixedValueParameter<CheckedItemList<ProblemModifier>> ModifierParameter => (IFixedValueParameter<CheckedItemList<ProblemModifier>>)Parameters[ModifierParameterName];
30
31    public IValueParameter<BoolArray> MaximizationParameter => ((IValueParameter<BoolArray>)Parameters["Maximization"]);
32    #endregion
33
34    #region Parameter Properties
35    public MultiObjectiveBasicProblem<IEncoding> Problem {
36      get => ProblemParameter.Value;
37      set => ProblemParameter.Value = value;
38    }
39
40    public CheckedItemList<ProblemModifier> Modifiers => ModifierParameter.Value;
41    #endregion
42
43    #region Constructors & Cloning
44    [StorableConstructor]
45    protected MultiObjectiveModifiedProblem(StorableConstructorFlag _) : base(_) { }
46    protected MultiObjectiveModifiedProblem(MultiObjectiveModifiedProblem original, Cloner cloner) : base(original, cloner) {
47      Initialize();
48    }
49    public MultiObjectiveModifiedProblem() {
50      var defaultModifiers = new CheckedItemList<ProblemModifier> {
51        { new EvaluationCacheProblemModifier(), false },
52        { new EvaluationRepetitionProblemModifier(), false },
53        { new EvaluationLoggingProblemModifier(), false }
54      };
55      Parameters.Add(new ValueParameter<MultiObjectiveBasicProblem<IEncoding>>(ProblemParameterName, "The actual problem that should be used to evaluate individuals."));
56      Parameters.Add(new FixedValueParameter<CheckedItemList<ProblemModifier>>(ModifierParameterName, "The modifiers applied to the problem (order can be important)", defaultModifiers));
57      EncodingParameter.Hidden = true;
58      MaximizationParameter.Hidden = true;
59      SolutionCreatorParameter.Hidden = true;
60      EvaluatorParameter.Hidden = true;
61      Initialize();
62    }
63
64    public override IDeepCloneable Clone(Cloner cloner) {
65      return new MultiObjectiveModifiedProblem(this, cloner);
66    }
67    #endregion
68
69    [StorableHook(HookType.AfterDeserialization)]
70    private void AfterDeserialization() {
71      if (Encoding == null) Encoding = new IntegerVectorEncoding("null-encoding");
72      Initialize();
73    }
74
75    private void Initialize() {
76      if (Problem != null) {
77        Problem.OperatorsChanged -= Problem_OperatorsChanged;
78        Problem.OperatorsChanged += Problem_OperatorsChanged;
79      }
80      ProblemParameter.ValueChanged -= ProblemParameter_ValueChanged;
81      ProblemParameter.ValueChanged += ProblemParameter_ValueChanged;
82      Modifiers.CheckedItemsChanged -= ActiveModifiersChanged;
83      Modifiers.CheckedItemsChanged += ActiveModifiersChanged;
84      Modifiers.ItemsMoved -= ActiveModifiersChanged; //This my fire unnecessarily but CheckedItemsChanged does not account for order ...
85      Modifiers.ItemsMoved += ActiveModifiersChanged;
86      Modifiers.ItemsAdded -= ActiveModifiersChanged;
87      Modifiers.ItemsAdded += ActiveModifiersChanged;
88      Modifiers.ItemsRemoved -= ActiveModifiersChanged;
89      Modifiers.ItemsRemoved += ActiveModifiersChanged;
90      Modifiers.ItemsReplaced -= ActiveModifiersChanged;
91      Modifiers.ItemsReplaced += ActiveModifiersChanged;
92      UpdateModifiers();
93    }
94
95    public override double[] Evaluate(Individual individual, IRandom random) {
96      return activeStart.ModifiedEvaluate(individual, random);
97    }
98
99    public override void Analyze(Individual[] individuals, double[][] qualities, ResultCollection results, IRandom random) {
100      activeStart.ModifiedAnalyze(individuals, qualities, results, random);
101    }
102
103    private bool updating;
104    private void UpdateModifiers() {
105      if (Problem == null || updating) return;
106      updating = true;
107      var am = Modifiers.CheckedItems.Select(x => x.Value).ToArray();
108
109      //unwire modifiers to prevent cycles while setting and superfluous listeners
110      foreach (var problemModifier in Modifiers) problemModifier.NextModifier = null;
111      //wire modifiers
112      for (var i = 0; i < am.Length - 1; i++) am[i].NextModifier = am[i + 1];
113      if (am.Length != 0) am[am.Length - 1].NextModifier = endPoint;
114      endPoint.Problem = Problem;
115
116      //listen to activeStart changes
117      if (activeStart != null) {
118        activeStart.EncodingChanged -= StartEncodingChanged;
119        activeStart.MaximizationChanged -= StartMaximizationChanged;
120        activeStart.SolutionCreatorChanged -= StartSolutionCreatorChanged;
121      }
122      activeStart = am.Length == 0 ? endPoint : am[0];
123      activeStart.EncodingChanged += StartEncodingChanged;
124      activeStart.MaximizationChanged += StartMaximizationChanged;
125      activeStart.SolutionCreatorChanged += StartSolutionCreatorChanged;
126
127      foreach (var m in Modifiers) m.Initialize();
128
129      updating = false;
130      if (Encoding == activeStart.Encoding || activeStart.Encoding == null) return;
131      Encoding = activeStart.Encoding;
132    }
133
134    private void StartMaximizationChanged(object sender, EventArgs e) {
135      if (activeStart.Maximization == null) return;
136      MaximizationParameter.Value = (BoolArray)activeStart.Maximization.AsReadOnly();
137    }
138
139    private void StartEncodingChanged(object sender, EventArgs e) {
140      if (Encoding == activeStart.Encoding || activeStart.Encoding == null) return;
141      Encoding = activeStart.Encoding;
142    }
143
144    private void StartSolutionCreatorChanged(object sender, EventArgs e) {
145      if (SolutionCreator == activeStart.SolutionCreator || activeStart.SolutionCreator == null) return;
146      SolutionCreator = activeStart.SolutionCreator;
147    }
148
149    private void ActiveModifiersChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<ProblemModifier>> e) {
150      UpdateModifiers();
151    }
152
153    private void ProblemParameter_ValueChanged(object sender, EventArgs e) {
154      if (Problem != null) {
155        Problem.OperatorsChanged -= Problem_OperatorsChanged;
156        Problem.OperatorsChanged += Problem_OperatorsChanged;
157      }
158      endPoint.Problem = Problem;
159      UpdateModifiers();
160    }
161
162    private void Problem_OperatorsChanged(object sender, EventArgs e) {
163      UpdateModifiers();
164    }
165
166    void IStatefulItem.InitializeState() {
167      UpdateModifiers();
168    }
169
170    void IStatefulItem.ClearState() {
171      UpdateModifiers();
172    }
173  }
174}
Note: See TracBrowser for help on using the repository browser.