Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3133_ProblemModifiers/HeuristicLab.Problems.Modifiers/SingleObjectiveModifiedProblem.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: 6.3 KB
Line 
1using System;
2using System.Linq;
3using HEAL.Attic;
4using HeuristicLab.Collections;
5using HeuristicLab.Common;
6using HeuristicLab.Core;
7using HeuristicLab.Optimization;
8using HeuristicLab.Parameters;
9
10namespace HeuristicLab.Problems.Modifiers {
11  [StorableType("4C46E221-E7E6-41B4-8CFB-35920CDCE6E8")]
12  [Creatable(CreatableAttribute.Categories.Problems, Priority = 90)]
13  [Item("SingleObjectiveModifiedProblem", "A wrapper problem for single-objective problems that should be evaluated using Hive.")]
14  public class SingleObjectiveModifiedProblem : SingleObjectiveBasicProblem<IEncoding>, IStatefulItem {
15
16    private readonly SingleObjectiveEndPointProblemModifier<IEncoding> endPoint = new SingleObjectiveEndPointProblemModifier<IEncoding>();
17    private ProblemModifier activeStart; //this is to avoid attaching to multiple modifiers
18    public override bool Maximization => false; // this is a fixed and readonly parameter in BasicProblem, we cannot change it dynamically (after the constructor).
19
20    #region Parameter Names
21    private const string ProblemParameterName = "Problem";
22    private const string ModifierParameterName = "Modifiers";
23    #endregion
24
25    #region Parameters
26    public IValueParameter<SingleObjectiveBasicProblem<IEncoding>> ProblemParameter => (IValueParameter<SingleObjectiveBasicProblem<IEncoding>>)Parameters[ProblemParameterName];
27
28    public IFixedValueParameter<CheckedItemList<ProblemModifier>> ModifierParameter => (IFixedValueParameter<CheckedItemList<ProblemModifier>>)Parameters[ModifierParameterName];
29    #endregion
30
31    #region Parameter Properties
32    public SingleObjectiveBasicProblem<IEncoding> Problem {
33      get => ProblemParameter.Value;
34      set => ProblemParameter.Value = value;
35    }
36
37    public CheckedItemList<ProblemModifier> Modifiers => ModifierParameter.Value;
38
39    #endregion
40
41    #region Constructors & Cloning
42    [StorableConstructor]
43    protected SingleObjectiveModifiedProblem(StorableConstructorFlag _) : base(_) { }
44    protected SingleObjectiveModifiedProblem(SingleObjectiveModifiedProblem original, Cloner cloner) : base(original, cloner) {
45      Initialize();
46    }
47    public SingleObjectiveModifiedProblem() {
48      var defaultModifiers = new CheckedItemList<ProblemModifier> {
49        {new EvaluationCacheProblemModifier(), false},
50        {new EvaluationRepetitionProblemModifier(), false},
51        {new EvaluationLoggingProblemModifier(), false}
52      };
53      Parameters.Add(new ValueParameter<SingleObjectiveBasicProblem<IEncoding>>(ProblemParameterName, "The actual problem that should used to evaluate individuals."));
54      Parameters.Add(new FixedValueParameter<CheckedItemList<ProblemModifier>>(ModifierParameterName, "The modifiers applied to the problem (order can be important)", defaultModifiers));
55      Initialize();
56    }
57
58    public override IDeepCloneable Clone(Cloner cloner) {
59      return new SingleObjectiveModifiedProblem(this, cloner);
60    }
61    #endregion
62
63    [StorableHook(HookType.AfterDeserialization)]
64    private void AfterDeserialization() {
65      Initialize();
66    }
67
68    private void Initialize() {
69      if (Problem != null) {
70        Problem.OperatorsChanged -= Problem_OperatorsChanged;
71        Problem.OperatorsChanged += Problem_OperatorsChanged;
72      }
73      ProblemParameter.ValueChanged -= ProblemParameter_ValueChanged;
74      ProblemParameter.ValueChanged += ProblemParameter_ValueChanged;
75      Modifiers.CheckedItemsChanged -= ActiveModifiersChanged;
76      Modifiers.CheckedItemsChanged += ActiveModifiersChanged;
77      Modifiers.ItemsMoved -= ActiveModifiersChanged; //This my fire unnecessarily but CheckedItemsChanged does not account for order ...
78      Modifiers.ItemsMoved += ActiveModifiersChanged;
79      UpdateModifiers();
80    }
81
82    public override double Evaluate(Individual individual, IRandom random) {
83      // this must be a minimization problem. If the wrapped problem is a maximization problem then just return the negative quality.
84      var wrappedQuality = activeStart.ModifiedEvaluate(individual, random)[0];
85      return Problem.Maximization ? -wrappedQuality : wrappedQuality;
86    }
87
88    public override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) {
89      activeStart.ModifiedAnalyze(individuals, qualities.Select(x => new[] { x }).ToArray(), results, random);
90    }
91
92    private bool updating;
93    private void UpdateModifiers() {
94      if (Problem == null || updating) return;
95      updating = true;
96      var am = Modifiers.CheckedItems.Select(x => x.Value).ToArray();
97
98      //unwire modifiers to prevent cycles while setting and superfluous listeners
99      foreach (var problemModifier in Modifiers) problemModifier.NextModifier = null;
100      //wire modifiers
101      for (var i = 0; i < am.Length - 1; i++) am[i].NextModifier = am[i + 1];
102      if (am.Length != 0) am[am.Length - 1].NextModifier = endPoint;
103      endPoint.Problem = Problem;
104
105      //listen to activeStart changes
106      if (activeStart != null) {
107        activeStart.EncodingChanged -= StartEncodingChanged;
108      }
109      activeStart = am.Length == 0 ? endPoint : am[0];
110      activeStart.EncodingChanged += StartEncodingChanged;
111
112      foreach (var m in Modifiers) m.Initialize();
113
114      updating = false;
115      if (Encoding == activeStart.Encoding || activeStart.Encoding == null) return;
116      Encoding = activeStart.Encoding;
117    }
118
119
120    private void StartEncodingChanged(object sender, EventArgs e) {
121      if (Encoding == activeStart.Encoding || activeStart.Encoding == null) return;
122      Encoding = activeStart.Encoding;
123    }
124    private void ActiveModifiersChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<ProblemModifier>> e) {
125      UpdateModifiers();
126    }
127
128    private void ProblemParameter_ValueChanged(object sender, EventArgs e) {
129      if (Problem != null) {
130        Problem.OperatorsChanged -= Problem_OperatorsChanged;
131        Problem.OperatorsChanged += Problem_OperatorsChanged;
132      }
133      endPoint.Problem = Problem;
134      UpdateModifiers();
135    }
136
137    private void Problem_OperatorsChanged(object sender, EventArgs e) {
138      UpdateModifiers();
139    }
140
141
142    void IStatefulItem.InitializeState() {
143      UpdateModifiers();
144    }
145
146    void IStatefulItem.ClearState() {
147      UpdateModifiers();
148    }
149  }
150}
Note: See TracBrowser for help on using the repository browser.