17
17
18
18
import numpy as np
19
19
from numpy import sum as npsum
20
+ from moptipy .api .mo_utils import dominates
20
21
21
22
from moptipy .api .objective import Objective
22
23
from moptipy .mo .problem .basic_mo_problem import BasicMOProblem
@@ -64,11 +65,18 @@ def __init__(self, objectives: Iterable[Objective],
64
65
List [Union [int , float ]], Callable [
65
66
[Union [None , np .dtype , Tuple [
66
67
Union [int , float ], ...]]], None ]],
67
- Callable [[np .ndarray ], Union [int , float ]]]) -> None :
68
+ Callable [[np .ndarray ], Union [int , float ]]],
69
+ domination : Optional [Callable [[np .ndarray , np .ndarray ], int ]]
70
+ = dominates ) -> None :
68
71
"""
69
72
Create the sum-based scalarization.
70
73
71
74
:param objectives: the objectives
75
+ :param domination: a function reflecting the domination relationship
76
+ between two vectors of objective values. It must obey the contract
77
+ of :meth:`~moptipy.api.mo_problem.MOProblem.f_dominates`, which is
78
+ the same as :func:`moptipy.api.mo_utils.dominates`, to which it
79
+ defaults. `None` overrides nothing.
72
80
"""
73
81
holder : List [Any ] = []
74
82
super ().__init__ (
@@ -77,7 +85,8 @@ def __init__(self, objectives: Iterable[Objective],
77
85
List [Union [int , float ]]], Callable [
78
86
[np .ndarray ], Union [int , float ]]],
79
87
lambda ai , n , lb , ub , fwd = holder .append :
80
- get_scalarizer (ai , n , lb , ub , fwd )))
88
+ get_scalarizer (ai , n , lb , ub , fwd )),
89
+ domination )
81
90
if len (holder ) != 2 :
82
91
raise ValueError (
83
92
f"need weights and weights dtype, but got { holder } ." )
@@ -242,14 +251,20 @@ class WeightedSum(BasicWeightedSum):
242
251
"""Scalarize objective values by computing their weighted sum."""
243
252
244
253
def __init__ (self , objectives : Iterable [Objective ],
245
- weights : Optional [Iterable [Union [int , float ]]] = None ) \
246
- -> None :
254
+ weights : Optional [Iterable [Union [int , float ]]] = None ,
255
+ domination : Optional [Callable [[np .ndarray , np .ndarray ], int ]]
256
+ = dominates ) -> None :
247
257
"""
248
258
Create the sum-based scalarization.
249
259
250
260
:param objectives: the objectives
251
261
:param weights: the weights of the objective values, or `None` if all
252
262
weights are `1`.
263
+ :param domination: a function reflecting the domination relationship
264
+ between two vectors of objective values. It must obey the contract
265
+ of :meth:`~moptipy.api.mo_problem.MOProblem.f_dominates`, which is
266
+ the same as :func:`moptipy.api.mo_utils.dominates`, to which it
267
+ defaults. `None` overrides nothing.
253
268
"""
254
269
use_weights : Optional [Tuple [Union [int , float ], ...]] \
255
270
= None if weights is None else tuple (try_int (w ) for w in weights )
@@ -263,15 +278,17 @@ def __init__(self, objectives: Iterable[Objective],
263
278
Union [int , float ], ...]]], None ]],
264
279
Callable [[np .ndarray ], Union [int , float ]]],
265
280
lambda ai , n , lb , ub , cb , uw = use_weights :
266
- _make_sum_scalarizer (ai , n , lb , ub , uw , cb )))
281
+ _make_sum_scalarizer (ai , n , lb , ub , uw , cb )),
282
+ domination )
267
283
268
284
def __str__ (self ):
269
285
"""
270
286
Get the string representation of the weighted sum scalarization.
271
287
272
288
:returns: `"weightedSum"`
273
289
"""
274
- return "weightedSum"
290
+ return "weightedSum" if self .f_dominates is dominates \
291
+ else "weightedSumWithDominationFunc"
275
292
276
293
277
294
def _prioritize (always_int : bool ,
@@ -332,18 +349,26 @@ def _prioritize(always_int: bool,
332
349
class Prioritize (BasicWeightedSum ):
333
350
"""Prioritize the first objective over the second and so on."""
334
351
335
- def __init__ (self , objectives : Iterable [Objective ]) -> None :
352
+ def __init__ (self , objectives : Iterable [Objective ],
353
+ domination : Optional [Callable [[np .ndarray , np .ndarray ], int ]]
354
+ = dominates ) -> None :
336
355
"""
337
356
Create the sum-based prioritization.
338
357
339
358
:param objectives: the objectives
359
+ :param domination: a function reflecting the domination relationship
360
+ between two vectors of objective values. It must obey the contract
361
+ of :meth:`~moptipy.api.mo_problem.MOProblem.f_dominates`, which is
362
+ the same as :func:`moptipy.api.mo_utils.dominates`, to which it
363
+ defaults. `None` overrides nothing.
340
364
"""
341
- super ().__init__ (objectives , _prioritize )
365
+ super ().__init__ (objectives , _prioritize , domination )
342
366
343
367
def __str__ (self ):
344
368
"""
345
369
Get the name of the weighted sum-based prioritization.
346
370
347
371
:returns: `"weightBasedPrioritization"`
348
372
"""
349
- return "weightBasedPrioritization"
373
+ return "weightBasedPrioritization" if self .f_dominates is dominates \
374
+ else "weightBasedPrioritizationWithDominationFunc"
0 commit comments