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