using System; using System.Collections.Generic; using System.Linq; using HeuristicLab.Data; namespace HeuristicLab.Algorithms.NSGA3 { public static class Utility { public static List Concat(List list1, List list2) { List resultList = new List(list1.Count + list2.Count); resultList.AddRange(list1); resultList.AddRange(list2); return resultList; } /// /// Returns the number of possible combinations of size from a set of /// size . /// /// /// /// /// /// Thrown, when > or when < 1. /// public static int NCR(int n, int r) { if (n < r) throw new InvalidOperationException($"Constraint was not met: n >= r (n = {n}, r = {r})"); if (r < 0) throw new InvalidOperationException($"Constraint was not met: r >= 0 (r = {r})"); if (n == r) return 1; r = Math.Max(r, n - r); long range1 = RangeMultiplication(r + 1, n - r); return (int)(range1 / Factorial(n - r)); } private static long RangeMultiplication(int start, int count) { long s = 1; return LeftFold((long a, int b) => checked(a * b), new List(Enumerable.Range(start, count)), s); } private static T2 LeftFold(Func func, List elements, T2 start) { var item = start; foreach (var element in elements) item = func(item, element); return item; } public static long Factorial(long n) { if (n < 0 || n > 30) throw new InvalidOperationException($"Constraint for n was not met: 0 <= n <= 30 (n = {n})"); long product = 1; for (long i = 2; i <= n; i++) product *= i; return product; } public static double[][] ToJaggedArray(this DoubleMatrix m) { if (m == null) return null; var a = new double[m.Rows][]; for (int i = m.Rows - 1; i >= 0; i--) { a[i] = new double[m.Columns]; for (int j = m.Columns - 1; j >= 0; j--) a[i][j] = m[i, j]; } return a; } public static DoubleMatrix ConvertToDoubleMatrix(List referencePoints) { return new DoubleMatrix(ToArray(referencePoints)); } public static double[][] ToFitnessMatrix(this List solutions) { double[][] data = new double[solutions.Count][]; for (int i = 0; i < solutions.Count; i++) { Solution solution = solutions[i]; data[i] = new double[solution.Objectives.Length]; for (int j = 0; j < solution.Objectives.Length; j++) { data[i][j] = solution.Objectives[j]; } } return data; } public static DoubleMatrix ToMatrix(this IEnumerable> data) { var d2 = data.ToArray(); var mat = new DoubleMatrix(d2.Length, d2[0].Count); for (var i = 0; i < mat.Rows; i++) for (var j = 0; j < mat.Columns; j++) mat[i, j] = d2[i][j]; return mat; } private static double[,] ToArray(List referencePoints) { if (referencePoints == null || !referencePoints.Any()) throw new ArgumentException($"{nameof(referencePoints)} is null or empty"); int obj = referencePoints.First().Values.Length; int pointCount = referencePoints.Count; double[,] array = new double[pointCount, obj]; for (int p = 0; p < pointCount; p++) for (int d = 0; d < obj; d++) array[p, d] = referencePoints[p].Values[d]; return array; } public static TOut Min(Func func, IEnumerable inputs) where TOut : IComparable { return MinArgMin(func, inputs).Item2; } public static TIn ArgMin(Func func, IEnumerable inputs) where TOut : IComparable { return MinArgMin(func, inputs).Item1; } /// /// Finds the value amongst such that the output value returned /// by is minimal. /// /// The input type for the function. /// The comparable output type of the function. /// The function for which to find the minimal value. /// /// The function arguments for which to find the one with the minimum output value when /// given to . /// /// public static Tuple MinArgMin(Func func, IEnumerable inputs) where TOut : IComparable { if (func == null) throw new ArgumentNullException(nameof(func)); if (inputs == null) throw new ArgumentNullException(nameof(inputs)); var it = inputs.GetEnumerator(); var hasItems = it.MoveNext(); if (!hasItems) throw new InvalidOperationException("No items given to find the minimum of"); // find minimum argument and minimum value var minArg = it.Current; var minValue = func(it.Current); while (it.MoveNext()) { var currentArg = it.Current; var currentValue = func(it.Current); if (minValue.CompareTo(currentValue) > 0) { minArg = currentArg; minValue = currentValue; } } return Tuple.Create(minArg, minValue); } public static TOut Max(Func func, IEnumerable inputs) where TOut : IComparable { return MaxArgMax(func, inputs).Item2; } public static TIn ArgMax(Func func, IEnumerable inputs) where TOut : IComparable { return MaxArgMax(func, inputs).Item1; } /// /// Finds the value amongst such that the output value returned /// by is as big as possible. /// /// The input type for the function. /// The comparable output type of the function. /// The function for which to find the biggest value. /// /// The function arguments for which to find the one with the biggest output value when /// given to . /// /// public static Tuple MaxArgMax(Func func, IEnumerable inputs) where TOut : IComparable { if (func == null) throw new ArgumentNullException(nameof(func)); if (inputs == null) throw new ArgumentNullException(nameof(inputs)); var it = inputs.GetEnumerator(); var hasItems = it.MoveNext(); if (!hasItems) throw new InvalidOperationException("No items given to find the maximum of"); // find maximum argument and maximum value var maxArg = it.Current; var maxValue = func(it.Current); while (it.MoveNext()) { var currentArg = it.Current; var currentValue = func(it.Current); if (maxValue.CompareTo(currentValue) < 0) { maxArg = currentArg; maxValue = currentValue; } } return Tuple.Create(maxArg, maxValue); } } }