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.PermutationEncoding;


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


31  using HeuristicLab.Random;


32 


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


34  [Item("Univariate solution model (Permutation.Absolute)", "")]


35  [StorableClass]


36  public sealed class UnivariateAbsoluteModel : Item, ISolutionModel<Encodings.PermutationEncoding.Permutation> {


37  [Storable]


38  public DoubleMatrix Probabilities { get; set; }


39  [Storable]


40  public IRandom Random { get; set; }


41 


42  [StorableConstructor]


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


44  private UnivariateAbsoluteModel(UnivariateAbsoluteModel original, Cloner cloner)


45  : base(original, cloner) {


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


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


48  }


49  public UnivariateAbsoluteModel(IRandom random, double[,] probabilities) {


50  Probabilities = new DoubleMatrix(probabilities);


51  Random = random;


52  }


53  public UnivariateAbsoluteModel(IRandom random, DoubleMatrix probabilties) {


54  Probabilities = probabilties;


55  Random = random;


56  }


57 


58  public override IDeepCloneable Clone(Cloner cloner) {


59  return new UnivariateAbsoluteModel(this, cloner);


60  }


61 


62  public Encodings.PermutationEncoding.Permutation Sample() {


63  var N = Probabilities.Rows;


64  var child = new Encodings.PermutationEncoding.Permutation(PermutationTypes.Absolute, N);


65  var indices = Enumerable.Range(0, N).Shuffle(Random).ToList();


66  var values = Enumerable.Range(0, N).Shuffle(Random).ToList();


67  for (var i = N  1; i > 0; i) {


68  var nextIndex = indices[i];


69  var ball = Random.NextDouble();


70  for (var v = 0; v < values.Count; v++) {


71  ball = Probabilities[nextIndex, values[v]] + 1.0 / N;


72  if (ball > 0.0) continue;


73  child[nextIndex] = values[v];


74  values.RemoveAt(v);


75  indices.RemoveAt(i);


76  break;


77  }


78  if (ball > 0) {


79  var v = values.Count  1;


80  child[nextIndex] = values[v];


81  values.RemoveAt(v);


82  indices.RemoveAt(i);


83  }


84  }


85  child[indices[0]] = values[0];


86  return child;


87  }


88 


89  public static UnivariateAbsoluteModel CreateUnbiased(IRandom random, IList<Encodings.PermutationEncoding.Permutation> pop, int N) {


90  var model = new double[N, N];


91  var factor = 1.0 / pop.Count;


92  for (var i = 0; i < pop.Count; i++) {


93  for (var j = 0; j < N; j++) {


94  model[j, pop[i][j]] += factor;


95  }


96  }


97  return new UnivariateAbsoluteModel(random, model);


98  }


99 


100  public static UnivariateAbsoluteModel CreateWithRankBias(IRandom random, bool maximization, IList<Encodings.PermutationEncoding.Permutation> population, IEnumerable<double> qualities, int N) {


101  var popSize = 0;


102  var model = new double[N, N];


103 


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


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


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


107  popSize++;


108  for (var j = 0; j < N; j++) {


109  model[j, ind.Solution[j]] += popSize;


110  }


111  }


112  // normalize to [0;1]


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


114  for (var i = 0; i < N; i++) {


115  for (var j = 0; j < N; j++)


116  model[i, j] *= factor / popSize;


117  }


118  if (popSize == 0) throw new ArgumentException("Cannot train model from empty population.");


119  return new UnivariateAbsoluteModel(random, model);


120  }


121 


122  public static UnivariateAbsoluteModel CreateWithFitnessBias(IRandom random, bool maximization, IList<Encodings.PermutationEncoding.Permutation> population, IEnumerable<double> qualities, int N) {


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


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


125  var model = new double[N, N];


126 


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


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


129  for (var j = 0; j < N; j++) {


130  model[j, ind.Solution[j]] += ind.Proportion * factor;


131  }


132  }


133  }


134  return new UnivariateAbsoluteModel(random, model);


135  }


136  }


137  }

