optuna

Форк
0
824 строки · 26.1 Кб
1
from __future__ import annotations
2

3
import math
4
import sys
5

6
import numpy as np
7
import shape_functions
8
import transformation_functions
9

10
from kurobako import problem
11

12

13
class BaseWFG:
14
    def __init__(
15
        self,
16
        S: np.ndarray,
17
        A: np.ndarray,
18
        upper_bounds: np.ndarray,
19
        shapes: list[shape_functions.BaseShapeFunction],
20
        transformations: list[list[transformation_functions.BaseTransformations]],
21
    ) -> None:
22
        assert all(S > 0)
23
        assert all((A == 0) + (A == 1))
24
        assert all(upper_bounds > 0)
25

26
        self._S = S
27
        self._A = A
28
        self._upper_bounds = upper_bounds
29
        self._shapes = shapes
30
        self._transformations = transformations
31

32
    def __call__(self, z: np.ndarray) -> np.ndarray:
33
        S = self._S
34
        A = self._A
35
        unit_z = z / self._upper_bounds
36
        shapes = self._shapes
37
        transformations = self._transformations
38

39
        y = unit_z
40
        for t_p in transformations:
41
            _y = np.empty((len(t_p),))
42
            for i in range(len(t_p)):
43
                if isinstance(t_p[i], transformation_functions.BaseReductionTransformation):
44
                    _y[i] = t_p[i](y)
45
                else:
46
                    _y[i] = t_p[i](y[i])
47
            y = _y
48

49
        x = np.empty(y.shape)
50
        x[:-1] = np.maximum(y[-1], A) * (y[:-1] - 0.5) + 0.5
51
        x[-1] = y[-1]
52

53
        f = x[-1] + S * np.asarray([h(m + 1, x[:-1]) for m, h in enumerate(shapes)])
54
        return f
55

56

57
class WFG1:
58
    """WFG1
59

60
    Args:
61
        n_arguments:
62
            The number of arguments.
63
        n_objectives:
64
            The number of objectives.
65
        k:
66
            The degree of the Pareto front.
67
    """
68

69
    def __init__(self, n_arguments: int, n_objectives: int, k: int):
70
        assert k % (n_objectives - 1) == 0
71
        assert k + 1 <= n_arguments
72

73
        self._n_arguments = n_arguments
74
        self._n_objectives = n_objectives
75
        self._k = k
76

77
        n = self._n_arguments
78
        M = self._n_objectives
79

80
        S = 2 * (np.arange(M) + 1)
81
        A = np.ones(M - 1)
82
        upper_bounds = 2 * (np.arange(n) + 1)
83

84
        self.domain = np.zeros((n, 2))
85
        self.domain[:, 1] = upper_bounds
86

87
        shapes: list[shape_functions.BaseShapeFunction]
88
        shapes = [shape_functions.ConvexShapeFunction(M) for _ in range(M - 1)]
89
        shapes.append(shape_functions.MixedConvexOrConcaveShapeFunction(M, 1, 5))
90

91
        transformations: list[list[transformation_functions.BaseTransformations]]
92
        transformations = [[] for _ in range(4)]
93

94
        transformations[0] = [transformation_functions.IdenticalTransformation() for _ in range(k)]
95
        # transformations[0] = [lambda y: y for _ in range(k)]
96
        for _ in range(n - k):
97
            transformations[0].append(transformation_functions.LinearShiftTransformation(0.35))
98

99
        # transformations[1] = [lambda y: y for _ in range(k)]
100

101
        transformations[1] = [transformation_functions.IdenticalTransformation() for _ in range(k)]
102
        for _ in range(n - k):
103
            transformations[1].append(
104
                transformation_functions.FlatRegionBiasTransformation(0.8, 0.75, 0.85)
105
            )
106

107
        transformations[2] = [
108
            transformation_functions.PolynomialBiasTransformation(0.02) for _ in range(n)
109
        ]
110

111
        def _input_converter(i: int, y: np.ndarray) -> np.ndarray:
112
            indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1))
113
            return y[indices]
114

115
        transformations[3] = [
116
            transformation_functions.WeightedSumReductionTransformation(
117
                2 * np.arange(i * k // (M - 1) + 1, (i + 1) * k // (M - 1) + 1),
118
                lambda y: _input_converter(i, y),
119
            )
120
            for i in range(M - 1)
121
        ]
122
        transformations[3].append(
123
            transformation_functions.WeightedSumReductionTransformation(
124
                2 * np.arange(k, n) + 1,
125
                lambda y: y[k:n],
126
            )
127
        )
128

129
        self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations)
130

131
    def __call__(self, z: np.ndarray) -> np.ndarray:
132
        return self.wfg.__call__(z)
133

134

135
class WFG2:
136
    """WFG2
137

138
    Args:
139
        n_arguments:
140
            The number of arguments.
141
        n_objectives:
142
            The number of objectives.
143
        k:
144
            The degree of the Pareto front.
145
    """
146

147
    def __init__(self, n_arguments: int, n_objectives: int, k: int):
148
        assert k % (n_objectives - 1) == 0
149
        assert k + 1 <= n_arguments // 2
150
        assert (n_arguments - k) % 2 == 0
151

152
        self._n_arguments = n_arguments
153
        self._n_objectives = n_objectives
154
        self._k = k
155

156
        n = self._n_arguments
157
        M = self._n_objectives
158

159
        S = 2 * (np.arange(M) + 1)
160
        A = np.ones(M - 1)
161
        upper_bounds = 2 * (np.arange(n) + 1)
162

163
        self.domain = np.zeros((n, 2))
164
        self.domain[:, 1] = upper_bounds
165

166
        shapes: list[shape_functions.BaseShapeFunction]
167
        shapes = [shape_functions.ConvexShapeFunction(M) for _ in range(M - 1)]
168
        shapes.append(shape_functions.DisconnectedShapeFunction(M, 1, 1, 5))
169

170
        transformations: list[list[transformation_functions.BaseTransformations]]
171
        transformations = [[] for _ in range(3)]
172

173
        transformations[0] = [transformation_functions.IdenticalTransformation() for _ in range(k)]
174
        for _ in range(n - k):
175
            transformations[0].append(transformation_functions.LinearShiftTransformation(0.35))
176

177
        def _input_converter0(i: int, y: np.ndarray) -> np.ndarray:
178
            indices = [k + 2 * (i + 1 - k) - 2, k + 2 * (i - k + 1) - 1]
179
            return y[indices]
180

181
        transformations[1] = [transformation_functions.IdenticalTransformation() for _ in range(k)]
182
        for i in range(k, n // 2):
183
            transformations[1].append(
184
                transformation_functions.NonSeparableReductionTransformation(
185
                    2, lambda y: _input_converter0(i, y)
186
                )
187
            )
188

189
        def _input_converter1(i: int, y: np.ndarray) -> np.ndarray:
190
            indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1))
191
            return y[indices]
192

193
        transformations[2] = [
194
            transformation_functions.WeightedSumReductionTransformation(
195
                np.ones(k // (M - 1)),
196
                lambda y: _input_converter1(i, y),
197
            )
198
            for i in range(M - 1)
199
        ]
200
        transformations[2].append(
201
            transformation_functions.WeightedSumReductionTransformation(
202
                np.ones(n // 2 - k),
203
                lambda y: y[k : n // 2],
204
            )
205
        )
206

207
        # transformations = [transformations[0], transformations[1], transformations[2]]
208

209
        self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations)
210

211
    def __call__(self, z: np.ndarray) -> np.ndarray:
212
        return self.wfg.__call__(z)
213

214

215
class WFG3:
216
    """WFG3
217

218
    Args:
219
        n_arguments:
220
            The number of arguments.
221
        n_objectives:
222
            The number of objectives.
223
        k:
224
            The degree of the Pareto front.
225
    """
226

227
    def __init__(self, n_arguments: int, n_objectives: int, k: int):
228
        assert k % (n_objectives - 1) == 0
229
        assert k + 1 <= n_arguments // 2
230
        assert (n_arguments - k) % 2 == 0
231

232
        self._n_arguments = n_arguments
233
        self._n_objectives = n_objectives
234
        self._k = k
235

236
        n = self._n_arguments
237
        M = self._n_objectives
238

239
        S = 2 * (np.arange(M) + 1)
240
        A = np.zeros(M - 1)
241
        A[0] = 1
242
        upper_bounds = 2 * (np.arange(n) + 1)
243

244
        self.domain = np.zeros((n, 2))
245
        self.domain[:, 1] = upper_bounds
246

247
        shapes: list[shape_functions.BaseShapeFunction]
248
        shapes = [shape_functions.LinearShapeFunction(M) for _ in range(M)]
249

250
        transformations: list[list[transformation_functions.BaseTransformations]]
251
        transformations = [[] for _ in range(3)]
252

253
        transformations[0] = [transformation_functions.IdenticalTransformation() for _ in range(k)]
254
        for _ in range(n - k):
255
            transformations[0].append(transformation_functions.LinearShiftTransformation(0.35))
256

257
        def _input_converter0(i: int, y: np.ndarray) -> np.ndarray:
258
            indices = [k + 2 * (i + 1 - k) - 2, k + 2 * (i - k + 1) - 1]
259
            return y[indices]
260

261
        transformations[1] = [transformation_functions.IdenticalTransformation() for _ in range(k)]
262
        for i in range(k, n // 2):
263
            transformations[1].append(
264
                transformation_functions.NonSeparableReductionTransformation(
265
                    2, lambda y: _input_converter0(i, y)
266
                )
267
            )
268

269
        def _input_converter1(i: int, y: np.ndarray) -> np.ndarray:
270
            indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1))
271
            return y[indices]
272

273
        transformations[2] = [
274
            transformation_functions.WeightedSumReductionTransformation(
275
                np.ones(k // (M - 1)),
276
                lambda y: _input_converter1(i, y),
277
            )
278
            for i in range(M - 1)
279
        ]
280
        transformations[2].append(
281
            transformation_functions.WeightedSumReductionTransformation(
282
                np.ones(n // 2 - k),
283
                lambda y: y[k : n // 2],
284
            )
285
        )
286

287
        # transformations = [transformations[0], transformations[1], transformations[2]]
288

289
        self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations)
290

291
    def __call__(self, z: np.ndarray) -> np.ndarray:
292
        return self.wfg.__call__(z)
293

294

295
class WFG4:
296
    """WFG4
297

298
    Args:
299
        n_arguments:
300
            The number of arguments.
301
        n_objectives:
302
            The number of objectives.
303
        k:
304
            The degree of the Pareto front.
305
    """
306

307
    def __init__(self, n_arguments: int, n_objectives: int, k: int):
308
        assert k % (n_objectives - 1) == 0
309
        assert k + 1 <= n_arguments
310

311
        self._n_arguments = n_arguments
312
        self._n_objectives = n_objectives
313
        self._k = k
314

315
        n = self._n_arguments
316
        M = self._n_objectives
317

318
        S = 2 * (np.arange(M) + 1)
319
        A = np.ones(M - 1)
320
        upper_bounds = 2 * (np.arange(n) + 1)
321

322
        self.domain = np.zeros((n, 2))
323
        self.domain[:, 1] = upper_bounds
324

325
        shapes: list[shape_functions.BaseShapeFunction]
326
        shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)]
327

328
        transformations: list[list[transformation_functions.BaseTransformations]]
329
        transformations = [[] for _ in range(2)]
330

331
        transformations[0] = [
332
            transformation_functions.MultiModalShiftTransformation(30, 10, 0.35) for _ in range(n)
333
        ]
334

335
        def _input_converter(i: int, y: np.ndarray) -> np.ndarray:
336
            indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1))
337
            return y[indices]
338

339
        # transformations[1] = []
340
        for i in range(M - 1):
341
            transformations[1].append(
342
                transformation_functions.WeightedSumReductionTransformation(
343
                    np.ones(k // (M - 1)), lambda y: _input_converter(i, y)
344
                )
345
            )
346
        transformations[1].append(
347
            transformation_functions.WeightedSumReductionTransformation(
348
                np.ones(n - k),
349
                lambda y: y[k:n],
350
            )
351
        )
352

353
        # transformations = [transformations[0], transformations[1]]
354

355
        self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations)
356

357
    def __call__(self, z: np.ndarray) -> np.ndarray:
358
        return self.wfg.__call__(z)
359

360

361
class WFG5:
362
    """WFG5
363

364
    Args:
365
        n_arguments:
366
            The number of arguments.
367
        n_objectives:
368
            The number of objectives.
369
        k:
370
            The degree of the Pareto front.
371
    """
372

373
    def __init__(self, n_arguments: int, n_objectives: int, k: int):
374
        assert k % (n_objectives - 1) == 0
375
        assert k + 1 <= n_arguments
376

377
        self._n_arguments = n_arguments
378
        self._n_objectives = n_objectives
379
        self._k = k
380

381
        n = self._n_arguments
382
        M = self._n_objectives
383

384
        S = 2 * (np.arange(M) + 1)
385
        A = np.ones(M - 1)
386
        upper_bounds = 2 * (np.arange(n) + 1)
387

388
        self.domain = np.zeros((n, 2))
389
        self.domain[:, 1] = upper_bounds
390

391
        shapes: list[shape_functions.BaseShapeFunction]
392
        shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)]
393

394
        transformations: list[list[transformation_functions.BaseTransformations]]
395
        transformations = [[] for _ in range(2)]
396

397
        transformations[0] = [
398
            transformation_functions.DeceptiveShiftTransformation(0.35, 0.001, 0.05)
399
            for _ in range(n)
400
        ]
401

402
        def _input_converter(i: int, y: np.ndarray) -> np.ndarray:
403
            indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1))
404
            return y[indices]
405

406
        transformations[1] = []
407
        for i in range(M - 1):
408
            transformations[1].append(
409
                transformation_functions.WeightedSumReductionTransformation(
410
                    np.ones(k // (M - 1)), lambda y: _input_converter(i, y)
411
                )
412
            )
413
        transformations[1].append(
414
            transformation_functions.WeightedSumReductionTransformation(
415
                np.ones(n - k),
416
                lambda y: y[k:n],
417
            )
418
        )
419

420
        # transformations = [transformations[0], transformations[1]]
421

422
        self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations)
423

424
    def __call__(self, z: np.ndarray) -> np.ndarray:
425
        return self.wfg.__call__(z)
426

427

428
class WFG6:
429
    """WFG6
430

431
    Args:
432
        n_arguments:
433
            The number of arguments.
434
        n_objectives:
435
            The number of objectives.
436
        k:
437
            The degree of the Pareto front.
438
    """
439

440
    def __init__(self, n_arguments: int, n_objectives: int, k: int):
441
        assert k % (n_objectives - 1) == 0
442
        assert k + 1 <= n_arguments
443

444
        self._n_arguments = n_arguments
445
        self._n_objectives = n_objectives
446
        self._k = k
447

448
        n = self._n_arguments
449
        M = self._n_objectives
450

451
        S = 2 * (np.arange(M) + 1)
452
        A = np.ones(M - 1)
453
        upper_bounds = 2 * (np.arange(n) + 1)
454

455
        self.domain = np.zeros((n, 2))
456
        self.domain[:, 1] = upper_bounds
457

458
        shapes: list[shape_functions.BaseShapeFunction]
459
        shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)]
460

461
        transformations: list[list[transformation_functions.BaseTransformations]]
462
        transformations = [[] for _ in range(2)]
463

464
        transformations[0] = [transformation_functions.IdenticalTransformation() for _ in range(k)]
465
        for _ in range(n - k):
466
            transformations[0].append(transformation_functions.LinearShiftTransformation(0.35))
467

468
        def _input_converter(i: int, y: np.ndarray) -> np.ndarray:
469
            indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1))
470
            return y[indices]
471

472
        # transformations[1] = []
473
        for i in range(M - 1):
474
            transformations[1].append(
475
                transformation_functions.NonSeparableReductionTransformation(
476
                    k // (M - 1), lambda y: _input_converter(i, y)
477
                )
478
            )
479
        transformations[1].append(
480
            transformation_functions.NonSeparableReductionTransformation(
481
                n - k,
482
                lambda y: y[k:n],
483
            )
484
        )
485

486
        # transformations = [transformations[0], transformations[1]]
487

488
        self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations)
489

490
    def __call__(self, z: np.ndarray) -> np.ndarray:
491
        return self.wfg.__call__(z)
492

493

494
class WFG7:
495
    """WFG7
496

497
    Args:
498
        n_arguments:
499
            The number of arguments.
500
        n_objectives:
501
            The number of objectives.
502
        k:
503
            The degree of the Pareto front.
504
    """
505

506
    def __init__(self, n_arguments: int, n_objectives: int, k: int):
507
        assert k % (n_objectives - 1) == 0
508
        assert k + 1 <= n_arguments
509

510
        self._n_arguments = n_arguments
511
        self._n_objectives = n_objectives
512
        self._k = k
513

514
        n = self._n_arguments
515
        M = self._n_objectives
516

517
        S = 2 * (np.arange(M) + 1)
518
        A = np.ones(M - 1)
519
        upper_bounds = 2 * (np.arange(n) + 1)
520

521
        self.domain = np.zeros((n, 2))
522
        self.domain[:, 1] = upper_bounds
523

524
        shapes: list[shape_functions.BaseShapeFunction]
525
        shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)]
526

527
        def _input_converter0(i: int, y: np.ndarray) -> np.ndarray:
528
            return y[i:n]
529

530
        transformations: list[list[transformation_functions.BaseTransformations]]
531
        transformations = [[] for _ in range(3)]
532

533
        transformations[0] = [
534
            transformation_functions.ParameterDependentBiasTransformation(
535
                np.ones(n - i),
536
                lambda y: _input_converter0(i, y),
537
                0.98 / 49.98,
538
                0.02,
539
                50,
540
                i,
541
            )
542
            for i in range(k)
543
        ]
544
        for _ in range(n - k):
545
            transformations[0].append(transformation_functions.IdenticalTransformation())
546

547
        transformations[1] = [transformation_functions.IdenticalTransformation() for _ in range(k)]
548
        for _ in range(n - k):
549
            transformations[1].append(transformation_functions.LinearShiftTransformation(0.35))
550

551
        def _input_converter1(i: int, y: np.ndarray) -> np.ndarray:
552
            indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1))
553
            return y[indices]
554

555
        transformations[2] = []
556
        for i in range(M - 1):
557
            transformations[2].append(
558
                transformation_functions.WeightedSumReductionTransformation(
559
                    np.ones(k // (M - 1)), lambda y: _input_converter1(i, y)
560
                )
561
            )
562
        transformations[2].append(
563
            transformation_functions.WeightedSumReductionTransformation(
564
                np.ones(n - k),
565
                lambda y: y[k:n],
566
            )
567
        )
568

569
        # transformations = [transformations[0], transformations[1], transformations[2]]
570

571
        self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations)
572

573
    def __call__(self, z: np.ndarray) -> np.ndarray:
574
        return self.wfg.__call__(z)
575

576

577
class WFG8:
578
    """WFG8
579

580
    Args:
581
        n_arguments:
582
            The number of arguments.
583
        n_objectives:
584
            The number of objectives.
585
        k:
586
            The degree of the Pareto front.
587
    """
588

589
    def __init__(self, n_arguments: int, n_objectives: int, k: int):
590
        assert k % (n_objectives - 1) == 0
591
        assert k + 1 <= n_arguments
592

593
        self._n_arguments = n_arguments
594
        self._n_objectives = n_objectives
595
        self._k = k
596

597
        n = self._n_arguments
598
        M = self._n_objectives
599

600
        S = 2 * (np.arange(M) + 1)
601
        A = np.ones(M - 1)
602
        upper_bounds = 2 * (np.arange(n) + 1)
603

604
        self.domain = np.zeros((n, 2))
605
        self.domain[:, 1] = upper_bounds
606

607
        shapes: list[shape_functions.BaseShapeFunction]
608
        shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)]
609

610
        def _input_converter0(i: int, y: np.ndarray) -> np.ndarray:
611
            return y[: i - 1]
612

613
        transformations: list[list[transformation_functions.BaseTransformations]]
614
        transformations = [[] for _ in range(3)]
615

616
        transformations[0] = [transformation_functions.IdenticalTransformation() for _ in range(k)]
617
        for i in range(k, n):
618
            transformations[0].append(
619
                transformation_functions.ParameterDependentBiasTransformation(
620
                    np.ones(i - 1),
621
                    lambda y: _input_converter0(i, y),
622
                    0.98 / 49.98,
623
                    0.02,
624
                    50,
625
                    i,
626
                )
627
            )
628

629
        transformations[1] = [transformation_functions.IdenticalTransformation() for _ in range(k)]
630
        for _ in range(n - k):
631
            transformations[1].append(transformation_functions.LinearShiftTransformation(0.35))
632

633
        def _input_converter(i: int, y: np.ndarray) -> np.ndarray:
634
            indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1))
635
            return y[indices]
636

637
        transformations[2] = []
638
        for i in range(M - 1):
639
            transformations[2].append(
640
                transformation_functions.WeightedSumReductionTransformation(
641
                    np.ones(k // (M - 1)), lambda y: _input_converter(i, y)
642
                )
643
            )
644
        transformations[2].append(
645
            transformation_functions.WeightedSumReductionTransformation(
646
                np.ones(n - k),
647
                lambda y: y[k:n],
648
            )
649
        )
650

651
        # transformations = [transformations[0], transformations[1], transformations[2]]
652

653
        self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations)
654

655
    def __call__(self, z: np.ndarray) -> np.ndarray:
656
        return self.wfg.__call__(z)
657

658

659
class WFG9:
660
    """WFG9
661

662
    Args:
663
        n_arguments:
664
            The number of arguments.
665
        n_objectives:
666
            The number of objectives.
667
        k:
668
            The degree of the Pareto front.
669
    """
670

671
    def __init__(self, n_arguments: int, n_objectives: int, k: int):
672
        assert k % (n_objectives - 1) == 0
673
        assert k + 1 <= n_arguments
674

675
        self._n_arguments = n_arguments
676
        self._n_objectives = n_objectives
677
        self._k = k
678

679
        n = self._n_arguments
680
        M = self._n_objectives
681

682
        S = 2 * (np.arange(M) + 1)
683
        A = np.ones(M - 1)
684
        upper_bounds = 2 * (np.arange(n) + 1)
685

686
        self.domain = np.zeros((n, 2))
687
        self.domain[:, 1] = upper_bounds
688

689
        shapes: list[shape_functions.BaseShapeFunction]
690
        shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)]
691

692
        def _input_converter0(i: int, y: np.ndarray) -> np.ndarray:
693
            return y[i:n]
694

695
        transformations: list[list[transformation_functions.BaseTransformations]]
696
        transformations = [[] for _ in range(3)]
697

698
        transformations[0] = [
699
            transformation_functions.ParameterDependentBiasTransformation(
700
                np.ones(n - i),
701
                lambda y: _input_converter0(i, y),
702
                0.98 / 49.98,
703
                0.02,
704
                50,
705
                i,
706
            )
707
            for i in range(n - 1)
708
        ]
709
        transformations[0].append(transformation_functions.IdenticalTransformation())
710

711
        transformations[1] = [
712
            transformation_functions.DeceptiveShiftTransformation(0.35, 0.001, 0.05)
713
            for _ in range(k)
714
        ]
715
        for _ in range(n - k):
716
            transformations[1].append(
717
                transformation_functions.MultiModalShiftTransformation(30, 95, 0.35)
718
            )
719

720
        def _input_converter(i: int, y: np.ndarray) -> np.ndarray:
721
            indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1))
722
            return y[indices]
723

724
        transformations[2] = []
725
        for i in range(M - 1):
726
            transformations[2].append(
727
                transformation_functions.NonSeparableReductionTransformation(
728
                    k // (M - 1), lambda y: _input_converter(i, y)
729
                )
730
            )
731
        transformations[2].append(
732
            transformation_functions.NonSeparableReductionTransformation(
733
                n - k,
734
                lambda y: y[k:n],
735
            )
736
        )
737

738
        # transformations = [transformations[0], transformations[1], transformations[2]]
739

740
        self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations)
741

742
    def __call__(self, z: np.ndarray) -> np.ndarray:
743
        return self.wfg.__call__(z)
744

745

746
class WFGProblemFactory(problem.ProblemFactory):
747
    def specification(self) -> problem.ProblemSpec:
748
        self._n_wfg = int(sys.argv[1])
749
        self._n_dim = int(sys.argv[2])
750

751
        self._low = 0
752
        self._high = 2
753
        params = [
754
            problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i))
755
            for i in range(self._n_dim)
756
        ]
757
        return problem.ProblemSpec(
758
            name=f"WFG{self._n_wfg}",
759
            params=params,
760
            values=[problem.Var("f1"), problem.Var("f2")],
761
        )
762

763
    def create_problem(self, seed: int) -> problem.Problem:
764
        return WFGProblem()
765

766

767
class WFGProblem(problem.Problem):
768
    def __init__(self) -> None:
769
        super().__init__()
770

771
    def create_evaluator(self, params: list[problem.Var]) -> problem.Evaluator:
772
        return WFGEvaluator(params)
773

774

775
class WFGEvaluator(problem.Evaluator):
776
    def __init__(self, params: list[problem.Var]) -> None:
777
        self._n_wfg = int(sys.argv[1])
778
        self._n_dim = int(sys.argv[2])
779
        self._n_obj = int(sys.argv[3])
780
        self._k = int(sys.argv[4])
781

782
        self._x = np.array(params)
783
        self._current_step = 0
784

785
        self.wfg: WFG1 | WFG2 | WFG3 | WFG4 | WFG5 | WFG6 | WFG7 | WFG8 | WFG9
786
        if self._n_wfg == 1:
787
            self.wfg = WFG1(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k)
788
        elif self._n_wfg == 2:
789
            self.wfg = WFG2(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k)
790
        elif self._n_wfg == 3:
791
            self.wfg = WFG3(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k)
792
        elif self._n_wfg == 4:
793
            self.wfg = WFG4(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k)
794
        elif self._n_wfg == 5:
795
            self.wfg = WFG5(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k)
796
        elif self._n_wfg == 6:
797
            self.wfg = WFG6(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k)
798
        elif self._n_wfg == 7:
799
            self.wfg = WFG7(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k)
800
        elif self._n_wfg == 8:
801
            self.wfg = WFG8(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k)
802
        elif self._n_wfg == 9:
803
            self.wfg = WFG9(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k)
804
        else:
805
            raise AssertionError("Invalid specification for WFG number.")
806

807
    def current_step(self) -> int:
808
        return self._current_step
809

810
    def evaluate(self, next_step: int) -> list[float]:
811
        self._current_step = 1
812
        v = self.wfg(self._x)
813
        v = v.tolist()
814

815
        if math.isnan(v[0]) or math.isinf(v[0]):
816
            raise ValueError
817
        if math.isnan(v[1]) or math.isinf(v[1]):
818
            raise ValueError
819
        return [v[0], v[1]]
820

821

822
if __name__ == "__main__":
823
    runner = problem.ProblemRunner(WFGProblemFactory())
824
    runner.run()
825

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.