1  using System;


2  using System.Collections.Generic;


3  using System.Linq;


4  using HeuristicLab.Data;


5 


6  namespace HeuristicLab.Algorithms.NSGA3


7  {


8  internal static class Utility


9  {


10  internal static List<T> Concat<T>(List<T> list1, List<T> list2)


11  {


12  List<T> resultList = new List<T>(list1.Count + list2.Count);


13 


14  resultList.AddRange(list1);


15  resultList.AddRange(list2);


16 


17  return resultList;


18  }


19 


20  /// <summary>


21  /// Returns the number of possible combinations of size <paramref name="r" /> from a set of


22  /// size <paramref name="n" />.


23  /// </summary>


24  /// <param name="n"></param>


25  /// <param name="r"></param>


26  /// <returns></returns>


27  /// <exception cref="ArgumentException">


28  /// Thrown, when <paramref name="r" /> > <paramref name="n" /> or when <paramref name="r"


29  /// /> < 1.


30  /// </exception>


31  internal static int NCR(int n, int r)


32  {


33  if (n < r) throw new ArgumentException($"Constraint was not met: n >= r (n = {n}, r = {r})");


34  if (r < 1) throw new ArgumentException($"Constraint was not met: r >= 1 (r = {r})");


35  if (n == r) return n;


36  return Factorial(n) / (Factorial(r) * Factorial(n  r));


37  }


38 


39  internal static int Factorial(int n)


40  {


41  if (n <= 0) throw new ArgumentException($"Constraint for n was not met: 0 < n <= 30 (n = {n})");


42  int product = 1;


43  for (int i = 2; i <= n; i++)


44  product *= i;


45 


46  return product;


47  }


48 


49  internal static DoubleMatrix ConvertToDoubleMatrix(List<ReferencePoint> referencePoints)


50  {


51  return new DoubleMatrix(ToArray(referencePoints));


52  }


53 


54  internal static double[][] ToFitnessMatrix(this List<Solution> solutions)


55  {


56  double[][] data = new double[solutions.Count][];


57  for (int i = 0; i < solutions.Count; i++)


58  {


59  Solution solution = solutions[i];


60  data[i] = new double[solution.Fitness.Length];


61  for (int j = 0; j < solution.Fitness.Length; j++)


62  {


63  data[i][j] = solution.Fitness[j];


64  }


65  }


66 


67  return data;


68  }


69 


70  internal static DoubleMatrix ToMatrix(this IEnumerable<IReadOnlyList<double>> data)


71  {


72  var d2 = data.ToArray();


73  var mat = new DoubleMatrix(d2.Length, d2[0].Count);


74  for (var i = 0; i < mat.Rows; i++)


75  for (var j = 0; j < mat.Columns; j++)


76  mat[i, j] = d2[i][j];


77  return mat;


78  }


79 


80  private static double[,] ToArray(List<ReferencePoint> referencePoints)


81  {


82  if (referencePoints == null  !referencePoints.Any()) throw new ArgumentException($"{nameof(referencePoints)} is null or empty");


83  int nDim = referencePoints.First().NumberOfDimensions;


84  int pointCount = referencePoints.Count;


85  double[,] array = new double[nDim, pointCount];


86 


87  for (int p = 0; p < pointCount; p++)


88  for (int d = 0; d < nDim; d++)


89  array[d, p] = referencePoints[p].Values[d];


90 


91  return array;


92  }


93 


94  internal static TOut Min<TIn, TOut>(Func<TIn, TOut> func, IEnumerable<TIn> inputs) where TOut : IComparable


95  {


96  return MinArgMin(func, inputs).Item2;


97  }


98 


99  internal static TIn ArgMin<TIn, TOut>(Func<TIn, TOut> func, IEnumerable<TIn> inputs) where TOut : IComparable


100  {


101  return MinArgMin(func, inputs).Item1;


102  }


103 


104  /// <summary>


105  /// Finds the value amongst <paramref name="inputs" /> such that the output value returned


106  /// by <paramref name="func" /> is minimal.


107  /// </summary>


108  /// <typeparam name="TIn">The input type for the function.</typeparam>


109  /// <typeparam name="TOut">The comparable output type of the function.</typeparam>


110  /// <param name="func">The function for which to find the minimal value.</param>


111  /// <param name="inputs">


112  /// The function arguments for which to find the one with the minimum output value when


113  /// given to <paramref name="func" />.


114  /// </param>


115  /// <returns></returns>


116  internal static Tuple<TIn, TOut> MinArgMin<TIn, TOut>(Func<TIn, TOut> func, IEnumerable<TIn> inputs) where TOut : IComparable


117  {


118  if (func == null) throw new ArgumentNullException(nameof(func));


119  if (inputs == null) throw new ArgumentNullException(nameof(inputs));


120  var it = inputs.GetEnumerator();


121  var hasItems = it.MoveNext();


122  if (!hasItems) throw new InvalidOperationException("No items given to find the minimum of");


123 


124  // find minimum argument and minimum value


125  var minArg = it.Current;


126  var minValue = func(it.Current);


127  while (it.MoveNext())


128  {


129  var currentArg = it.Current;


130  var currentValue = func(it.Current);


131  if (minValue.CompareTo(currentValue) > 0)


132  {


133  minArg = currentArg;


134  minValue = currentValue;


135  }


136  }


137 


138  return Tuple.Create(minArg, minValue);


139  }


140 


141  internal static TOut Max<TIn, TOut>(Func<TIn, TOut> func, IEnumerable<TIn> inputs) where TOut : IComparable


142  {


143  return MaxArgMax(func, inputs).Item2;


144  }


145 


146  internal static TIn ArgMax<TIn, TOut>(Func<TIn, TOut> func, IEnumerable<TIn> inputs) where TOut : IComparable


147  {


148  return MaxArgMax(func, inputs).Item1;


149  }


150 


151  /// <summary>


152  /// Finds the value amongst <paramref name="inputs" /> such that the output value returned


153  /// by <paramref name="func" /> is as big as possible.


154  /// </summary>


155  /// <typeparam name="TIn">The input type for the function.</typeparam>


156  /// <typeparam name="TOut">The comparable output type of the function.</typeparam>


157  /// <param name="func">The function for which to find the biggest value.</param>


158  /// <param name="inputs">


159  /// The function arguments for which to find the one with the biggest output value when


160  /// given to <paramref name="func" />.


161  /// </param>


162  /// <returns></returns>


163  internal static Tuple<TIn, TOut> MaxArgMax<TIn, TOut>(Func<TIn, TOut> func, IEnumerable<TIn> inputs) where TOut : IComparable


164  {


165  if (func == null) throw new ArgumentNullException(nameof(func));


166  if (inputs == null) throw new ArgumentNullException(nameof(inputs));


167  var it = inputs.GetEnumerator();


168  var hasItems = it.MoveNext();


169  if (!hasItems) throw new InvalidOperationException("No items given to find the maximum of");


170 


171  // find maximum argument and maximum value


172  var maxArg = it.Current;


173  var maxValue = func(it.Current);


174  while (it.MoveNext())


175  {


176  var currentArg = it.Current;


177  var currentValue = func(it.Current);


178  if (maxValue.CompareTo(currentValue) < 0)


179  {


180  maxArg = currentArg;


181  maxValue = currentValue;


182  }


183  }


184 


185  return Tuple.Create(maxArg, maxValue);


186  }


187  }


188  } 
