1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022016 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 


22  using System;


23  using System.Collections.Generic;


24  using System.Linq;


25  using HeuristicLab.Algorithms.MemPR.Interfaces;


26  using HeuristicLab.Common;


27  using HeuristicLab.Core;


28  using HeuristicLab.Data;


29  using HeuristicLab.Encodings.BinaryVectorEncoding;


30  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;


31  using HeuristicLab.Random;


32 


33  namespace HeuristicLab.Algorithms.MemPR.Binary.SolutionModel.Univariate {


34  [Item("Univariate solution model (binary)", "")]


35  [StorableClass]


36  public sealed class UnivariateModel : Item, ISolutionModel<BinaryVector> {


37  [Storable]


38  public DoubleArray Probabilities { get; set; }


39  [Storable]


40  public IRandom Random { get; set; }


41 


42  [StorableConstructor]


43  private UnivariateModel(bool deserializing) : base(deserializing) { }


44  private UnivariateModel(UnivariateModel original, Cloner cloner)


45  : base(original, cloner) {


46  Probabilities = cloner.Clone(original.Probabilities);


47  Random = cloner.Clone(original.Random);


48  }


49  public UnivariateModel(IRandom random, int N) : this(random, Enumerable.Range(0, N).Select(x => 0.5).ToArray()) { }


50  public UnivariateModel(IRandom random, double[] probabilities) {


51  Probabilities = new DoubleArray(probabilities);


52  Random = random;


53  }


54  public UnivariateModel(IRandom random, DoubleArray probabilties) {


55  Probabilities = probabilties;


56  Random = random;


57  }


58 


59  public override IDeepCloneable Clone(Cloner cloner) {


60  return new UnivariateModel(this, cloner);


61  }


62 


63  public BinaryVector Sample() {


64  var vec = new BinaryVector(Probabilities.Length);


65  for (var i = 0; i < Probabilities.Length; i++)


66  vec[i] = Random.NextDouble() < Probabilities[i];


67  return vec;


68  }


69 


70  public static ISolutionModel<BinaryVector> CreateWithoutBias(IRandom random, IEnumerable<BinaryVector> population) {


71  double[] model = null;


72  var popSize = 0;


73  foreach (var p in population) {


74  popSize++;


75  if (model == null) model = new double[p.Length];


76  for (var x = 0; x < model.Length; x++) {


77  if (p[x]) model[x]++;


78  }


79  }


80  if (model == null) throw new ArgumentException("Cannot train model from empty population.");


81  // normalize to [0;1]


82  var factor = 1.0 / popSize;


83  for (var x = 0; x < model.Length; x++) {


84  model[x] *= factor;


85  }


86  return new UnivariateModel(random, model);


87  }


88 


89  public static ISolutionModel<BinaryVector> CreateWithRankBias(IRandom random, bool maximization, IEnumerable<BinaryVector> population, IEnumerable<double> qualities) {


90  var popSize = 0;


91 


92  double[] model = null;


93  var pop = population.Zip(qualities, (b, q) => new { Solution = b, Fitness = q });


94  foreach (var ind in maximization ? pop.OrderBy(x => x.Fitness) : pop.OrderByDescending(x => x.Fitness)) {


95  // from worst to best, worst solution has 1 vote, best solution N votes


96  popSize++;


97  if (model == null) model = new double[ind.Solution.Length];


98  for (var x = 0; x < model.Length; x++) {


99  if (ind.Solution[x]) model[x] += popSize;


100  }


101  }


102  if (model == null) throw new ArgumentException("Cannot train model from empty population.");


103  // normalize to [0;1]


104  var factor = 2.0 / (popSize + 1);


105  for (var i = 0; i < model.Length; i++) {


106  model[i] *= factor / popSize;


107  }


108  return new UnivariateModel(random, model);


109  }


110 


111  public static ISolutionModel<BinaryVector> CreateWithFitnessBias(IRandom random, bool maximization, IEnumerable<BinaryVector> population, IEnumerable<double> qualities) {


112  var proportions = Util.Auxiliary.PrepareProportional(qualities, true, !maximization);


113  var factor = 1.0 / proportions.Sum();


114  double[] model = null;


115  foreach (var ind in population.Zip(proportions, (p, q) => new { Solution = p, Proportion = q })) {


116  if (model == null) model = new double[ind.Solution.Length];


117  for (var x = 0; x < model.Length; x++) {


118  if (ind.Solution[x]) model[x] += ind.Proportion * factor;


119  }


120  }


121  if (model == null) throw new ArgumentException("Cannot train model from empty population.");


122  return new UnivariateModel(random, model);


123  }


124  }


125  }

