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 (inputs == null) throw new ArgumentNullException(nameof(inputs));
|
---|
119 | var it = inputs.GetEnumerator();
|
---|
120 | var hasItems = it.MoveNext();
|
---|
121 | if (!hasItems) throw new InvalidOperationException("No items given to find the minimum of");
|
---|
122 |
|
---|
123 | // find minimum argument and minimum value
|
---|
124 | var minArg = it.Current;
|
---|
125 | var minValue = func(it.Current);
|
---|
126 | while (it.MoveNext())
|
---|
127 | {
|
---|
128 | var currentArg = it.Current;
|
---|
129 | var currentValue = func(it.Current);
|
---|
130 | if (minValue.CompareTo(currentValue) > 0)
|
---|
131 | {
|
---|
132 | minArg = currentArg;
|
---|
133 | minValue = currentValue;
|
---|
134 | }
|
---|
135 | }
|
---|
136 |
|
---|
137 | return Tuple.Create(minArg, minValue);
|
---|
138 | }
|
---|
139 |
|
---|
140 | internal static TOut Max<TIn, TOut>(Func<TIn, TOut> func, IEnumerable<TIn> inputs) where TOut : IComparable
|
---|
141 | {
|
---|
142 | return MaxArgMax(func, inputs).Item2;
|
---|
143 | }
|
---|
144 |
|
---|
145 | internal static TIn ArgMax<TIn, TOut>(Func<TIn, TOut> func, IEnumerable<TIn> inputs) where TOut : IComparable
|
---|
146 | {
|
---|
147 | return MaxArgMax(func, inputs).Item1;
|
---|
148 | }
|
---|
149 |
|
---|
150 | /// <summary>
|
---|
151 | /// Finds the value amongst <paramref name="inputs" /> such that the output value returned
|
---|
152 | /// by <paramref name="func" /> is as big as possible.
|
---|
153 | /// </summary>
|
---|
154 | /// <typeparam name="TIn">The input type for the function.</typeparam>
|
---|
155 | /// <typeparam name="TOut">The comparable output type of the function.</typeparam>
|
---|
156 | /// <param name="func">The function for which to find the biggest value.</param>
|
---|
157 | /// <param name="inputs">
|
---|
158 | /// The function arguments for which to find the one with the biggest output value when
|
---|
159 | /// given to <paramref name="func" />.
|
---|
160 | /// </param>
|
---|
161 | /// <returns></returns>
|
---|
162 | internal static Tuple<TIn, TOut> MaxArgMax<TIn, TOut>(Func<TIn, TOut> func, IEnumerable<TIn> inputs) where TOut : IComparable
|
---|
163 | {
|
---|
164 | if (inputs == null) throw new ArgumentNullException(nameof(inputs));
|
---|
165 | var it = inputs.GetEnumerator();
|
---|
166 | var hasItems = it.MoveNext();
|
---|
167 | if (!hasItems) throw new InvalidOperationException("No items given to find the maximum of");
|
---|
168 |
|
---|
169 | // find maximum argument and maximum value
|
---|
170 | var maxArg = it.Current;
|
---|
171 | var maxValue = func(it.Current);
|
---|
172 | while (it.MoveNext())
|
---|
173 | {
|
---|
174 | var currentArg = it.Current;
|
---|
175 | var currentValue = func(it.Current);
|
---|
176 | if (maxValue.CompareTo(currentValue) < 0)
|
---|
177 | {
|
---|
178 | maxArg = currentArg;
|
---|
179 | maxValue = currentValue;
|
---|
180 | }
|
---|
181 | }
|
---|
182 |
|
---|
183 | return Tuple.Create(maxArg, maxValue);
|
---|
184 | }
|
---|
185 | }
|
---|
186 | } |
---|