1 | using System;
|
---|
2 | using System.Collections.Generic;
|
---|
3 | using System.Linq;
|
---|
4 | using System.Text;
|
---|
5 | using System.Threading.Tasks;
|
---|
6 | using HeuristicLab.Encodings.RealVectorEncoding;
|
---|
7 |
|
---|
8 | namespace HeuristicLab.Problems.MultiObjectiveTestFunctions.Testfunctions {
|
---|
9 | class Evaluators {
|
---|
10 |
|
---|
11 | //http://www.tik.ee.ethz.ch/sop/download/supplementary/testproblems/ [30.11.2015]
|
---|
12 | private double[] ZDT1(RealVector r) { //0,1
|
---|
13 | double g = 0;
|
---|
14 | for (int i = 1; i < r.Length; i++) g += r[i];
|
---|
15 | g = 1.0 + 9.0 * g / (r.Length - 1);
|
---|
16 | double[] res = { r[0], g * (1.0 - Math.Sqrt(r[0] / g)) };
|
---|
17 | return res;
|
---|
18 | }
|
---|
19 | private double[] ZDT2(RealVector r) { //0,1
|
---|
20 | double g = 0;
|
---|
21 | for (int i = 1; i < r.Length; i++) g += r[i];
|
---|
22 | g = 1.0 + 9.0 * g / (r.Length - 1);
|
---|
23 | double d = r[0] / g;
|
---|
24 | double[] res = { r[0], g * (1.0 - d * d) };
|
---|
25 | return res;
|
---|
26 | }
|
---|
27 | private double[] ZDT3(RealVector r) { //0,1
|
---|
28 | double g = 0;
|
---|
29 | for (int i = 1; i < r.Length; i++) g += r[i];
|
---|
30 | g = 1.0 + 9.0 * g / (r.Length - 1);
|
---|
31 | double d = r[0] / g;
|
---|
32 | double[] res = { r[0], g * (1.0 - Math.Sqrt(d) - d * Math.Sin(10 * Math.PI * r[0])) };
|
---|
33 | return res;
|
---|
34 | }
|
---|
35 | private double[] ZDT4(RealVector r) { //-5,5
|
---|
36 | double g = 0;
|
---|
37 | for (int i = 1; i < r.Length; i++) {
|
---|
38 | double v = r[i];
|
---|
39 | g += v * v - 10 * Math.Cos(4 * Math.PI * v);
|
---|
40 | }
|
---|
41 | g = 1.0 + 10.0 * (r.Length - 1) + g;
|
---|
42 | double d = r[0] / g;
|
---|
43 | double[] res = { r[0], g * (1.0 - d * d) };
|
---|
44 | return res;
|
---|
45 | }
|
---|
46 | private double[] ZDT6(RealVector r) { //0,1
|
---|
47 | double g = 0;
|
---|
48 | for (int i = 1; i < r.Length; i++) g += r[i];
|
---|
49 | g = g = 1.0 + 9.0 * Math.Pow(g / (r.Length - 1), 0.25);
|
---|
50 | double d = r[0] / g;
|
---|
51 | double[] res = { 1 - Math.Exp(-4 * r[0]) * Math.Pow(Math.Sin(6 * Math.PI * r[0]), 6), g * (1.0 - d * d) };
|
---|
52 | return res;
|
---|
53 | }
|
---|
54 |
|
---|
55 |
|
---|
56 | //IMPOTANT There is often confusion about the numbering and the function definitions
|
---|
57 | //eg.: in EALib only the first 4 functions are the same although the other 3 share resemblances
|
---|
58 | //even on http://www.tik.ee.ethz.ch/ where the original paper is referenced DTLZ7 on the page is DTLZ6 in the paper
|
---|
59 | /*Deb, K., Thiele, L., Laumanns, M., & Zitzler, E. (2002, May).
|
---|
60 | Scalable multi-objective optimization test problems.
|
---|
61 | In Proceedings of the Congress on Evolutionary Computation (CEC-2002),(Honolulu, USA) (pp. 825-830).
|
---|
62 | http://repository.ias.ac.in/81671/ [30.11.15]
|
---|
63 | */
|
---|
64 | private double[] DTLZ1(RealVector r, int objectives) { //0,1
|
---|
65 | double[] res = new double[objectives];
|
---|
66 |
|
---|
67 | //calculate g(Xm)
|
---|
68 | double sum = 0, length = 0;
|
---|
69 | for (int i = objectives; i < r.Length; i++) {
|
---|
70 | double d = r[i] - 0.5;
|
---|
71 | sum += d * d - Math.Cos(20 * Math.PI * d);
|
---|
72 | length += r[i] * r[i];
|
---|
73 | }
|
---|
74 | length = Math.Sqrt(length);
|
---|
75 | double g = 100 * (length + sum);
|
---|
76 |
|
---|
77 | //calculating f0...fM-1
|
---|
78 | for (int i = 0; i < objectives; i++) {
|
---|
79 | double f = 0.5 * i == 0 ? 1 : (1 - r[objectives - i - 1]) * (1 + g);
|
---|
80 | for (int j = 0; j < objectives - i - 1; j++) {
|
---|
81 | f *= r[j];
|
---|
82 | }
|
---|
83 | res[i] = f;
|
---|
84 | }
|
---|
85 | return res;
|
---|
86 | }
|
---|
87 | private double[] DTLZ2(RealVector r, int objectives) { //0,1
|
---|
88 | double[] res = new double[objectives];
|
---|
89 |
|
---|
90 | //calculate g(Xm)
|
---|
91 | double g = 0;
|
---|
92 | for (int i = objectives; i < r.Length; i++) {
|
---|
93 | double d = r[i] - 0.5;
|
---|
94 | g += d * d;
|
---|
95 | }
|
---|
96 |
|
---|
97 | //calculating f0...fM-1
|
---|
98 | for (int i = 0; i < objectives; i++) {
|
---|
99 | double f = i == 0 ? 1 : (Math.Sin(r[objectives - i - 1] * Math.PI / 2)) * (1 + g);
|
---|
100 | for (int j = 0; j < objectives - i - 1; j++) {
|
---|
101 | f *= Math.Cos(r[j] * Math.PI / 2);
|
---|
102 | }
|
---|
103 | res[i] = f;
|
---|
104 | }
|
---|
105 | return res;
|
---|
106 | }
|
---|
107 | private double[] DTLZ3(RealVector r, int objectives) { //0,1
|
---|
108 | double[] res = new double[objectives];
|
---|
109 |
|
---|
110 | //calculate g(Xm)
|
---|
111 | double sum = 0, length = 0;
|
---|
112 | for (int i = objectives; i < r.Length; i++) {
|
---|
113 | double d = r[i] - 0.5;
|
---|
114 | sum += d * d - Math.Cos(20 * Math.PI * d);
|
---|
115 | length += r[i] * r[i];
|
---|
116 | }
|
---|
117 | length = Math.Sqrt(length);
|
---|
118 | double g = 100 * (length + sum);
|
---|
119 |
|
---|
120 | //calculating f0...fM-1
|
---|
121 | for (int i = 0; i < objectives; i++) {
|
---|
122 | double f = i == 0 ? 1 : (Math.Sin(r[objectives - i - 1] * Math.PI / 2)) * (1 + g);
|
---|
123 | for (int j = 0; j < objectives - i - 1; j++) {
|
---|
124 | f *= Math.Cos(r[j] * Math.PI / 2);
|
---|
125 | }
|
---|
126 | res[i] = f;
|
---|
127 | }
|
---|
128 | return res;
|
---|
129 | }
|
---|
130 | private double[] DTLZ4(RealVector r, int objectives) { //0,1
|
---|
131 | double[] res = new double[objectives];
|
---|
132 |
|
---|
133 | //calculate g(Xm)
|
---|
134 | double g = 0;
|
---|
135 | for (int i = objectives; i < r.Length; i++) {
|
---|
136 | double d = r[i] - 0.5;
|
---|
137 | g += d * d;
|
---|
138 | }
|
---|
139 |
|
---|
140 | //calculating f0...fM-1
|
---|
141 | for (int i = 0; i < objectives; i++) {
|
---|
142 | double f = i == 0 ? 1 : (Math.Sin(Math.Pow(r[objectives - i - 1], 100) * Math.PI / 2)) * (1 + g);
|
---|
143 | for (int j = 0; j < objectives - i - 1; j++) {
|
---|
144 | f *= Math.Cos(Math.Pow(r[j], 100) * Math.PI / 2);
|
---|
145 | }
|
---|
146 | res[i] = f;
|
---|
147 | }
|
---|
148 | return res;
|
---|
149 | }
|
---|
150 | private double[] DTLZ5(RealVector r, int objectives) { //0,1
|
---|
151 | double[] res = new double[objectives];
|
---|
152 |
|
---|
153 | //calculate g(Xm)
|
---|
154 | double g = 0;
|
---|
155 | for (int i = objectives; i < r.Length; i++) {
|
---|
156 | g += Math.Pow(r[i], 0.1);
|
---|
157 | }
|
---|
158 |
|
---|
159 | //phi definition
|
---|
160 | Func<double, double> phi;
|
---|
161 | phi = (double x) => { return Math.PI / (4 * 1 + g) * (1 + 2 * g * x); };
|
---|
162 |
|
---|
163 | //calculating f0...fM-1
|
---|
164 | for (int i = 0; i < objectives; i++) {
|
---|
165 | double f = i == 0 ? 1 : (Math.Sin(phi(r[objectives - i - 1]) * Math.PI / 2)) * (1 + g);
|
---|
166 | for (int j = 0; j < objectives - i - 1; j++) {
|
---|
167 | f *= Math.Cos(phi(r[j]) * Math.PI / 2);
|
---|
168 | }
|
---|
169 | res[i] = f;
|
---|
170 | }
|
---|
171 | return res;
|
---|
172 | }
|
---|
173 | private double[] DTLZ6(RealVector r, int objectives) { //0,1
|
---|
174 | double[] res = new double[objectives];
|
---|
175 |
|
---|
176 | //calculate g(Xm)
|
---|
177 | double g = 0, length = 0;
|
---|
178 | for (int i = objectives; i < r.Length; i++) {
|
---|
179 | g += r[i];
|
---|
180 | length += r[i] * r[i];
|
---|
181 | }
|
---|
182 | length = Math.Sqrt(length);
|
---|
183 | g = 1.0 + 9.0 / length * g;
|
---|
184 |
|
---|
185 | //calculating f0...fM-2
|
---|
186 | for (int i = 0; i < objectives - 1; i++) {
|
---|
187 | res[i] = r[i];
|
---|
188 | }
|
---|
189 | //calculate fM-1
|
---|
190 | double h = objectives;
|
---|
191 | for (int i = 0; i < objectives - 1; i++) {
|
---|
192 | h -= res[i] / (1 + g) * (1 + Math.Sin(3 * Math.PI * res[i]));
|
---|
193 | }
|
---|
194 | res[objectives - 1] = (1 + g) * h;
|
---|
195 |
|
---|
196 | return res;
|
---|
197 | }
|
---|
198 | private double[] DTLZ7(RealVector r, int objectives) { //0,1
|
---|
199 | double[] res = new double[objectives];
|
---|
200 |
|
---|
201 | //calculate f0...fM-1;
|
---|
202 | double n = 10 * objectives;
|
---|
203 | for (int i = 0; i < objectives; i++) {
|
---|
204 | double d = 0;
|
---|
205 | for (int j = (int)Math.Floor((i - 1) * n / objectives); j < (int)Math.Floor(i * n / objectives); j++) {
|
---|
206 | d += r[j];
|
---|
207 | }
|
---|
208 | d *= 1 / Math.Floor(n / objectives);
|
---|
209 | res[i] = d;
|
---|
210 | }
|
---|
211 |
|
---|
212 | //evaluate constraints g0...gM-2
|
---|
213 | for (int i = 0; i < objectives - 1; i++) {
|
---|
214 | if (res[objectives - 1] + 4 * res[i] - 1 < 0) return null; //TODO null is not the way to go
|
---|
215 | }
|
---|
216 | //evaluate gM-1
|
---|
217 | double min = Double.PositiveInfinity;
|
---|
218 | for (int i = 0; i < objectives - 1; i++) {
|
---|
219 | for (int j = 0; j < i; j++) min = Math.Min(min, res[i] + res[j]);
|
---|
220 | };
|
---|
221 | if (2 * res[objectives - 1] + min - 1 < 0) return null; //TODO null is not the way to go
|
---|
222 |
|
---|
223 | return res;
|
---|
224 | }
|
---|
225 |
|
---|
226 | //original paper not accessible + wikipedia definition works only with fixed (3) dimensions
|
---|
227 | //http://darwin.di.uminho.pt/jecoli/index.php/Multiobjective_example [30.11.2015]
|
---|
228 | private double[] Kursawe(RealVector r) { //no Bounds??
|
---|
229 | //objective 1
|
---|
230 | double f0 = 0.0;
|
---|
231 | for (int i = 0; i < r.Length - 1; i++) {
|
---|
232 | f0 += -10 * Math.Exp(-0.2 * Math.Sqrt(r[i] * r[i] + r[i + 1] * r[i + 1]));
|
---|
233 | }
|
---|
234 | //objective2
|
---|
235 | double f1 = 0.0;
|
---|
236 | for (int i = 0; i < r.Length; i++) {
|
---|
237 | f1 += Math.Pow(Math.Abs(r[i]), 0.2) + 5 * Math.Sin(Math.Pow(r[i], 3));
|
---|
238 | }
|
---|
239 |
|
---|
240 | double[] res = { f0, f1 };
|
---|
241 | return res;
|
---|
242 | }
|
---|
243 |
|
---|
244 | //http://www.eng.buffalo.edu/Research/MODEL/mdo.test.orig/class2prob4/descr.html
|
---|
245 | //TODO this is not multi-objective
|
---|
246 | private double[] Golinski(RealVector r) { //bounds {{2.6,3.6}, {0.7,0.8}, {17,28}, {7.3, 8.3}, {7.3,8.3}, {2.9,3.9}, {5.0,5.5}}
|
---|
247 | if (r.Length != 7) return null;
|
---|
248 |
|
---|
249 | double[] Cf = { 0.7854, 3.3333, 14.9334, 43.0934, 1.5079, 7.477 };
|
---|
250 | double f = Cf[0] * r[0] * r[1] * r[1];
|
---|
251 | f*= Cf[1] * r[2] * r[2] + Cf[2] * r[2] - Cf[3];
|
---|
252 | f -= Cf[4] * (r[5] * r[5] + r[6] * r[6]);
|
---|
253 | f += Cf[5] * (r[5] * r[5] * r[5] + r[6] * r[6] * r[6]);
|
---|
254 | f += Cf[0] * (r[3] * r[5] * r[5] + r[4] * r[6] * r[6]);
|
---|
255 |
|
---|
256 | double Ca12s = 745.0*745.0;
|
---|
257 | //Constraints x[0],x[1],x[2],x[5],x[6]
|
---|
258 | List<GoldinskiConstraint> constraints = new List<GoldinskiConstraint>();
|
---|
259 | constraints.Add(new GoldinskiConstraint(x => 27.0/(x[0]*x[1]*x[1]*x[2])));
|
---|
260 | constraints.Add(new GoldinskiConstraint(x => 397.5 / (x[0] * x[1] * x[1] * x[2]*x[2])));
|
---|
261 | constraints.Add(new GoldinskiConstraint(x => 1.93*Math.Pow(x[3],3) / (x[1] * x[2] * Math.Pow(x[5],4))));
|
---|
262 | constraints.Add(new GoldinskiConstraint(x => 1.93 * Math.Pow(x[4], 3) / (x[1] * x[2] * Math.Pow(x[6], 4))));
|
---|
263 | constraints.Add(new GoldinskiConstraint(x => Math.Sqrt(Ca12s*x[3]*x[3]/(x[1]*x[1]*x[2]*x[2])+0.169e8)/(1100*0.1*Math.Pow(x[5],3))));
|
---|
264 | constraints.Add(new GoldinskiConstraint(x => Math.Sqrt(Ca12s * x[4] * x[4] / (x[1] * x[1] * x[2] * x[2]) + 0.169e8) / (859 * 0.1 * Math.Pow(x[6], 3))));
|
---|
265 | constraints.Add(new GoldinskiConstraint(x => x[1]*x[2]/40.0));
|
---|
266 | constraints.Add(new GoldinskiConstraint(x => 5.0 * x[1] / x[0]));
|
---|
267 | constraints.Add(new GoldinskiConstraint(x => x[0] / 12 * x[1]));
|
---|
268 | constraints.Add(new GoldinskiConstraint(x => 2.6/x[0])); //g10
|
---|
269 | constraints.Add(new GoldinskiConstraint(x => x[0]/3.6));
|
---|
270 | constraints.Add(new GoldinskiConstraint(x => 0.7 / x[1]));
|
---|
271 | constraints.Add(new GoldinskiConstraint(x => x[1] / 0.8));
|
---|
272 | return null;
|
---|
273 | }
|
---|
274 | private class GoldinskiConstraint {
|
---|
275 | private Func<RealVector, double> phi;
|
---|
276 | public GoldinskiConstraint(Func<RealVector, double> phi) {
|
---|
277 | this.phi = phi;
|
---|
278 | }
|
---|
279 | public bool eval(RealVector r) {
|
---|
280 | return phi(r) <= 1.0;
|
---|
281 | }
|
---|
282 | }
|
---|
283 |
|
---|
284 |
|
---|
285 | // https://en.wikipedia.org/wiki/Test_functions_for_optimization [30.11.2015]
|
---|
286 | private double[] Fonseca(RealVector r) { //-4,4
|
---|
287 | double f0 = 0.0, aux = 1.0 / Math.Sqrt(r.Length);
|
---|
288 |
|
---|
289 | //objective1
|
---|
290 | for (int i = 0; i < r.Length; i++) {
|
---|
291 | double d = r[i] - aux;
|
---|
292 | f0 += d * d;
|
---|
293 | }
|
---|
294 | f0 = 1 - Math.Exp(-f0);
|
---|
295 |
|
---|
296 | //objective2
|
---|
297 | double f1 = 0.0;
|
---|
298 | for (int i = 0; i < r.Length; i++) {
|
---|
299 | double d = r[i] + aux;
|
---|
300 | f1 += d * d;
|
---|
301 | }
|
---|
302 | f1 = 1 - Math.Exp(-f1);
|
---|
303 |
|
---|
304 | double[] res = { f0, f1 };
|
---|
305 | return res;
|
---|
306 | }
|
---|
307 | private double[] Schaffer1(RealVector r) { //-5,10??
|
---|
308 | if (r.Length != 1) return null;
|
---|
309 | double x = r[0];
|
---|
310 |
|
---|
311 | //objective1
|
---|
312 | double f0=x*x;
|
---|
313 |
|
---|
314 | //objective0
|
---|
315 | double f1 = x - 2;
|
---|
316 | f1 *= f1;
|
---|
317 |
|
---|
318 | double[] res = { f0, f1 };
|
---|
319 | return res;
|
---|
320 | }
|
---|
321 | private double[] Schaffer2(RealVector r) { //-5,10
|
---|
322 | if (r.Length != 1) return null;
|
---|
323 | double x = r[0];
|
---|
324 |
|
---|
325 | //objective1
|
---|
326 | double f0;
|
---|
327 | if (x <= 11) f0 = -x;
|
---|
328 | else if (x <= 3) f0 = x - 2;
|
---|
329 | else if (x <= 4) f0 = 4 - x;
|
---|
330 | else f0 = x - 4;
|
---|
331 |
|
---|
332 | //objective0
|
---|
333 | double f1 = x - 5;
|
---|
334 | f1 *= f1;
|
---|
335 |
|
---|
336 | double[] res = { f0, f1 };
|
---|
337 | return res;
|
---|
338 | }
|
---|
339 |
|
---|
340 | }
|
---|
341 | }
|
---|