1 | using System.Linq;
|
---|
2 | using HeuristicLab.Common;
|
---|
3 | using HeuristicLab.Core;
|
---|
4 | using HeuristicLab.Data;
|
---|
5 | using HeuristicLab.Operators;
|
---|
6 | using HeuristicLab.Optimization;
|
---|
7 | using HeuristicLab.Parameters;
|
---|
8 | using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
|
---|
9 |
|
---|
10 | namespace HeuristicLab.Problems.MetaOptimization {
|
---|
11 | /// <summary>
|
---|
12 | /// TODO
|
---|
13 | /// </summary>
|
---|
14 | [Item("ReferenceQualityAnalyzer", "")]
|
---|
15 | [StorableClass]
|
---|
16 | public sealed class ReferenceQualityAnalyzer : SingleSuccessorOperator, IAnalyzer {
|
---|
17 |
|
---|
18 | public ValueLookupParameter<ResultCollection> ResultsParameter {
|
---|
19 | get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }
|
---|
20 | }
|
---|
21 | public ScopeTreeLookupParameter<ParameterConfigurationTree> ParameterConfigurationParameter {
|
---|
22 | get { return (ScopeTreeLookupParameter<ParameterConfigurationTree>)Parameters["ParameterConfigurationTree"]; }
|
---|
23 | }
|
---|
24 | public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
|
---|
25 | get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
|
---|
26 | }
|
---|
27 | public LookupParameter<DoubleArray> ReferenceQualityAveragesParameter {
|
---|
28 | get { return (LookupParameter<DoubleArray>)Parameters["ReferenceQualityAverages"]; }
|
---|
29 | }
|
---|
30 | public LookupParameter<DoubleArray> ReferenceQualityDeviationsParameter {
|
---|
31 | get { return (LookupParameter<DoubleArray>)Parameters["ReferenceQualityDeviations"]; }
|
---|
32 | }
|
---|
33 | public LookupParameter<DoubleArray> ReferenceEvaluatedSolutionAveragesParameter {
|
---|
34 | get { return (LookupParameter<DoubleArray>)Parameters["ReferenceEvaluatedSolutionAverages"]; }
|
---|
35 | }
|
---|
36 | public LookupParameter<ConstrainedItemList<IProblem>> ProblemsParameter {
|
---|
37 | get { return (LookupParameter<ConstrainedItemList<IProblem>>)Parameters[MetaOptimizationProblem.ProblemsParameterName]; }
|
---|
38 | }
|
---|
39 | public LookupParameter<BoolValue> MaximizationParameter {
|
---|
40 | get { return (LookupParameter<BoolValue>)Parameters["Maximization"]; }
|
---|
41 | }
|
---|
42 |
|
---|
43 | public ReferenceQualityAnalyzer()
|
---|
44 | : base() {
|
---|
45 | Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", ""));
|
---|
46 | Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", ""));
|
---|
47 | Parameters.Add(new ScopeTreeLookupParameter<ParameterConfigurationTree>("ParameterConfigurationTree", ""));
|
---|
48 | Parameters.Add(new LookupParameter<DoubleArray>("ReferenceQualityAverages", ""));
|
---|
49 | Parameters.Add(new LookupParameter<DoubleArray>("ReferenceQualityDeviations", ""));
|
---|
50 | Parameters.Add(new LookupParameter<DoubleArray>("ReferenceEvaluatedSolutionAverages", ""));
|
---|
51 | Parameters.Add(new LookupParameter<ConstrainedItemList<IProblem>>(MetaOptimizationProblem.ProblemsParameterName, ""));
|
---|
52 | Parameters.Add(new LookupParameter<BoolValue>("Maximization", "Set to false if the problem should be minimized."));
|
---|
53 | }
|
---|
54 |
|
---|
55 | [StorableConstructor]
|
---|
56 | private ReferenceQualityAnalyzer(bool deserializing) : base(deserializing) { }
|
---|
57 | private ReferenceQualityAnalyzer(ReferenceQualityAnalyzer original, Cloner cloner) : base(original, cloner) { }
|
---|
58 | public override IDeepCloneable Clone(Cloner cloner) {
|
---|
59 | return new ReferenceQualityAnalyzer(this, cloner);
|
---|
60 | }
|
---|
61 |
|
---|
62 | public override IOperation Apply() {
|
---|
63 | ResultCollection results = ResultsParameter.ActualValue;
|
---|
64 | ItemArray<ParameterConfigurationTree> solutions = ParameterConfigurationParameter.ActualValue;
|
---|
65 | ItemArray<DoubleValue> qualities = QualityParameter.ActualValue;
|
---|
66 | bool maximization = MaximizationParameter.ActualValue.Value;
|
---|
67 |
|
---|
68 | if (ReferenceQualityAveragesParameter.ActualValue == null) {
|
---|
69 | // this is generation zero. calculate the reference values and apply them on population. in future generations `AlgorithmRunsAnalyzer` will do the nomalization
|
---|
70 | DoubleArray referenceQualityAverages = CalculateReferenceQualityAverages(solutions, maximization);
|
---|
71 | DoubleArray referenceQualityDeviations = CalculateReferenceQualityDeviations(solutions, maximization);
|
---|
72 | DoubleArray referenceEvaluatedSolutionAverages = CalculateReferenceEvaluatedSolutionAverages(solutions, maximization);
|
---|
73 |
|
---|
74 | ReferenceQualityAveragesParameter.ActualValue = referenceQualityAverages;
|
---|
75 | ReferenceQualityDeviationsParameter.ActualValue = referenceQualityDeviations;
|
---|
76 | ReferenceEvaluatedSolutionAveragesParameter.ActualValue = referenceEvaluatedSolutionAverages;
|
---|
77 |
|
---|
78 | NormalizePopulation(solutions, qualities, referenceQualityAverages, referenceQualityDeviations, referenceEvaluatedSolutionAverages, 1, 1, 1, maximization);
|
---|
79 |
|
---|
80 | results.Add(new Result("ReferenceQualities", referenceQualityAverages));
|
---|
81 | results.Add(new Result("ReferenceQualityDeviations", referenceQualityDeviations));
|
---|
82 | results.Add(new Result("ReferenceEvaluatedSolutionAverages", referenceEvaluatedSolutionAverages));
|
---|
83 | }
|
---|
84 |
|
---|
85 | return base.Apply();
|
---|
86 | }
|
---|
87 |
|
---|
88 | private DoubleArray CalculateReferenceQualityAverages(ItemArray<ParameterConfigurationTree> solutions, bool maximization) {
|
---|
89 | DoubleArray references = new DoubleArray(ProblemsParameter.ActualValue.Count);
|
---|
90 | for (int pi = 0; pi < ProblemsParameter.ActualValue.Count; pi++) {
|
---|
91 | if (maximization)
|
---|
92 | references[pi] = solutions.Where(x => x.AverageQualities != null).Select(x => x.AverageQualities[pi]).Max();
|
---|
93 | else
|
---|
94 | references[pi] = solutions.Where(x => x.AverageQualities != null).Select(x => x.AverageQualities[pi]).Min();
|
---|
95 | }
|
---|
96 | return references;
|
---|
97 | }
|
---|
98 |
|
---|
99 | private DoubleArray CalculateReferenceQualityDeviations(ItemArray<ParameterConfigurationTree> solutions, bool maximization) {
|
---|
100 | DoubleArray references = new DoubleArray(ProblemsParameter.ActualValue.Count);
|
---|
101 | for (int pi = 0; pi < ProblemsParameter.ActualValue.Count; pi++) {
|
---|
102 | if (maximization)
|
---|
103 | references[pi] = solutions.Where(x => x.QualityStandardDeviations != null).Select(x => x.QualityStandardDeviations[pi]).Max();
|
---|
104 | else
|
---|
105 | references[pi] = solutions.Where(x => x.QualityStandardDeviations != null).Select(x => x.QualityStandardDeviations[pi]).Min();
|
---|
106 | }
|
---|
107 | return references;
|
---|
108 | }
|
---|
109 |
|
---|
110 | private DoubleArray CalculateReferenceEvaluatedSolutionAverages(ItemArray<ParameterConfigurationTree> solutions, bool maximization) {
|
---|
111 | DoubleArray references = new DoubleArray(ProblemsParameter.ActualValue.Count);
|
---|
112 | for (int pi = 0; pi < ProblemsParameter.ActualValue.Count; pi++) {
|
---|
113 | if (maximization)
|
---|
114 | references[pi] = solutions.Where(x => x.AverageEvaluatedSolutions != null).Select(x => x.AverageEvaluatedSolutions[pi]).Max();
|
---|
115 | else
|
---|
116 | references[pi] = solutions.Where(x => x.AverageEvaluatedSolutions != null).Select(x => x.AverageEvaluatedSolutions[pi]).Min();
|
---|
117 | }
|
---|
118 | return references;
|
---|
119 | }
|
---|
120 |
|
---|
121 | private void NormalizePopulation(ItemArray<ParameterConfigurationTree> solutions, ItemArray<DoubleValue> qualities,
|
---|
122 | DoubleArray referenceQualityAverages,
|
---|
123 | DoubleArray referenceQualityDeviations,
|
---|
124 | DoubleArray referenceEvaluatedSolutionAverages,
|
---|
125 | double qualityAveragesWeight,
|
---|
126 | double qualityDeviationsWeight,
|
---|
127 | double evaluatedSolutionsWeight,
|
---|
128 | bool maximization) {
|
---|
129 | for (int i = 0; i < solutions.Length; i++) {
|
---|
130 | if (solutions[i].AverageQualities == null || solutions[i].QualityStandardDeviations == null || solutions[i].AverageEvaluatedSolutions == null) {
|
---|
131 | // this parameterConfigurationTree has not been evaluated correctly (due to a faulty configuration, which led to an exception)
|
---|
132 | // since we are in generation zero, there is no WorstQuality available for a penalty value
|
---|
133 | double penaltyValue = maximization ? double.MinValue : double.MaxValue;
|
---|
134 | qualities[i].Value = penaltyValue;
|
---|
135 | } else {
|
---|
136 | qualities[i].Value = MetaOptimizationUtil.Normalize(solutions[i],
|
---|
137 | referenceQualityAverages.ToArray(),
|
---|
138 | referenceQualityDeviations.ToArray(),
|
---|
139 | referenceEvaluatedSolutionAverages.ToArray(),
|
---|
140 | qualityAveragesWeight,
|
---|
141 | qualityDeviationsWeight,
|
---|
142 | evaluatedSolutionsWeight,
|
---|
143 | maximization);
|
---|
144 | }
|
---|
145 | }
|
---|
146 | }
|
---|
147 | }
|
---|
148 | }
|
---|