Free cookie consent management tool by TermsFeed Policy Generator

source: branches/EfficientGlobalOptimization/HeuristicLab.Algorithms.EGO/DiscreteEGO/DiscreteInfillSolver.cs @ 15870

Last change on this file since 15870 was 15343, checked in by bwerth, 7 years ago

#2745 added discretized EGO-version for use with IntegerVectors

File size: 6.9 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 HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Encodings.IntegerVectorEncoding;
30using HeuristicLab.Optimization;
31using HeuristicLab.Parameters;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33using HeuristicLab.Problems.DataAnalysis;
34
35namespace HeuristicLab.Algorithms.EGO {
36  [Item("DiscreteInfillSolver", "An IntegerVectorCreator that creates candidates by optimizing an infill-subproblem")]
37  [StorableClass]
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(bool 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[dim % bounds.Rows, 2] * steps;
97        var low = checkIntBounds(bounds, dim, res[dim] - step);
98        var high = checkIntBounds(bounds, dim, res[dim] + step);
99        if (!low && !high) continue;
100        else if (low && high) res[dim] += (random.NextDouble() < 0.5 ? -step : step);
101        else if (low) res[dim] -= step;
102        else res[dim] += step;
103        changed = true;
104      }
105      return res;
106    }
107
108
109    private bool checkIntBounds(IntMatrix b, int row, int value) {
110      var bi = row % b.Rows;
111      var l = b[bi, 0];
112      var h = b[bi, 1];
113      var s = b[bi, 2];
114      return l <= value && h >= value && (value - l) % s == 0;
115    }
116
117    private IntegerVector OptimizeInfillProblem(IAlgorithm algorithm, IRegressionSolution model, bool maximization, IntMatrix bounds, int length, IRandom random) {
118      var infillProblem = algorithm.Problem as DiscreteInfillProblem;
119      if (infillProblem == null) throw new ArgumentException("The algortihm has no InfillProblem to solve");
120      infillProblem.Encoding.Length = length;
121      infillProblem.Encoding.Bounds = bounds;
122      infillProblem.Initialize(model, maximization);
123      var res = EgoUtilities.SyncRunSubAlgorithm(algorithm, random.Next(int.MaxValue), Cancellation);
124      var v = res[DiscreteInfillProblem.BestInfillSolutionResultName].Value as IntegerVector;
125      algorithm.Runs.Clear();
126      return v;
127    }
128
129    private static double GetMinDifference(IDataset data, IntegerVector r) {
130      var mind = double.MaxValue;
131      for (var i = 0; i < data.Rows; i++) {
132        var d = 0.0;
133        for (var j = 0; j < r.Length; j++) {
134          var d2 = data.GetDoubleValue("input" + j, i) - r[j];
135          d += d2 * d2;
136        }
137        if (!(d < mind)) continue;
138        mind = d;
139      }
140      return mind;
141    }
142
143
144
145  }
146}
Note: See TracBrowser for help on using the repository browser.