problems.bend
unified-nsga-iii@0.2.2.0 · 654 lines · 98 definitions
1
2
3
4
5
6
7
8
9import Base
10import unified-nsga-iii@0.2.2.0/individual.bend as Ind
11import unified-nsga-iii@0.2.2.0/bounds.bend as Bounds
12import unified-nsga-iii@0.2.2.0/util.bend as Util
13
14type Family is Data:
15 Zdt1{}
16 Zdt2{}
17 Zdt3{}
18 Zdt4{}
19 Zdt6{}
20 Dtlz1{}
21 Dtlz2{}
22 Dtlz3{}
23 Dtlz4{}
24 Dtlz7{}
25 Sphere{}
26 Ackley{}
27 Rosenbrock{}
28 Osy{}
29 Tnk{}
30 C1Dtlz1{}
31
32type Problem is Data:
33 MkProblem{
34 kind: Family
35 box: Bounds.Box
36 alpha: F32
37 }
38
39def box_of(p: Problem) -> Bounds.Box:
40 match p:
41 case MkProblem{kind, box, alpha}:
42 box
43
44def kind_of(p: Problem) -> Family:
45 match p:
46 case MkProblem{kind, box, alpha}:
47 kind
48
49def alpha_of(p: Problem) -> F32:
50 match p:
51 case MkProblem{kind, box, alpha}:
52 alpha
53
54def n_obj(p: Problem) -> Nat:
55 Bounds.n_obj(box_of(p))
56
57def n_var(p: Problem) -> Nat:
58 Bounds.n_var(box_of(p))
59
60def mk_prob(kind: Family, box: Bounds.Box) -> Problem:
61 MkProblem{kind, box, 0.0}
62
63
64def zdt1(n: Nat) -> Problem:
65 mk_prob(Zdt1{}, Bounds.unit_n(n, 2n))
66
67def zdt2(n: Nat) -> Problem:
68 mk_prob(Zdt2{}, Bounds.unit_n(n, 2n))
69
70def zdt3(n: Nat) -> Problem:
71 mk_prob(Zdt3{}, Bounds.unit_n(n, 2n))
72
73
74def zdt4_ivs(n: Nat) -> List<&2, Bounds.Interval>:
75 match n:
76 case 0n:
77 Nil{}
78 case 1n+p:
79 Bounds.interval(0.0, 1.0) <> List.replicate(Bounds.Interval, p, Bounds.interval(F32.neg(5.0), 5.0))
80
81def zdt4(n: Nat) -> Problem:
82 mk_prob(Zdt4{}, Bounds.box(2n, zdt4_ivs(n)))
83
84
85def zdt6(n: Nat) -> Problem:
86 mk_prob(Zdt6{}, Bounds.unit_n(n, 2n))
87
88
89def dtlz_n(m: Nat, k: Nat) -> Nat:
90 match m:
91 case 0n:
92 k
93 case 1n+pm:
94 match k:
95 case 0n:
96 pm
97 case 1n+pk:
98 Nat.add(pm, 1n+pk)
99
100
101def dtlz2(+m: Nat, k: Nat) -> Problem:
102 mk_prob(Dtlz2{}, Bounds.unit_n(dtlz_n(m, k), m))
103
104
105def dtlz1(+m: Nat, k: Nat) -> Problem:
106 mk_prob(Dtlz1{}, Bounds.unit_n(dtlz_n(m, k), m))
107
108
109def dtlz3(+m: Nat, k: Nat) -> Problem:
110 mk_prob(Dtlz3{}, Bounds.unit_n(dtlz_n(m, k), m))
111
112
113def dtlz4_alpha(+m: Nat, k: Nat, +alpha: F32) -> Problem:
114 MkProblem{Dtlz4{}, Bounds.unit_n(dtlz_n(m, k), m), alpha}
115
116def dtlz4(+m: Nat, k: Nat) -> Problem:
117 dtlz4_alpha(m, k, 100.0)
118
119
120def dtlz7(+m: Nat, k: Nat) -> Problem:
121 mk_prob(Dtlz7{}, Bounds.unit_n(dtlz_n(m, k), m))
122
123
124def sphere(n: Nat) -> Problem:
125 mk_prob(Sphere{}, Bounds.span_n(n, 1n, F32.neg(5.12), 5.12))
126
127def ackley(n: Nat) -> Problem:
128 mk_prob(Ackley{}, Bounds.span_n(n, 1n, F32.neg(32.768), 32.768))
129
130def rosenbrock(n: Nat) -> Problem:
131 mk_prob(Rosenbrock{}, Bounds.span_n(n, 1n, F32.neg(2.048), 2.048))
132
133
134def osy() -> Problem:
135 mk_prob(
136 Osy{},
137 Bounds.box(
138 2n,
139 Bounds.interval(0.0, 10.0)
140 <> Bounds.interval(0.0, 10.0)
141 <> Bounds.interval(1.0, 5.0)
142 <> Bounds.interval(0.0, 6.0)
143 <> Bounds.interval(1.0, 5.0)
144 <> [Bounds.interval(0.0, 10.0)]
145 )
146 )
147
148
149def tnk() -> Problem:
150 mk_prob(
151 Tnk{},
152 Bounds.box(2n, Bounds.interval(0.0, F32.pi()) <> [Bounds.interval(1.0e-30, F32.pi())])
153 )
154
155
156def c1_dtlz1(+m: Nat, k: Nat) -> Problem:
157 mk_prob(C1Dtlz1{}, Bounds.unit_n(dtlz_n(m, k), m))
158
159def sum_from(xs: List<&2, F32>) -> F32:
160 match xs:
161 case Nil{}:
162 0.0
163 case h <> t:
164 F32.add(h, sum_from(t))
165
166def sum_tail(xs: List<&2, F32>) -> F32:
167 match xs:
168 case Nil{}:
169 0.0
170 case h <> t:
171 sum_from(t)
172
173def list_tail(xs: List<&2, F32>) -> List<&2, F32>:
174 match xs:
175 case Nil{}:
176 Nil{}
177 case h <> t:
178 t
179
180def zdt_den(n: Nat) -> F32:
181 match n:
182 case 0n:
183 1.0
184 case 1n:
185 1.0
186 case 1n+p:
187 F32.from_nat(p)
188
189
190def zdt_g(+x: List<&2, F32>) -> F32:
191 +n = Util.list_len(F32, x)
192 F32.add(1.0, F32.div(F32.mul(9.0, sum_tail(x)), zdt_den(n)))
193
194def zdt1_f(+x: List<&2, F32>) -> List<&2, F32>:
195 +x0 = Util.get_f32(x, 0n)
196 +g = zdt_g(x)
197 x0 <> [F32.mul(g, F32.sub(1.0, F32.sqrt(F32.div(x0, g))))]
198
199def zdt2_f(+x: List<&2, F32>) -> List<&2, F32>:
200 +x0 = Util.get_f32(x, 0n)
201 +g = zdt_g(x)
202 +r = F32.div(x0, g)
203 x0 <> [F32.mul(g, F32.sub(1.0, F32.mul(r, r)))]
204
205
206def zdt3_f(+x: List<&2, F32>) -> List<&2, F32>:
207 +x0 = Util.get_f32(x, 0n)
208 +g = zdt_g(x)
209 +r = F32.div(x0, g)
210 +s = F32.sin(F32.mul(F32.mul(10.0, F32.pi()), x0))
211 x0 <> [F32.mul(g, F32.sub(F32.sub(1.0, F32.sqrt(r)), F32.mul(r, s)))]
212
213def zdt4_term(+xi: F32) -> F32:
214 F32.sub(F32.square(xi), F32.mul(10.0, F32.cos(F32.mul(F32.mul(4.0, F32.pi()), xi))))
215
216def sum_zdt4(xs: List<&2, F32>) -> F32:
217 match xs:
218 case Nil{}:
219 0.0
220 case h <> t:
221 F32.add(zdt4_term(h), sum_zdt4(t))
222
223def pred(n: Nat) -> Nat:
224 match n:
225 case 0n:
226 0n
227 case 1n+p:
228 p
229
230
231def zdt4_g(+x: List<&2, F32>) -> F32:
232 +n = Util.list_len(F32, x)
233 F32.add(F32.add(1.0, F32.mul(10.0, F32.from_nat(pred(n)))), sum_zdt4(list_tail(x)))
234
235def zdt4_f(+x: List<&2, F32>) -> List<&2, F32>:
236 +x0 = Util.get_f32(x, 0n)
237 +g = zdt4_g(x)
238 x0 <> [F32.mul(g, F32.sub(1.0, F32.sqrt(F32.div(x0, g))))]
239
240
241def zdt6_f(+x: List<&2, F32>) -> List<&2, F32>:
242 +x0 = Util.get_f32(x, 0n)
243 +wave = F32.pow(F32.sin(F32.mul(F32.mul(6.0, F32.pi()), x0)), 6.0)
244 +f0 = F32.sub(1.0, F32.mul(F32.exp(F32.mul(F32.neg(4.0), x0)), wave))
245 +n = Util.list_len(F32, x)
246 +g = F32.add(1.0, F32.mul(9.0, F32.pow(F32.div(sum_tail(x), zdt_den(n)), 0.25)))
247 +r = F32.div(f0, g)
248 f0 <> [F32.mul(g, F32.sub(1.0, F32.mul(r, r)))]
249
250def sum_sq_half(xs: List<&2, F32>) -> F32:
251 match xs:
252 case Nil{}:
253 0.0
254 case h <> t:
255 F32.add(F32.square(F32.sub(h, 0.5)), sum_sq_half(t))
256
257def tail_from_m(+x: List<&2, F32>, m: Nat) -> List<&2, F32>:
258 List.drop(&2, F32, x, pred(m))
259
260
261def dtlz2_g(+x: List<&2, F32>, m: Nat) -> F32:
262 sum_sq_half(tail_from_m(x, m))
263
264def dtlz1_term(+xi: F32) -> F32:
265 +d = F32.sub(xi, 0.5)
266 F32.sub(F32.square(d), F32.cos(F32.mul(F32.mul(20.0, F32.pi()), d)))
267
268def sum_dtlz1(xs: List<&2, F32>) -> F32:
269 match xs:
270 case Nil{}:
271 0.0
272 case h <> t:
273 F32.add(dtlz1_term(h), sum_dtlz1(t))
274
275
276
277def dtlz1_g(+x: List<&2, F32>, m: Nat) -> F32:
278 +tail = tail_from_m(x, m)
279 F32.mul(100.0, F32.add(F32.from_nat(Util.list_len(F32, tail)), sum_dtlz1(tail)))
280
281def half_pi() -> F32:
282 F32.div(F32.pi(), 2.0)
283
284def prod_cos.go(+x: List<&2, F32>, fuel: Nat, +i: Nat, acc: F32) -> F32:
285 match fuel:
286 case 0n:
287 acc
288 case 1n+f:
289 prod_cos.go(
290 x,
291 f,
292 1n+i,
293 F32.mul(acc, F32.cos(F32.mul(Util.get_f32(x, i), half_pi())))
294 )
295
296def prod_cos(+x: List<&2, F32>, n: Nat) -> F32:
297 prod_cos.go(x, n, 0n, 1.0)
298
299def dtlz2_sin(+x: List<&2, F32>, +m: Nat, +i: Nat) -> F32:
300 F32.sin(F32.mul(Util.get_f32(x, pred(Nat.sub(m, i))), half_pi()))
301
302def dtlz2_fi.tail(+x: List<&2, F32>, +m: Nat, +g: F32, +i: Nat, +body: F32, first: Bool) -> F32:
303 match first:
304 case True{}:
305 body
306 case False{}:
307 F32.mul(body, dtlz2_sin(x, m, i))
308
309
310def dtlz2_fi(+x: List<&2, F32>, +m: Nat, +g: F32, +i: Nat) -> F32:
311 dtlz2_fi.tail(
312 x,
313 m,
314 g,
315 i,
316 F32.mul(F32.add(1.0, g), prod_cos(x, pred(Nat.sub(m, i)))),
317 Nat.is_eq(i, 0n)
318 )
319
320def dtlz2_fs.go(+x: List<&2, F32>, +m: Nat, +g: F32, fuel: Nat, +i: Nat) -> List<&2, F32>:
321 match fuel:
322 case 0n:
323 Nil{}
324 case 1n+f:
325 dtlz2_fi(x, m, g, i) <> dtlz2_fs.go(x, m, g, f, 1n+i)
326
327def dtlz2_f(+x: List<&2, F32>, +m: Nat) -> List<&2, F32>:
328 dtlz2_fs.go(x, m, dtlz2_g(x, m), m, 0n)
329
330def prod_xs.go(+x: List<&2, F32>, fuel: Nat, +i: Nat, acc: F32) -> F32:
331 match fuel:
332 case 0n:
333 acc
334 case 1n+f:
335 prod_xs.go(x, f, 1n+i, F32.mul(acc, Util.get_f32(x, i)))
336
337def prod_xs(+x: List<&2, F32>, n: Nat) -> F32:
338 prod_xs.go(x, n, 0n, 1.0)
339
340def dtlz1_scale(+body: F32, +x: List<&2, F32>, +idx: Nat, first: Bool) -> F32:
341 match first:
342 case True{}:
343 body
344 case False{}:
345 F32.mul(body, F32.sub(1.0, Util.get_f32(x, idx)))
346
347
348def dtlz1_fi(+x: List<&2, F32>, +m: Nat, +g: F32, +i: Nat) -> F32:
349 +idx = pred(Nat.sub(m, i))
350 dtlz1_scale(F32.mul(F32.mul(0.5, F32.add(1.0, g)), prod_xs(x, idx)), x, idx, Nat.is_eq(i, 0n))
351
352def dtlz1_fs.go(+x: List<&2, F32>, +m: Nat, +g: F32, fuel: Nat, +i: Nat) -> List<&2, F32>:
353 match fuel:
354 case 0n:
355 Nil{}
356 case 1n+f:
357 dtlz1_fi(x, m, g, i) <> dtlz1_fs.go(x, m, g, f, 1n+i)
358
359def dtlz1_f(+x: List<&2, F32>, +m: Nat) -> List<&2, F32>:
360 dtlz1_fs.go(x, m, dtlz1_g(x, m), m, 0n)
361
362
363
364
365
366
367
368
369def nn_obj(+v: F32) -> F32:
370 Bool.pick(F32, F32.is_lt(v, 0.0), 0.0, v)
371
372def nn_objs(xs: List<&2, F32>) -> List<&2, F32>:
373 match xs:
374 case Nil{}:
375 Nil{}
376 case h <> t:
377 nn_obj(h) <> nn_objs(t)
378
379
380def dtlz3_f(+x: List<&2, F32>, +m: Nat) -> List<&2, F32>:
381 nn_objs(dtlz2_fs.go(x, m, dtlz1_g(x, m), m, 0n))
382
383
384def map_prefix_pow.go(fuel: Nat, xs: List<&2, F32>, +alpha: F32) -> List<&2, F32>:
385 match fuel:
386 case 0n:
387 xs
388 case 1n+f:
389 match xs:
390 case Nil{}:
391 Nil{}
392 case h <> t:
393 F32.pow(h, alpha) <> map_prefix_pow.go(f, t, alpha)
394
395
396def map_prefix_pow(+xs: List<&2, F32>, fuel: Nat, +alpha: F32) -> List<&2, F32>:
397 map_prefix_pow.go(fuel, xs, alpha)
398
399
400def dtlz4_f(+x: List<&2, F32>, +m: Nat, +alpha: F32) -> List<&2, F32>:
401 dtlz2_f(map_prefix_pow(x, pred(m), alpha), m)
402
403def pos_or.fin(+x: F32, +fallback: F32, ok: Bool) -> F32:
404 match ok:
405 case True{}:
406 x
407 case False{}:
408 fallback
409
410def pos_or(+x: F32, +fallback: F32) -> F32:
411 pos_or.fin(x, fallback, F32.is_gt(x, 0.0))
412
413
414def dtlz7_g(+x: List<&2, F32>, m: Nat) -> F32:
415 +tail = tail_from_m(x, m)
416 +den = pos_or(F32.from_nat(Util.list_len(F32, tail)), 1.0)
417 F32.add(1.0, F32.div(F32.mul(9.0, sum_from(tail)), den))
418
419def dtlz7_h.go(+x: List<&2, F32>, +g1: F32, fuel: Nat, +i: Nat, acc: F32) -> F32:
420 match fuel:
421 case 0n:
422 acc
423 case 1n+f:
424 +fi = Util.get_f32(x, i)
425 +term = F32.mul(F32.div(fi, g1), F32.add(1.0, F32.sin(F32.mul(F32.mul(3.0, F32.pi()), fi))))
426 dtlz7_h.go(x, g1, f, 1n+i, F32.add(acc, term))
427
428def dtlz7_prefix(+x: List<&2, F32>, fuel: Nat, +i: Nat) -> List<&2, F32>:
429 match fuel:
430 case 0n:
431 Nil{}
432 case 1n+f:
433 Util.get_f32(x, i) <> dtlz7_prefix(x, f, 1n+i)
434
435
436def dtlz7_f(+x: List<&2, F32>, +m: Nat) -> List<&2, F32>:
437 match m:
438 case 0n:
439 Nil{}
440 case 1n+p:
441 +g = dtlz7_g(x, m)
442 +g1 = F32.add(1.0, g)
443 +h = F32.sub(F32.from_nat(m), dtlz7_h.go(x, g1, p, 0n, 0.0))
444 List.append(&2, F32, dtlz7_prefix(x, p, 0n), [F32.mul(g1, h)])
445
446def sum_sq(xs: List<&2, F32>) -> F32:
447 match xs:
448 case Nil{}:
449 0.0
450 case h <> t:
451 F32.add(F32.square(h), sum_sq(t))
452
453def sphere_f(+x: List<&2, F32>) -> List<&2, F32>:
454 [sum_sq(x)]
455
456type Acc2 is Data:
457 Acc2{
458 s1: F32
459 s2: F32
460 }
461
462def ackley_go(xs: List<&2, F32>, +s1: F32, +s2: F32) -> Acc2:
463 match xs:
464 case Nil{}:
465 Acc2{s1, s2}
466 case +h <> t:
467 ackley_go(
468 t,
469 F32.add(s1, F32.square(h)),
470 F32.add(s2, F32.cos(F32.mul(F32.mul(2.0, F32.pi()), h)))
471 )
472
473def ackley_den(n: Nat) -> F32:
474 match n:
475 case 0n:
476 1.0
477 case 1n+p:
478 F32.from_nat(1n+p)
479
480def ackley_from(+n: Nat, acc: Acc2) -> List<&2, F32>:
481 match acc:
482 case Acc2{s1, s2}:
483 +den = ackley_den(n)
484 [F32.add(
485 F32.add(
486 F32.mul(F32.neg(20.0), F32.exp(F32.mul(F32.neg(0.2), F32.sqrt(F32.div(s1, den))))),
487 F32.neg(F32.exp(F32.div(s2, den)))
488 ),
489 F32.add(20.0, F32.exp(1.0))
490 )]
491
492
493def ackley_f(+x: List<&2, F32>) -> List<&2, F32>:
494 ackley_from(Util.list_len(F32, x), ackley_go(x, 0.0, 0.0))
495
496def rosen_step(rest: List<&2, F32>, +a: F32) -> F32:
497 match rest:
498 case Nil{}:
499 0.0
500 case +b <> t:
501 +diff = F32.sub(b, F32.square(a))
502 +one = F32.sub(1.0, a)
503 F32.add(F32.add(F32.mul(100.0, F32.square(diff)), F32.square(one)), rosen_step(t, b))
504
505def rosenbrock_f(+x: List<&2, F32>) -> List<&2, F32>:
506 match x:
507 case Nil{}:
508 [0.0]
509 case a <> rest:
510 [rosen_step(rest, a)]
511
512
513type Scored is Data:
514 Scored{
515 f: List<&2, F32>
516 g: List<&2, F32>
517 }
518
519def plain(+f: List<&2, F32>) -> Scored:
520 Scored{f, Nil{}}
521
522def scored_f(s: Scored) -> List<&2, F32>:
523 match s:
524 case Scored{f, g}:
525 f
526
527def scored_g(s: Scored) -> List<&2, F32>:
528 match s:
529 case Scored{f, g}:
530 g
531
532
533def osy_f(+x: List<&2, F32>) -> List<&2, F32>:
534 +x0 = Util.get_f32(x, 0n)
535 +x1 = Util.get_f32(x, 1n)
536 +x2 = Util.get_f32(x, 2n)
537 +x3 = Util.get_f32(x, 3n)
538 +x4 = Util.get_f32(x, 4n)
539 +pen = F32.add(
540 F32.mul(25.0, F32.square(F32.sub(x0, 2.0))),
541 F32.add(
542 F32.square(F32.sub(x1, 2.0)),
543 F32.add(
544 F32.square(F32.sub(x2, 1.0)),
545 F32.add(F32.square(F32.sub(x3, 4.0)), F32.square(F32.sub(x4, 1.0)))
546 )
547 )
548 )
549 F32.neg(pen) <> [sum_sq(x)]
550
551
552def osy_g(+x: List<&2, F32>) -> List<&2, F32>:
553 +x0 = Util.get_f32(x, 0n)
554 +x1 = Util.get_f32(x, 1n)
555 +x2 = Util.get_f32(x, 2n)
556 +x3 = Util.get_f32(x, 3n)
557 +x4 = Util.get_f32(x, 4n)
558 +x5 = Util.get_f32(x, 5n)
559 F32.neg(F32.div(F32.sub(F32.add(x0, x1), 2.0), 2.0))
560 <> F32.neg(F32.div(F32.sub(F32.sub(6.0, x0), x1), 6.0))
561 <> F32.neg(F32.div(F32.add(F32.sub(2.0, x1), x0), 2.0))
562 <> F32.neg(F32.div(F32.add(F32.sub(2.0, x0), F32.mul(3.0, x1)), 2.0))
563 <> F32.neg(F32.div(F32.sub(F32.sub(4.0, F32.square(F32.sub(x2, 3.0))), x3), 4.0))
564 <> [F32.neg(F32.div(F32.sub(F32.add(F32.square(F32.sub(x4, 3.0)), x5), 4.0), 4.0))]
565
566def osy_score(+x: List<&2, F32>) -> Scored:
567 Scored{osy_f(x), osy_g(x)}
568
569
570def tnk_g(+x: List<&2, F32>) -> List<&2, F32>:
571 +x0 = Util.get_f32(x, 0n)
572 +x1 = Util.get_f32(x, 1n)
573 +circle = F32.sub(
574 F32.sub(F32.add(F32.square(x0), F32.square(x1)), 1.0),
575 F32.mul(0.1, F32.cos(F32.mul(16.0, F32.atan(F32.div(x0, x1)))))
576 )
577 +dx = F32.sub(x0, 0.5)
578 +dy = F32.sub(x1, 0.5)
579 F32.neg(circle) <> [F32.sub(F32.mul(2.0, F32.add(F32.square(dx), F32.square(dy))), 1.0)]
580
581def tnk_score(+x: List<&2, F32>) -> Scored:
582 Scored{Util.get_f32(x, 0n) <> [Util.get_f32(x, 1n)], tnk_g(x)}
583
584
585def c1_w(fuel: Nat, fs: List<&2, F32>, +acc: F32) -> F32:
586 match fuel:
587 case 0n:
588 acc
589 case 1n:
590 match fs:
591 case Nil{}:
592 acc
593 case +h <> rest:
594 F32.add(acc, F32.div(h, 0.6))
595 case 1n+f:
596 match fs:
597 case Nil{}:
598 acc
599 case +h <> rest:
600 c1_w(f, rest, F32.add(acc, F32.div(h, 0.5)))
601
602def c1_g(+fs: List<&2, F32>) -> List<&2, F32>:
603 [F32.sub(c1_w(Util.list_len(F32, fs), fs, 0.0), 1.0)]
604
605def c1_score(+x: List<&2, F32>, +m: Nat) -> Scored:
606 +f = dtlz1_f(x, m)
607 Scored{f, c1_g(f)}
608
609def eval_kind(kind: Family, +x: List<&2, F32>, +m: Nat, +alpha: F32) -> Scored:
610 match kind:
611 case Zdt1{}:
612 plain(zdt1_f(x))
613 case Zdt2{}:
614 plain(zdt2_f(x))
615 case Zdt3{}:
616 plain(zdt3_f(x))
617 case Zdt4{}:
618 plain(zdt4_f(x))
619 case Zdt6{}:
620 plain(zdt6_f(x))
621 case Dtlz1{}:
622 plain(dtlz1_f(x, m))
623 case Dtlz2{}:
624 plain(dtlz2_f(x, m))
625 case Dtlz3{}:
626 plain(dtlz3_f(x, m))
627 case Dtlz4{}:
628 plain(dtlz4_f(x, m, alpha))
629 case Dtlz7{}:
630 plain(dtlz7_f(x, m))
631 case Sphere{}:
632 plain(sphere_f(x))
633 case Ackley{}:
634 plain(ackley_f(x))
635 case Rosenbrock{}:
636 plain(rosenbrock_f(x))
637 case Osy{}:
638 osy_score(x)
639 case Tnk{}:
640 tnk_score(x)
641 case C1Dtlz1{}:
642 c1_score(x, m)
643
644def apply_score(+ind: Ind.Individual, s: Scored) -> Ind.Individual:
645 match s:
646 case Scored{f, g}:
647 Ind.set_constraints(Ind.set_objectives(ind, f), g)
648
649def evaluate(+p: Problem, +ind: Ind.Individual) -> Ind.Individual:
650 apply_score(ind, eval_kind(kind_of(p), Ind.variables(ind), n_obj(p), alpha_of(p)))
651
652
653def evaluate_all(+p: Problem, +xs: List<&2, Ind.Individual>) -> List<&2, Ind.Individual>:
654 Util.map_halves(~Ind.Individual, ~Ind.Individual, ~Problem, ~evaluate, p, xs)