Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2745_EfficientGlobalOptimization/HeuristicLab.Algorithms.EGO/DiscreteEGO/DiscreteInfillSolver.cs @ 17915

Last change on this file since 17915 was 17337, checked in by bwerth, 5 years ago

#2745 forgot to add Storable Tags to Interfaces

File size: 7.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 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.Threading;
24using System.Linq;
25using System.Collections.Generic;
26using HEAL.Attic;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Data;
30using HeuristicLab.Encodings.IntegerVectorEncoding;
31using HeuristicLab.Optimization;
32using HeuristicLab.Parameters;
33using HeuristicLab.Problems.DataAnalysis;
34
35namespace HeuristicLab.Algorithms.EGO {
36  [Item("DiscreteInfillSolver", "An IntegerVectorCreator that creates candidates by optimizing an infill-subproblem")]
37    [StorableType("50004a0b-b3aa-438c-bd80-bd5ff1763683")]
38    public class DiscreteInfillSolver : IntegerVectorCreator, ICancellableOperator {
39
40    public ILookupParameter<IAlgorithm> InfillOptimizationAlgorithmParamter => (ILookupParameter<IAlgorithm>)Parameters["InfillAlgorithm"];
41    public ILookupParameter<IRegressionSolution> ModelParameter => (ILookupParameter<IRegressionSolution>)Parameters["Model"];
42    public ILookupParameter<BoolValue> MaximizationParameter => (ILookupParameter<BoolValue>)Parameters["Maximization"];
43    public ILookupParameter<BoolValue> RemoveDuplicatesParameter => (ILookupParameter<BoolValue>)Parameters["RemoveDuplicates"];
44    public IFixedValueParameter<DoubleValue> DuplicateCutoffParameter => (IFixedValueParameter<DoubleValue>)Parameters["Duplicates Cutoff"];
45    public ILookupParameter<IntMatrix> InfillBoundsParameter => (ILookupParameter<IntMatrix>)Parameters["InfillBounds"];
46
47    public CancellationToken Cancellation { get; set; }
48
49    [StorableConstructor]
50    protected DiscreteInfillSolver(StorableConstructorFlag deserializing) : base(deserializing) { }
51    protected DiscreteInfillSolver(DiscreteInfillSolver original, Cloner cloner) : base(original, cloner) { }
52    public DiscreteInfillSolver() {
53      Parameters.Add(new LookupParameter<IAlgorithm>("InfillAlgorithm", "The algorithm used to optimize the infill problem") { Hidden = true });
54      Parameters.Add(new LookupParameter<IRegressionSolution>("Model", "The RegressionSolution upon which the InfillProblem operates") { Hidden = true });
55      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "Whether the original problem is a maximization problem") { Hidden = true });
56      Parameters.Add(new LookupParameter<BoolValue>("RemoveDuplicates", "Whether duplicates shall be removed") { Hidden = true });
57      Parameters.Add(new FixedValueParameter<DoubleValue>("Duplicates Cutoff", "The cut off radius for", new DoubleValue(0.01)) { Hidden = false });
58      Parameters.Add(new LookupParameter<IntMatrix>("InfillBounds", "The bounds applied for infill solving") { Hidden = true });
59    }
60
61    public override IDeepCloneable Clone(Cloner cloner) {
62      return new DiscreteInfillSolver(this, cloner);
63    }
64
65    protected override IntegerVector Create(IRandom random, IntValue length, IntMatrix bounds) {
66      var infillBounds = InfillBoundsParameter.ActualValue;
67      if (infillBounds != null && infillBounds.Rows > 0) {
68        bounds = infillBounds;
69      }
70
71      var alg = InfillOptimizationAlgorithmParamter.ActualValue;
72      var model = ModelParameter.ActualValue;
73      var max = MaximizationParameter.ActualValue.Value;
74      var res = OptimizeInfillProblem(alg, model, max, bounds, length.Value, random);
75      var rad = DuplicateCutoffParameter.Value.Value;
76      if (!RemoveDuplicatesParameter.ActualValue.Value || GetMinDifference(model.ProblemData.Dataset, res) >= rad * rad) return res;
77
78      bool changed = false;
79      var steps = 0;
80      var dims = new List<int>();
81
82      //TODO this may take a long time to compute if many samples have already been evaluated in the surrounding area
83      //as the preferred region can not be sampled denser and denser due to the disceretization, the variance between two sampled points may be impossible to decease
84
85      //TODO speed up GetMinDifferecnce via tree-structure
86      while (!changed || GetMinDifference(model.ProblemData.Dataset, res) < rad * rad) {
87        if (dims.Count == 0) {
88          if (!changed && steps > 0) throw new ArgumentException("Can not avoid duplicate");
89          dims = Enumerable.Range(0, res.Length).ToList();
90          steps++;
91          changed = false;
92        }
93        var i = random.Next(dims.Count);
94        var dim = dims[i];
95        dims.RemoveAt(i);
96        var step = bounds.Columns>2?bounds[dim % bounds.Rows, 2]:1 * steps;
97       
98        var low = checkIntBounds(bounds, dim, res[dim] - step);
99        var high = checkIntBounds(bounds, dim, res[dim] + step);
100        if (!low && !high) continue;
101        else if (low && high) res[dim] += (random.NextDouble() < 0.5 ? -step : step);
102        else if (low) res[dim] -= step;
103        else res[dim] += step;
104        changed = true;
105      }
106      return res;
107    }
108
109
110    private bool checkIntBounds(IntMatrix b, int row, int value) {
111      var bi = row % b.Rows;
112      var l = b[bi, 0];
113      var h = b[bi, 1];
114      var s = b.Columns>2?b[bi, 2]:1;
115      return l <= value && h >= value && (value - l) % s == 0;
116    }
117
118    private IntegerVector OptimizeInfillProblem(IAlgorithm algorithm, IRegressionSolution model, bool maximization, IntMatrix bounds, int length, IRandom random) {
119      var infillProblem = algorithm.Problem as DiscreteInfillProblem;
120      if (infillProblem == null) throw new ArgumentException("The algortihm has no InfillProblem to solve");
121      infillProblem.Encoding.Length = length;
122      infillProblem.Encoding.Bounds = bounds;
123      infillProblem.Initialize(model, maximization);
124      var res = EgoUtilities.SyncRunSubAlgorithm(algorithm, random.Next(int.MaxValue), Cancellation);
125      var v = res[DiscreteInfillProblem.BestInfillSolutionResultName].Value as IntegerVector;
126      algorithm.Runs.Clear();
127      return v;
128    }
129
130    private static double GetMinDifference(IDataset data, IntegerVector r) {
131      var mind = double.MaxValue;
132      for (var i = 0; i < data.Rows; i++) {
133        var d = 0.0;
134        for (var j = 0; j < r.Length; j++) {
135          var d2 = data.GetDoubleValue("input" + j, i) - r[j];
136          d += d2 * d2;
137        }
138        if (!(d < mind)) continue;
139        mind = d;
140      }
141      return mind;
142    }
143
144
145
146  }
147}
Note: See TracBrowser for help on using the repository browser.