1 | using System;
|
---|
2 | using System.Collections.Generic;
|
---|
3 | using System.Linq;
|
---|
4 | using HeuristicLab.Data;
|
---|
5 |
|
---|
6 | namespace HeuristicLab.Algorithms.NSGA3
|
---|
7 | {
|
---|
8 | public static class Utility
|
---|
9 | {
|
---|
10 | public 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="InvalidOperationException">
|
---|
28 | /// Thrown, when <paramref name="r" /> > <paramref name="n" /> or when <paramref name="r"
|
---|
29 | /// /> < 1.
|
---|
30 | /// </exception>
|
---|
31 | public static int NCR(int n, int r)
|
---|
32 | {
|
---|
33 | if (n < r) throw new InvalidOperationException($"Constraint was not met: n >= r (n = {n}, r = {r})");
|
---|
34 | if (r < 1) throw new InvalidOperationException($"Constraint was not met: r >= 1 (r = {r})");
|
---|
35 | if (n == r) return 1;
|
---|
36 | return (int)(Factorial(n) / (Factorial(r) * Factorial(n - r)));
|
---|
37 | }
|
---|
38 |
|
---|
39 | public static long Factorial(int n)
|
---|
40 | {
|
---|
41 | if (n < 0 || n > 30) throw new InvalidOperationException($"Constraint for n was not met: 0 <= n <= 30 (n = {n})");
|
---|
42 | long product = 1;
|
---|
43 | for (int i = 2; i <= n; i++)
|
---|
44 | product *= i;
|
---|
45 |
|
---|
46 | return product;
|
---|
47 | }
|
---|
48 | public static double[][] ToJaggedArray(this DoubleMatrix m)
|
---|
49 | {
|
---|
50 | if (m == null) return null;
|
---|
51 | var i = m.Rows - 1;
|
---|
52 | var a = new double[i][];
|
---|
53 | for (i--; i >= 0; i--)
|
---|
54 | {
|
---|
55 | var j = m.Columns;
|
---|
56 | a[i] = new double[j];
|
---|
57 | for (j--; j >= 0; j--) a[i][j] = m[i, j];
|
---|
58 | }
|
---|
59 | return a;
|
---|
60 | }
|
---|
61 |
|
---|
62 | public static DoubleMatrix ConvertToDoubleMatrix(List<ReferencePoint> referencePoints)
|
---|
63 | {
|
---|
64 | return new DoubleMatrix(ToArray(referencePoints));
|
---|
65 | }
|
---|
66 |
|
---|
67 | public static double[][] ToFitnessMatrix(this List<Solution> solutions)
|
---|
68 | {
|
---|
69 | double[][] data = new double[solutions.Count][];
|
---|
70 | for (int i = 0; i < solutions.Count; i++)
|
---|
71 | {
|
---|
72 | Solution solution = solutions[i];
|
---|
73 | data[i] = new double[solution.Fitness.Length];
|
---|
74 | for (int j = 0; j < solution.Fitness.Length; j++)
|
---|
75 | {
|
---|
76 | data[i][j] = solution.Fitness[j];
|
---|
77 | }
|
---|
78 | }
|
---|
79 |
|
---|
80 | return data;
|
---|
81 | }
|
---|
82 |
|
---|
83 | public static DoubleMatrix ToMatrix(this IEnumerable<IReadOnlyList<double>> data)
|
---|
84 | {
|
---|
85 | var d2 = data.ToArray();
|
---|
86 | var mat = new DoubleMatrix(d2.Length, d2[0].Count);
|
---|
87 | for (var i = 0; i < mat.Rows; i++)
|
---|
88 | for (var j = 0; j < mat.Columns; j++)
|
---|
89 | mat[i, j] = d2[i][j];
|
---|
90 | return mat;
|
---|
91 | }
|
---|
92 |
|
---|
93 | private static double[,] ToArray(List<ReferencePoint> referencePoints)
|
---|
94 | {
|
---|
95 | if (referencePoints == null || !referencePoints.Any()) throw new ArgumentException($"{nameof(referencePoints)} is null or empty");
|
---|
96 | int nDim = referencePoints.First().NumberOfDimensions;
|
---|
97 | int pointCount = referencePoints.Count;
|
---|
98 | double[,] array = new double[nDim, pointCount];
|
---|
99 |
|
---|
100 | for (int p = 0; p < pointCount; p++)
|
---|
101 | for (int d = 0; d < nDim; d++)
|
---|
102 | array[d, p] = referencePoints[p].Values[d];
|
---|
103 |
|
---|
104 | return array;
|
---|
105 | }
|
---|
106 |
|
---|
107 | public static TOut Min<TIn, TOut>(Func<TIn, TOut> func, IEnumerable<TIn> inputs) where TOut : IComparable
|
---|
108 | {
|
---|
109 | return MinArgMin(func, inputs).Item2;
|
---|
110 | }
|
---|
111 |
|
---|
112 | public static TIn ArgMin<TIn, TOut>(Func<TIn, TOut> func, IEnumerable<TIn> inputs) where TOut : IComparable
|
---|
113 | {
|
---|
114 | return MinArgMin(func, inputs).Item1;
|
---|
115 | }
|
---|
116 |
|
---|
117 | /// <summary>
|
---|
118 | /// Finds the value amongst <paramref name="inputs" /> such that the output value returned
|
---|
119 | /// by <paramref name="func" /> is minimal.
|
---|
120 | /// </summary>
|
---|
121 | /// <typeparam name="TIn">The input type for the function.</typeparam>
|
---|
122 | /// <typeparam name="TOut">The comparable output type of the function.</typeparam>
|
---|
123 | /// <param name="func">The function for which to find the minimal value.</param>
|
---|
124 | /// <param name="inputs">
|
---|
125 | /// The function arguments for which to find the one with the minimum output value when
|
---|
126 | /// given to <paramref name="func" />.
|
---|
127 | /// </param>
|
---|
128 | /// <returns></returns>
|
---|
129 | public static Tuple<TIn, TOut> MinArgMin<TIn, TOut>(Func<TIn, TOut> func, IEnumerable<TIn> inputs) where TOut : IComparable
|
---|
130 | {
|
---|
131 | if (func == null) throw new ArgumentNullException(nameof(func));
|
---|
132 | if (inputs == null) throw new ArgumentNullException(nameof(inputs));
|
---|
133 | var it = inputs.GetEnumerator();
|
---|
134 | var hasItems = it.MoveNext();
|
---|
135 | if (!hasItems) throw new InvalidOperationException("No items given to find the minimum of");
|
---|
136 |
|
---|
137 | // find minimum argument and minimum value
|
---|
138 | var minArg = it.Current;
|
---|
139 | var minValue = func(it.Current);
|
---|
140 | while (it.MoveNext())
|
---|
141 | {
|
---|
142 | var currentArg = it.Current;
|
---|
143 | var currentValue = func(it.Current);
|
---|
144 | if (minValue.CompareTo(currentValue) > 0)
|
---|
145 | {
|
---|
146 | minArg = currentArg;
|
---|
147 | minValue = currentValue;
|
---|
148 | }
|
---|
149 | }
|
---|
150 |
|
---|
151 | return Tuple.Create(minArg, minValue);
|
---|
152 | }
|
---|
153 |
|
---|
154 | public static TOut Max<TIn, TOut>(Func<TIn, TOut> func, IEnumerable<TIn> inputs) where TOut : IComparable
|
---|
155 | {
|
---|
156 | return MaxArgMax(func, inputs).Item2;
|
---|
157 | }
|
---|
158 |
|
---|
159 | public static TIn ArgMax<TIn, TOut>(Func<TIn, TOut> func, IEnumerable<TIn> inputs) where TOut : IComparable
|
---|
160 | {
|
---|
161 | return MaxArgMax(func, inputs).Item1;
|
---|
162 | }
|
---|
163 |
|
---|
164 | /// <summary>
|
---|
165 | /// Finds the value amongst <paramref name="inputs" /> such that the output value returned
|
---|
166 | /// by <paramref name="func" /> is as big as possible.
|
---|
167 | /// </summary>
|
---|
168 | /// <typeparam name="TIn">The input type for the function.</typeparam>
|
---|
169 | /// <typeparam name="TOut">The comparable output type of the function.</typeparam>
|
---|
170 | /// <param name="func">The function for which to find the biggest value.</param>
|
---|
171 | /// <param name="inputs">
|
---|
172 | /// The function arguments for which to find the one with the biggest output value when
|
---|
173 | /// given to <paramref name="func" />.
|
---|
174 | /// </param>
|
---|
175 | /// <returns></returns>
|
---|
176 | public static Tuple<TIn, TOut> MaxArgMax<TIn, TOut>(Func<TIn, TOut> func, IEnumerable<TIn> inputs) where TOut : IComparable
|
---|
177 | {
|
---|
178 | if (func == null) throw new ArgumentNullException(nameof(func));
|
---|
179 | if (inputs == null) throw new ArgumentNullException(nameof(inputs));
|
---|
180 | var it = inputs.GetEnumerator();
|
---|
181 | var hasItems = it.MoveNext();
|
---|
182 | if (!hasItems) throw new InvalidOperationException("No items given to find the maximum of");
|
---|
183 |
|
---|
184 | // find maximum argument and maximum value
|
---|
185 | var maxArg = it.Current;
|
---|
186 | var maxValue = func(it.Current);
|
---|
187 | while (it.MoveNext())
|
---|
188 | {
|
---|
189 | var currentArg = it.Current;
|
---|
190 | var currentValue = func(it.Current);
|
---|
191 | if (maxValue.CompareTo(currentValue) < 0)
|
---|
192 | {
|
---|
193 | maxArg = currentArg;
|
---|
194 | maxValue = currentValue;
|
---|
195 | }
|
---|
196 | }
|
---|
197 |
|
---|
198 | return Tuple.Create(maxArg, maxValue);
|
---|
199 | }
|
---|
200 | }
|
---|
201 | } |
---|