Update quality_indicator.py #11
Annotations
73 errors and 3 warnings
desdeo_tools/scalarization/ASF.py#L392
Trailing whitespace (W291)
|
desdeo_tools/scalarization/ASF.py#L393
Trailing whitespace (W291)
|
desdeo_tools/scalarization/ASF.py#L395
Blank line contains whitespace (W293)
|
desdeo_tools/scalarization/ASF.py#L403
Blank line contains whitespace (W293)
|
desdeo_tools/scalarization/ASF.py#L406
Trailing whitespace (W291)
|
desdeo_tools/scalarization/ASF.py#L407
Trailing whitespace (W291)
|
desdeo_tools/scalarization/ASF.py#L409
Blank line contains whitespace (W293)
|
desdeo_tools/scalarization/ASF.py#L412
Trailing whitespace (W291)
|
desdeo_tools/scalarization/ASF.py#L469
Blank line contains whitespace (W293)
|
desdeo_tools/scalarization/ASF.py#L474
Blank line contains whitespace (W293)
|
desdeo_tools/scalarization/ASF.py#L477
Trailing whitespace (W291)
|
desdeo_tools/scalarization/ASF.py#L497
Local variable 'phi' is assigned to but never used (F841)
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/interaction/validators.py#L1
import pandas as pd
import numpy as np
class ValidationError(Exception):
- """Raised when an error related to the validation is encountered.
- """
+ """Raised when an error related to the validation is encountered."""
-def validate_ref_point_with_ideal_and_nadir(
- dimensions_data: pd.DataFrame, reference_point: pd.DataFrame
-):
+def validate_ref_point_with_ideal_and_nadir(dimensions_data: pd.DataFrame, reference_point: pd.DataFrame):
validate_ref_point_dimensions(dimensions_data, reference_point)
validate_ref_point_data_type(reference_point)
validate_ref_point_with_ideal(dimensions_data, reference_point)
validate_with_ref_point_nadir(dimensions_data, reference_point)
-def validate_ref_point_with_ideal(
- dimensions_data: pd.DataFrame, reference_point: pd.DataFrame
-):
+def validate_ref_point_with_ideal(dimensions_data: pd.DataFrame, reference_point: pd.DataFrame):
validate_ref_point_dimensions(dimensions_data, reference_point)
ideal_fitness = dimensions_data.loc["ideal"] * dimensions_data.loc["minimize"]
ref_point_fitness = reference_point * dimensions_data.loc["minimize"]
if not (ideal_fitness <= ref_point_fitness).all(axis=None):
- problematic_columns = ideal_fitness.index[
- (ideal_fitness > ref_point_fitness).values.tolist()[0]
- ].values
+ problematic_columns = ideal_fitness.index[(ideal_fitness > ref_point_fitness).values.tolist()[0]].values
msg = (
f"Reference point should be worse than or equal to the ideal point\n"
f"The following columns have problematic values: {problematic_columns}"
)
raise ValidationError(msg)
-def validate_with_ref_point_nadir(
- dimensions_data: pd.DataFrame, reference_point: pd.DataFrame
-):
+def validate_with_ref_point_nadir(dimensions_data: pd.DataFrame, reference_point: pd.DataFrame):
validate_ref_point_dimensions(dimensions_data, reference_point)
nadir_fitness = dimensions_data.loc["nadir"] * dimensions_data.loc["minimize"]
ref_point_fitness = reference_point * dimensions_data.loc["minimize"]
if not (ref_point_fitness <= nadir_fitness).all(axis=None):
- problematic_columns = nadir_fitness.index[
- (nadir_fitness < ref_point_fitness).values.tolist()[0]
- ].values
+ problematic_columns = nadir_fitness.index[(nadir_fitness < ref_point_fitness).values.tolist()[0]].values
msg = (
f"Reference point should be better than or equal to the nadir point\n"
f"The following columns have problematic values: {problematic_columns}"
)
raise ValidationError(msg)
-def validate_ref_point_dimensions(
- dimensions_data: pd.DataFrame, reference_point: pd.DataFrame
-):
+def validate_ref_point_dimensions(dimensions_data: pd.DataFrame, reference_point: pd.DataFrame):
if not dimensions_data.shape[1] == reference_point.shape[1]:
msg = (
f"There is a mismatch in the number of columns of the dataframes.\n"
f"Columns in dimensions data: {dimensions_data.columns}\n"
f"Columns in the reference point provided: {reference_point.columns}"
|
desdeo_tools/utilities/quality_indicator.py#L95
Expected 2 blank lines after class or function definition, found 1 (E305)
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/interaction/validators.py#L70
def validate_ref_point_data_type(reference_point: pd.DataFrame):
for dtype in reference_point.dtypes:
if not pd.api.types.is_numeric_dtype(dtype):
- msg = (
- f"Type of data in reference point dataframe should be numeric.\n"
- f"Provided datatype: {dtype}"
- )
+ msg = f"Type of data in reference point dataframe should be numeric.\n" f"Provided datatype: {dtype}"
raise ValidationError(msg)
def validate_specified_solutions(indices: np.ndarray, n_solutions: int) -> None:
"""Validate the Decision maker's choice of preferred/non-preferred solutions.
|
desdeo_tools/utilities/quality_indicator.py#L96
Trailing whitespace (W291)
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/interaction/validators.py#L94
if indices.shape[0] < 1:
raise ValidationError("Please specify at least one (non-)preferred solution.")
if not isinstance(indices, (np.ndarray, list)):
raise ValidationError(
- "Please specify index/indices of (non-)preferred solutions in a list, even if there is only "
- "one."
+ "Please specify index/indices of (non-)preferred solutions in a list, even if there is only " "one."
)
if not all(0 <= i <= (n_solutions - 1) for i in indices):
msg = "indices of (non-)preferred solutions should be between 0 and {}. Current indices are {}.".format(
n_solutions - 1, indices
)
raise ValidationError(msg)
-def validate_bounds(
- dimensions_data: pd.DataFrame, bounds: np.ndarray, n_objectives: int
-) -> None:
+def validate_bounds(dimensions_data: pd.DataFrame, bounds: np.ndarray, n_objectives: int) -> None:
"""Validate the Decision maker's desired lower and upper bounds for objective values.
Args:
dimensions_data (pd.DataFrame): DataFrame including information whether an objective is minimized or
maximized, for each objective. In addition, includes ideal and nadir vectors.
|
desdeo_tools/utilities/quality_indicator.py#L97
Trailing whitespace (W291)
|
desdeo_tools/utilities/quality_indicator.py#L101
Line too long (129 > 120 characters) (E501)
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/interaction/validators.py#L122
Raises:
ValidationError: In case desired bounds are invalid.
"""
if not isinstance(bounds, np.ndarray):
- msg = "Please specify bounds as a numpy array. Current type: {}.".format(
- type(bounds)
- )
+ msg = "Please specify bounds as a numpy array. Current type: {}.".format(type(bounds))
raise ValidationError(msg)
if len(bounds) != n_objectives:
- msg = "Length of 'bounds' ({}) must be the same as number of objectives ({}).".format(
- len(bounds), n_objectives
- )
+ msg = "Length of 'bounds' ({}) must be the same as number of objectives ({}).".format(len(bounds), n_objectives)
raise ValidationError(msg)
if not all(isinstance(b, (np.ndarray, list)) for b in bounds):
print(type(bounds[0]))
msg = "Please give bounds for each objective in a list."
raise ValidationError(msg)
|
desdeo_tools/utilities/quality_indicator.py#L104
Trailing whitespace (W291)
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/interaction/validators.py#L144
msg = "Lower bound cannot be greater than upper bound. Please specify lower bound first, then upper bound."
raise ValidationError(msg)
# check that bounds are within ideal and nadir points for each objective
for i, b in enumerate(bounds):
- if (
- dimensions_data.loc["minimize"].values.tolist()[i] == 1
- ): # minimized objectives
+ if dimensions_data.loc["minimize"].values.tolist()[i] == 1: # minimized objectives
if dimensions_data.loc["ideal"].values.tolist()[i] is not None:
if b[0] < dimensions_data.loc["ideal"].values.tolist()[i]:
msg = "Lower bound cannot be lower than ideal value for objective. Ideal vector: {}.".format(
dimensions_data.loc["ideal"].values.tolist()
)
|
desdeo_tools/utilities/quality_indicator.py#L110
Expected 2 blank lines, found 0 (E302)
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/maps/preference_incorporated_space_RP.py#L11
from typing import Type, List, Union, Dict
class PreferenceIncorporatedSpaceError(Exception):
- """Raised when an error related to the preference incorporated space is encountered.
- """
+ """Raised when an error related to the preference incorporated space is encountered."""
class PreferenceIncorporatedSpace:
def __init__(
self,
|
desdeo_tools/utilities/quality_indicator.py#L172
Expected 2 blank lines, found 1 (E302)
|
tests/conftest.py#L9
Blank line contains whitespace (W293)
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/maps/preference_incorporated_space_RP.py#L45
if utopian is not None:
self.utopian = utopian
if nadir is not None:
self.nadir = nadir
- self.initialized_scalarizers = [
- scalarizer(utopian=utopian, nadir=nadir, rho=rho)
- for scalarizer in scalarizers
- ]
+ self.initialized_scalarizers = [scalarizer(utopian=utopian, nadir=nadir, rho=rho) for scalarizer in scalarizers]
self.has_additional_constraints = False
self.constrained_scalarizers = []
for scalarizer in self.initialized_scalarizers:
# self.required_keys = scalarizer.required_keys.keys()
self.constrained_scalarizers.append(scalarizer.has_additional_constraints)
- self.has_additional_constraints = (
- self.has_additional_constraints or scalarizer.has_additional_constraints
- )
+ self.has_additional_constraints = self.has_additional_constraints or scalarizer.has_additional_constraints
def __call__(self, objective_vector: np.ndarray):
- mapped_vectors = np.zeros(
- (len(objective_vector), len(self.initialized_scalarizers))
- )
+ mapped_vectors = np.zeros((len(objective_vector), len(self.initialized_scalarizers)))
for i, scalarizer in enumerate(self.initialized_scalarizers):
mapped_vectors[:, i] = scalarizer(objective_vector, self.preferences[i])
return mapped_vectors
def evaluate_constraints(self, objective_vector: np.ndarray):
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/maps/preference_incorporated_space_RP.py#L81
if not has_constraints:
continue
constraints = np.hstack(
(
constraints,
- scalarizer.evaluate_constraints(
- objective_vector, self.preferences[i]
- ),
+ scalarizer.evaluate_constraints(objective_vector, self.preferences[i]),
)
)
class classificationPIS:
|
tests/conftest.py#L13
Blank line contains whitespace (W293)
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/maps/preference_incorporated_space_RP.py#L132
self.nadir = nadir
self.nimbus = NIMBUS_GLIDE(utopian=utopian, nadir=nadir)
self.nimbus_copycat = reference_point_method_GLIDE(utopian=utopian, nadir=nadir)
- self.initialized_scalarizers = [
- scalarizer(utopian=utopian, nadir=nadir, rho=rho)
- for scalarizer in scalarizers
- ]
+ self.initialized_scalarizers = [scalarizer(utopian=utopian, nadir=nadir, rho=rho) for scalarizer in scalarizers]
self.has_additional_constraints = False
def update_preference(self, preference: dict):
self.preference = preference
if "classifications" in preference.keys():
self.classification_preference = preference
- self.RP_preference = classification_to_reference_point(
- preference, ideal=self.utopian, nadir=self.nadir
- )
+ self.RP_preference = classification_to_reference_point(preference, ideal=self.utopian, nadir=self.nadir)
else:
- raise PreferenceIncorporatedSpaceError(
- "Classification preference expected."
- )
+ raise PreferenceIncorporatedSpaceError("Classification preference expected.")
def __call__(self, objective_vector: np.ndarray):
# IOPIS/NIMBUS logic
- nimbus_obj = self.nimbus(
- objective_vector=objective_vector, preference=self.classification_preference
- )
- nimbus_constraint = self.nimbus.evaluate_constraints(
- objective_vector, self.classification_preference
- )
+ nimbus_obj = self.nimbus(objective_vector=objective_vector, preference=self.classification_preference)
+ nimbus_constraint = self.nimbus.evaluate_constraints(objective_vector, self.classification_preference)
feasible = np.all(nimbus_constraint > 0, axis=1)
if not feasible.any():
nimbus_optimal = objective_vector[nimbus_constraint.max(axis=1).argmax()]
else:
nimbus_obj[~feasible] = np.inf
nimbus_optimal = objective_vector[nimbus_obj.argmin()]
# IOPIS mapping
- mapped_vectors = np.zeros(
- (len(objective_vector), len(self.initialized_scalarizers) + 1)
- )
+ mapped_vectors = np.zeros((len(objective_vector), len(self.initialized_scalarizers) + 1))
mapped_vectors[:, 0] = self.nimbus_copycat(
objective_vector=objective_vector,
preference={"reference point": nimbus_optimal},
)
|
tests/solver/test_scalarsolver.py#L10
Block comment should start with '# ' (E265)
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/maps/preference_incorporated_space_RP.py#L192
num_DM: int = 2,
scalarizer: Type[GLIDEBase] = AUG_STOM_GLIDE,
nadir: np.ndarray = None,
rho: float = 1e-6,
):
- super().__init__(
- scalarizers=[scalarizer] * num_DM, utopian=utopian, nadir=nadir, rho=rho
- )
+ super().__init__(scalarizers=[scalarizer] * num_DM, utopian=utopian, nadir=nadir, rho=rho)
def update_preference(self, preference: List[Dict]):
self.preferences = preference
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/EpsilonConstraintMethod.py#L4
from desdeo_tools.solver.ScalarSolver import ScalarMinimizer
from typing import Optional, Callable, Union
class ECMError(Exception):
- """Raised when an error related to the Epsilon Constraint Method is encountered.
- """
+ """Raised when an error related to the Epsilon Constraint Method is encountered."""
class EpsilonConstraintMethod:
"""A class to represent a class for scalarizing MOO problems using the epsilon
constraint method.
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/EpsilonConstraintMethod.py#L61
if ival != self._to_be_minimized
]
)
if len(epsilon_left_side) != len(self.epsilons):
- msg = (
- "The lenght of the epsilons array ({}) must match the total number of objectives - 1 ({})."
- ).format(len(self.epsilons), len(self.objectives(xs)) - 1)
+ msg = ("The lenght of the epsilons array ({}) must match the total number of objectives - 1 ({}).").format(
+ len(self.epsilons), len(self.objectives(xs)) - 1
+ )
raise ECMError(msg)
# evaluate values of epsilon constraint functions
- e: np.ndarray = np.array(
- [-(f - v) for f, v in zip(epsilon_left_side, self.epsilons)]
- )
+ e: np.ndarray = np.array([-(f - v) for f, v in zip(epsilon_left_side, self.epsilons)])
if self.constraints(xs) is not None:
c = self.constraints(xs)
- return np.concatenate(
- [c, e], axis=None
- ) # does it work with multiple constraints?
+ return np.concatenate([c, e], axis=None) # does it work with multiple constraints?
else:
return e
def __call__(self, objective_vector: np.ndarray) -> Union[float, np.ndarray]:
"""
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/EpsilonConstraintMethod.py#L90
Returns:
Value of objective function to be minimized.
"""
if np.shape(objective_vector)[0] > 1: # more rows than one
- return np.array(
- [
- objective_vector[i][self._to_be_minimized]
- for i, _ in enumerate(objective_vector)
- ]
- )
+ return np.array([objective_vector[i][self._to_be_minimized] for i, _ in enumerate(objective_vector)])
else:
return objective_vector[0][self._to_be_minimized]
# Testing the method
if __name__ == "__main__":
# 1. Define objective functions, bounds and constraints
def volume(r, h):
- return np.pi * r ** 2 * h
+ return np.pi * r**2 * h
def area(r, h):
- return 2 * np.pi ** 2 + np.pi * r * h
+ return 2 * np.pi**2 + np.pi * r * h
# add third objective
def weight(v):
return 0.01 * v
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/EpsilonConstraintMethod.py#L146
# index of which objective function to minimize
obj_min = 2
# set upper bound(s) for the other objectives, in the same order than which corresponding objective functions
# are defined
- epsil = np.array(
- [2000, -100]
- ) # multiply the epsilons with -1, if the constraint is of form f_i(x) >= e_i
+ epsil = np.array([2000, -100]) # multiply the epsilons with -1, if the constraint is of form f_i(x) >= e_i
# create an instance of EpsilonConstraintMethod-class for given problem
eps = EpsilonConstraintMethod(objective, obj_min, epsil, constraints=con_golden)
# constraint evaluator, used by the solver
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/EpsilonConstraintMethod.py#L164
# 3. Solve
# starting point
x0 = np.array([2, 11])
- minimizer = ScalarMinimizer(
- scalarized_objective, bounds, constraint_evaluator=cons_evaluate, method=None
- )
+ minimizer = ScalarMinimizer(scalarized_objective, bounds, constraint_evaluator=cons_evaluate, method=None)
# minimize
res = minimizer.minimize(x0)
final_r, final_h = res["x"][0], res["x"][1]
final_obj = objective(res["x"]).squeeze()
final_V, final_A, final_W = final_obj[0], final_obj[1], final_obj[2]
print(f"Final cake specs: radius: {final_r}cm, height: {final_h}cm.")
- print(
- f"Final cake dimensions: volume: {final_V}, area: {-final_A}, weight: {final_W}."
- )
+ print(f"Final cake dimensions: volume: {final_V}, area: {-final_A}, weight: {final_W}.")
print(final_r / final_h)
print(res)
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/ASF.py#L14
Instances of the implementations of this class should function as
function.
"""
@AbstractMethod
- def __call__(
- self, objective_vector: np.ndarray, reference_point: np.ndarray
- ) -> Union[float, np.ndarray]:
+ def __call__(self, objective_vector: np.ndarray, reference_point: np.ndarray) -> Union[float, np.ndarray]:
"""Evaluate the ASF.
Args:
objective_vectors (np.ndarray): The objective vectors to calculate
the values.
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/ASF.py#L53
"""
def __init__(self, weights: np.ndarray):
self.weights = weights
- def __call__(
- self, objective_vector: np.ndarray, reference_point: np.ndarray
- ) -> Union[float, np.ndarray]:
+ def __call__(self, objective_vector: np.ndarray, reference_point: np.ndarray) -> Union[float, np.ndarray]:
"""Evaluate the simple order-representing ASF.
Args:
objective_vector (np.ndarray): A vector representing a solution in
the solution space.
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/ASF.py#L118
self.preferential_factors = preferential_factors
self.nadir = nadir
self.utopian_point = utopian_point
self.rho = rho
- def __call__(
- self, objective_vector: np.ndarray, reference_point: np.ndarray
- ) -> Union[float, np.ndarray]:
+ def __call__(self, objective_vector: np.ndarray, reference_point: np.ndarray) -> Union[float, np.ndarray]:
mu = self.preferential_factors
f = objective_vector
q = reference_point
rho = self.rho
z_nad = self.nadir
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/ASF.py#L181
self.lt_inds = lt_inds
self.lte_inds = lte_inds
self.rho = rho
self.rho_sum = rho_sum
- def __call__(
- self, objective_vector: np.ndarray, reference_point: np.ndarray
- ) -> Union[float, np.ndarray]:
+ def __call__(self, objective_vector: np.ndarray, reference_point: np.ndarray) -> Union[float, np.ndarray]:
# assure this function works with single objective vectors
if objective_vector.ndim == 1:
f = objective_vector.reshape((1, -1))
else:
f = objective_vector
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/ASF.py#L231
def __init__(self, ideal: np.ndarray, rho: float = 1e-6, rho_sum: float = 1e-6):
self.ideal = ideal
self.rho = rho
self.rho_sum = rho_sum
- def __call__(
- self, objective_vectors: np.ndarray, reference_point: np.ndarray
- ) -> Union[float, np.ndarray]:
+ def __call__(self, objective_vectors: np.ndarray, reference_point: np.ndarray) -> Union[float, np.ndarray]:
# assure this function works with single objective vectors
if objective_vectors.ndim == 1:
f = objective_vectors.reshape((1, -1))
else:
f = objective_vectors
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/ASF.py#L346
nad = self.nadir
uto = self.ideal - self.rho
ex_mask = np.full((f.shape[1]), True, dtype=bool)
ex_mask[self.index_to_exclude] = False
- max_term = np.max(
- (f[:, ex_mask] - nad[ex_mask]) / (nad[ex_mask] - z[ex_mask]), axis=1
- )
- sum_term_1 = self.rho_sum * np.sum(
- (f[:, ex_mask]) / (nad[ex_mask] - z[ex_mask]), axis=1
- )
+ max_term = np.max((f[:, ex_mask] - nad[ex_mask]) / (nad[ex_mask] - z[ex_mask]), axis=1)
+ sum_term_1 = self.rho_sum * np.sum((f[:, ex_mask]) / (nad[ex_mask] - z[ex_mask]), axis=1)
# avoid division by zeros
- sum_term_2 = self.rho_sum * np.sum(
- (f[:, ~ex_mask]) / (nad[~ex_mask] - uto[~ex_mask]), axis=1
- )
+ sum_term_2 = self.rho_sum * np.sum((f[:, ~ex_mask]) / (nad[~ex_mask] - uto[~ex_mask]), axis=1)
return max_term + sum_term_1 + sum_term_2
class GuessASF(ASFBase):
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/ASF.py#L387
return max_term
class AspResASF(ASFBase):
"""Implementation of an ASF using both aspiration and reservation levels.
- directly consider both upper and lower bounds of the preferred ranges within the solution
- generation process, the variant of ASF utilizing both aspirations and reservations levels.
+ directly consider both upper and lower bounds of the preferred ranges within the solution
+ generation process, the variant of ASF utilizing both aspirations and reservations levels.
Originally proposed by Wierzbicki (1986), and also used in the PIE method (Sindhya et al. (2011)).
-
+
Args:
nadir (np.ndarray): The nadir point.
ideal (np.ndarray): The ideal point.
rho A small number to form the utopian point.
rho_sum (float): A small number to be used as a weight for the sum term.
alpha (float): An extricly positive number.
beta(float): An extricly positive number.
-
+
References:
Wierzbicki, A. P.
- On the completeness and constructiveness of parametric characterizations to vector optimization
- problems,
+ On the completeness and constructiveness of parametric characterizations to vector optimization
+ problems,
OR Spektrum, 1986, 8(2), 73–87.
-
+
Sindhya, K., Ruiz, A. B. and Miettinen, K.
A preference based interactive evolutionary algorithm for multi-objective optimization: PIE
- in H. Takahashi, K. Deb, E. Wanner and S. Greco, eds, ‘Evolutionary Multi-Criterion Optimization:
+ in H. Takahashi, K. Deb, E. Wanner and S. Greco, eds, ‘Evolutionary Multi-Criterion Optimization:
6th International Conference’, Proceedings, Springer-Verlag, Berlin, Heidelberg, 2011, pp. 212–225.
"""
def __init__(
self,
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/ASF.py#L464
return max_term + sum_term
class STEM(ASFBase):
"""Implementation of the Step Method (STEM).
-
+
Args:
nadir (np.ndarray): The nadir point.
ideal (np.ndarray): The ideal point.
rho A small number to form the utopian point.
-
+
References:
Benayoun, R., De Montgolfier, J., Tergny, J. and Laritchev, O.
- Linear programming with multiple objective functions: Step method (STEM)’,
+ Linear programming with multiple objective functions: Step method (STEM)’,
Mathematical programming, 1971, 1(1), 366–375.
"""
def __init__(self, nadir: np.ndarray, ideal: np.ndarray, rho: float = 1e-6):
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/interaction/request.py#L215
f"Mismatch in column names of data and dimensions_data.\n"
f"Column names in data: {data.columns}"
f"Column names in dimensions_data: {dimensions_data.columns}"
)
raise RequestError(msg)
- rouge_indices = [
- index
- for index in dimensions_data.index
- if index not in acceptable_dimensions_data_indices
- ]
+ rouge_indices = [index for index in dimensions_data.index if index not in acceptable_dimensions_data_indices]
if rouge_indices:
msg = (
f"dimensions_data should only contain the following indices:\n"
f"{acceptable_dimensions_data_indices}\n"
f"The dataframe provided contains the following unsupported indices:\n"
f"{rouge_indices}"
)
raise RequestError(msg)
if not isinstance(chart_title, (str, type(None))):
- msg = (
- f"Chart title should be a string. Provided chart type is:"
- f"{type(chart_title)}"
- )
+ msg = f"Chart title should be a string. Provided chart type is:" f"{type(chart_title)}"
raise RequestError(msg)
if not isinstance(message, str):
if not isinstance(message, list):
msg = (
f"Message/s to be printed should be string or list of strings"
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/interaction/request.py#L324
msg = (
f"Dimensional data should be in a pandas dataframe.\n"
f"Provided data is of type: {type(dimensions_data)}"
)
raise RequestError(msg)
- rouge_indices = [
- index
- for index in dimensions_data.index
- if index not in acceptable_dimensions_data_indices
- ]
+ rouge_indices = [index for index in dimensions_data.index if index not in acceptable_dimensions_data_indices]
if rouge_indices:
msg = (
f"dimensions_data should only contain the following indices:\n"
f"{acceptable_dimensions_data_indices}\n"
f"The dataframe provided contains the following unsupported indices:\n"
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/interaction/request.py#L375
RequestError: If reference point is not provided in a pandas DataFrame.
"""
if not isinstance(value, pd.DataFrame):
msg = "Reference should be provided in a pandas dataframe format"
raise RequestError(msg)
- self.content["validator"](
- reference_point=value, dimensions_data=self.content["dimensions_data"]
- )
+ self.content["validator"](reference_point=value, dimensions_data=self.content["dimensions_data"])
self._response = value
class PreferredSolutionPreference(BaseRequest):
"""Methods can use this class to ask the Decision maker to provide their preferences
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/MOEADSF.py#L4
from abc import abstractmethod
from typing import Union
class MOEADSFError(Exception):
- """Raised when an error related to the MOEADSF classes is encountered.
- """
+ """Raised when an error related to the MOEADSF classes is encountered."""
class MOEADSFBase(abc.ABC):
"""A base class for representing scalarizing functions for the MOEA/D algorithm.
Instances of the implementations of this class should work as function.
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/MOEADSF.py#L38
"""
pass
class Tchebycheff(MOEADSFBase):
- """Implements the Tchebycheff scalarizing function.
- """
+ """Implements the Tchebycheff scalarizing function."""
def __call__(
self,
objective_vector: np.ndarray,
reference_vector: np.ndarray,
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/MOEADSF.py#L62
Note:
The shaped of objective_vector and reference_vector must match.
"""
if not objective_vector.shape == reference_vector.shape:
- msg = (
- "The dimensions of the objective vector {} and "
- "reference_vector {} do not match."
- ).format(objective_vector.shape, reference_vector.shape)
+ msg = ("The dimensions of the objective vector {} and " "reference_vector {} do not match.").format(
+ objective_vector.shape, reference_vector.shape
+ )
raise MOEADSFError(msg)
feval = np.abs(objective_vector - ideal_vector) * reference_vector
max_fun = np.max(feval)
return max_fun
class WeightedSum(MOEADSFBase):
- """Implements the Weighted sum scalarization function
- """
+ """Implements the Weighted sum scalarization function"""
- def __call__(
- self, objective_vector: np.ndarray, reference_vector: np.ndarray
- ) -> Union[float, np.ndarray]:
+ def __call__(self, objective_vector: np.ndarray, reference_vector: np.ndarray) -> Union[float, np.ndarray]:
"""Evaluate the WeightedSum scalarizing function.
Args:
objective_vector (np.ndarray): A vector representing a solution in
the objective space.
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/MOEADSF.py#L94
Note:
The shaped of objective_vector and reference_vector must match. A reference point is not needed.
"""
if not objective_vector.shape == reference_vector.shape:
- msg = (
- "The dimensions of the objective vector {} and "
- "reference_vector {} do not match."
- ).format(objective_vector.shape, reference_vector.shape)
+ msg = ("The dimensions of the objective vector {} and " "reference_vector {} do not match.").format(
+ objective_vector.shape, reference_vector.shape
+ )
raise MOEADSFError(msg)
feval = np.sum(objective_vector * reference_vector)
return feval
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/MOEADSF.py#L141
Note:
The shaped of objective_vector and reference_vector must match. The reference point is not needed.
"""
if not objective_vector.shape == reference_vector.shape:
- msg = (
- "The dimensions of the objective vector {} and "
- "reference_vector {} do not match."
- ).format(objective_vector.shape, reference_vector.shape)
+ msg = ("The dimensions of the objective vector {} and " "reference_vector {} do not match.").format(
+ objective_vector.shape, reference_vector.shape
+ )
raise MOEADSFError(msg)
norm_weights = np.linalg.norm(reference_vector)
weights = np.true_divide(reference_vector, norm_weights)
fx_a = objective_vector - ideal_vector
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/Scalarizer.py#L54
res_scal = self._scalarizer(res_eval)
return res_scal
def __call__(self, xs: np.ndarray) -> np.ndarray:
- """Wrapper to the evaluate method.
- """
+ """Wrapper to the evaluate method."""
return self.evaluate(xs)
class DiscreteScalarizer:
- """Implements a class to scalarize discrete vectors given a scalarizing function.
- """
+ """Implements a class to scalarize discrete vectors given a scalarizing function."""
def __init__(self, scalarizer: Callable, scalarizer_args: Dict = None):
self._scalarizer = scalarizer
self._scalarizer_args = scalarizer_args
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/scalarization/Scalarizer.py#L85
if __name__ == "__main__":
vectors = np.array([[1, 1, 1], [2, 2, 2], [4, 5, 6.0]])
vector = np.array([1, 2, 3])
- dscalarizer = DiscreteScalarizer(
- lambda x, a=1: a * np.sum(x, axis=1), scalarizer_args={"a": 2}
- )
+ dscalarizer = DiscreteScalarizer(lambda x, a=1: a * np.sum(x, axis=1), scalarizer_args={"a": 2})
res = dscalarizer(vectors)
res_1d = dscalarizer(vector)
print(res)
print(res_1d)
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/utilities/pmod.py#L38
distance = 0
size = len(mapping_point)
pp_size = len(pref_point)
for j in range(0, size):
for i in range(0, pp_size):
- distance += (mapping_point[j][i] - pref_point[i]) * (
- mapping_point[j][i] - pref_point[i]
- )
+ distance += (mapping_point[j][i] - pref_point[i]) * (mapping_point[j][i] - pref_point[i])
sum_ += sqrt(distance)
return sum_ / distance
def dist_vector(vec1, vec2):
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/utilities/pmod.py#L78
distance = temp
dist.append(distance)
average = sum(dist) / len(dist)
for i in range(0, size):
temp = average - dist[i]
- sum_ += temp ** 2
+ sum_ += temp**2
return sqrt(sum_ / (size - 1))
def distan_d3(
ref_point: np.ndarray,
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/utilities/lattice_generators.py#L76
Returns:
np.ndarray: The lattice of points as a 2-D (num_points, num_dimensions) numpy array.
"""
- number_of_vectors = comb(
- lattice_resolution + num_dimensions - 1, num_dimensions - 1, exact=True
- )
+ number_of_vectors = comb(lattice_resolution + num_dimensions - 1, num_dimensions - 1, exact=True)
temp1 = range(1, num_dimensions + lattice_resolution)
temp1 = np.array(list(combinations(temp1, num_dimensions - 1)))
temp2 = np.array([range(num_dimensions - 1)] * number_of_vectors)
temp = temp1 - temp2 - 1
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/utilities/lattice_generators.py#L93
weight[:, -1] = lattice_resolution - temp[:, -1]
return weight / lattice_resolution
-def simplexLatticefromNumPoints(
- num_dimensions: int, num_points: int, atleast: bool = False
-) -> np.ndarray:
+def simplexLatticefromNumPoints(num_dimensions: int, num_points: int, atleast: bool = False) -> np.ndarray:
"""Create a simplex lattice design with the given number of points. The generated lattice is on the unit
hyperplane, and the points are distributed in the positive orthant. See more information at:
https://www.itl.nist.gov/div898/handbook/pri/section5/pri542.htm
The lattice is generated by first finding the largest lattice resolution that can generate a lattice with the
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/utilities/lattice_generators.py#L117
np.ndarray: The lattice of points as a 2-D (num_points, num_dimensions) numpy array.
"""
temp_lattice_resolution = 0
while True:
temp_lattice_resolution += 1
- number_of_vectors = comb(
- temp_lattice_resolution + num_dimensions - 1, num_dimensions - 1, exact=True
- )
+ number_of_vectors = comb(temp_lattice_resolution + num_dimensions - 1, num_dimensions - 1, exact=True)
if number_of_vectors > num_points:
break
if atleast:
return simplexLatticeDesign(num_dimensions, temp_lattice_resolution)
return simplexLatticeDesign(num_dimensions, temp_lattice_resolution - 1)
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/utilities/preference_converters.py#L1
"""Provides implementations that convert one type of preference information to another."""
import numpy as np
-def classification_to_reference_point(
- classification_preference: dict, ideal: np.ndarray, nadir: np.ndarray
-) -> dict:
+def classification_to_reference_point(classification_preference: dict, ideal: np.ndarray, nadir: np.ndarray) -> dict:
"""Convert classification type of preference (e.g. NIMBUS) to reference point
preference.
Args:
classification_preference (dict): A dict containing keys 'current solution',
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/utilities/preference_converters.py#L19
dict: The preference in the form of a reference point. Contains one key:
"reference point", which maps to the preference in a numpy array structure.
"""
z_bar = np.zeros_like(nadir, dtype=float)
- improve_inds = np.where(
- np.array(classification_preference["classifications"]) == "<"
- )[0]
- acceptable_inds = np.where(
- np.array(classification_preference["classifications"]) == "="
- )[0]
- free_inds = np.where(np.array(classification_preference["classifications"]) == "0")[
- 0
- ]
- improve_until_inds = np.where(
- np.array(classification_preference["classifications"]) == "<="
- )[0]
- impaire_until_inds = np.where(
- np.array(classification_preference["classifications"]) == ">="
- )[0]
+ improve_inds = np.where(np.array(classification_preference["classifications"]) == "<")[0]
+ acceptable_inds = np.where(np.array(classification_preference["classifications"]) == "=")[0]
+ free_inds = np.where(np.array(classification_preference["classifications"]) == "0")[0]
+ improve_until_inds = np.where(np.array(classification_preference["classifications"]) == "<=")[0]
+ impaire_until_inds = np.where(np.array(classification_preference["classifications"]) == ">=")[0]
z_bar[improve_inds] = ideal[improve_inds]
z_bar[improve_until_inds] = classification_preference["levels"][improve_until_inds]
- z_bar[acceptable_inds] = classification_preference["current solution"][
- acceptable_inds
- ]
+ z_bar[acceptable_inds] = classification_preference["current solution"][acceptable_inds]
z_bar[impaire_until_inds] = classification_preference["levels"][impaire_until_inds]
z_bar[free_inds] = nadir[free_inds]
return {"reference point": z_bar}
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/solver/ScalarSolver.py#L23
class ScalarMethod:
"""A class the define and implement methods for minimizing scalar valued functions."""
- def __init__(
- self, method: Callable, method_args=None, use_scipy: Optional[bool] = False
- ):
+ def __init__(self, method: Callable, method_args=None, use_scipy: Optional[bool] = False):
"""
Args:
method (Callable): A callable minimizer function which expects a
callable scalar valued function to be minimized. The function should
accept as its first argument a two dimensional numpy array and should
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/solver/ScalarSolver.py#L80
bounds=bounds,
constraints=constraint_evaluator,
**self._method_args,
)
else:
- res = self._method(
- obj_fun, x0, bounds=bounds, constraints=constraint_evaluator
- )
+ res = self._method(obj_fun, x0, bounds=bounds, constraints=constraint_evaluator)
return res
class MixedIntegerMinimizer:
-
"""Implements methods for solving scalar valued functions.
Args:
scalarized_objective (Callable): The objective function that has been scalarized
and ready for minimization.
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/solver/ScalarSolver.py#L113
self.scalarized_objective = scalarized_objective
self.problem = problem
self.lower_bounds = [var.get_bounds()[0] for var in self.problem.variables]
self.upper_bounds = [var.get_bounds()[1] for var in self.problem.variables]
var_types = np.array(
- [
- "I" if var.type.lower() in ["i", "integervariable", "integer"] else "R"
- for var in problem.variables
- ]
+ ["I" if var.type.lower() in ["i", "integervariable", "integer"] else "R" for var in problem.variables]
)
self.var_types = var_types
self.minlp_solver_path = minlp_solver_path
print("Scalarized objectives: ", self.scalarized_objective)
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/solver/ScalarSolver.py#L211
self.problem = problem
self._constraint_evaluator = constraint_evaluator
if method is None or method == "MixedIntegerMinimizer":
# Check if problem contains integer variables
- integer_vars = any(
- [
- var.type.lower() in ["i", "integervariable", "integer"]
- for var in problem.variables
- ]
- )
+ integer_vars = any([var.type.lower() in ["i", "integervariable", "integer"] for var in problem.variables])
if integer_vars:
# Use MixedIntegerMinimizer if integer variables are found
minlp_solver_path = kwargs.get("minlp_solver_path", None)
if minlp_solver_path is None:
raise ValueError(
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/solver/ScalarSolver.py#L228
)
self._use_scipy = False
self._mixed_integer_minimizer = MixedIntegerMinimizer(
self._scalarizer, problem, minlp_solver_path=minlp_solver_path
)
- self._method = ScalarMethod(
- lambda x, _, **y: self._mixed_integer_minimizer.minimize(x, **y)
- )
+ self._method = ScalarMethod(lambda x, _, **y: self._mixed_integer_minimizer.minimize(x, **y))
elif (method is None) or (method == "scipy_minimize"):
# scipy minimize
self._use_scipy = True
# Assuming the gradient reqruies evaluation of the
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/solver/ScalarSolver.py#L354
min_index = np.nanargmin(res)
return {"x": min_index, "fun": min_value, "success": True}
else:
bad_con_mask = ~self._constraint_evaluator(vectors)
if np.all(bad_con_mask):
- raise ScalarSolverException(
- "None of the supplied vectors adhere to the given "
- "constraint function."
- )
+ raise ScalarSolverException("None of the supplied vectors adhere to the given " "constraint function.")
tmp = np.copy(vectors)
tmp[bad_con_mask] = np.nan
res = self._scalarizer(tmp)
min_value = np.nanmin(res)
min_index = np.nanargmin(res)
|
/home/runner/work/desdeo-tools/desdeo-tools/tests/conftest.py#L4
@pytest.fixture
def SimpleVectorValuedFunction(xs: np.ndarray):
"""A simple vector valued function for testing.
-
+
Args:
xs (np.ndarray): A 2D numpy array with argument vectors as its rows.
Each vector consists of four values.
-
+
Returns:
np.ndarray: A 2D array with function evaluation results for each of
the argument vectors on its rows. Each row contains three values.
"""
f1 = xs[:, 0] + xs[:, 1]
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/utilities/polytopes.py#L5
from typing import Optional
from scipy.optimize import linprog
-def inherently_nondominated(
- A: np.ndarray, epsilon: Optional[float] = 1e-06, method: Optional[str] = "highs"
-) -> bool:
+def inherently_nondominated(A: np.ndarray, epsilon: Optional[float] = 1e-06, method: Optional[str] = "highs") -> bool:
"""Check if a polytope is inherently nondominated:
A polytope is inherently nondominated iff the polytope does not dominate itself.
Args:
A (np.ndarray): A polytope to be checked.
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/utilities/polytopes.py#L61
A2 = np.hstack((np.zeros((1, 1)), np.ones((1, a)), np.zeros((1, b))))
A3 = np.hstack((np.zeros((1, 1)), np.zeros((1, a)), np.ones((1, b))))
A_ub = np.vstack((A1, np.zeros((2, a + b + 1))))
b_ub = np.zeros(k + 2)
- A_eq = np.vstack(
- (np.zeros((k, a + b + 1)), A2, A3)
- ) # Add k rows for correct size, will be ignored
+ A_eq = np.vstack((np.zeros((k, a + b + 1)), A2, A3)) # Add k rows for correct size, will be ignored
b_eq = np.hstack((np.zeros(k), np.ones(2)))
res = linprog(coef, A_ub, b_ub, A_eq, b_eq, bounds, method=method)
if not res["success"]:
|
/home/runner/work/desdeo-tools/desdeo-tools/desdeo_tools/utilities/polytopes.py#L121
for j in range(2, b + 1):
# All combinations of size j from row i
addition = np.array(list(itertools.combinations(simplices[i], j)))
# Add all combinations to F, so that we repeat the value at index 0 until enough values
chunks = addition[:, 0].shape[0] # How many chunks to split into
- repeated = np.split(
- np.repeat(addition[:, 0], b - j), chunks
- ) # Repeat the values at index 0
+ repeated = np.split(np.repeat(addition[:, 0], b - j), chunks) # Repeat the values at index 0
addition = np.hstack((addition, repeated)) # Add the repeated values
F = np.vstack((F, addition)) # Add new rows to F
# F(F(:,1)==0,:) = []; ?
return np.unique(F, axis=0).astype(int)
|
Run linters
Process completed with exit code 1.
|
Run linters
Node.js 16 actions are deprecated. Please update the following actions to use Node.js 20: actions/checkout@v2, actions/setup-python@v1, wearerequired/lint-action@v1, actions/checkout@v3. For more information see: https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/.
|
Run linters
The following actions uses node12 which is deprecated and will be forced to run on node16: actions/checkout@v2, actions/setup-python@v1, wearerequired/lint-action@v1. For more info: https://github.blog/changelog/2023-06-13-github-actions-all-actions-will-run-on-node16-instead-of-node12-by-default/
|
Run linters
Unexpected input(s) 'isort', 'isort_args', valid inputs are ['github_token', 'continue_on_error', 'auto_fix', 'git_no_verify', 'git_name', 'git_email', 'commit_message', 'check_name', 'neutral_check_on_warning', 'stylelint', 'stylelint_args', 'stylelint_dir', 'stylelint_extensions', 'stylelint_command_prefix', 'gofmt', 'gofmt_args', 'gofmt_dir', 'gofmt_extensions', 'gofmt_command_prefix', 'golint', 'golint_args', 'golint_dir', 'golint_extensions', 'golint_command_prefix', 'eslint', 'eslint_args', 'eslint_dir', 'eslint_extensions', 'eslint_command_prefix', 'prettier', 'prettier_args', 'prettier_dir', 'prettier_extensions', 'prettier_command_prefix', 'xo', 'xo_args', 'xo_dir', 'xo_extensions', 'xo_command_prefix', 'php_codesniffer', 'php_codesniffer_args', 'php_codesniffer_dir', 'php_codesniffer_extensions', 'php_codesniffer_command_prefix', 'black', 'black_args', 'black_dir', 'black_extensions', 'black_command_prefix', 'flake8', 'flake8_args', 'flake8_dir', 'flake8_extensions', 'flake8_command_prefix', 'mypy', 'mypy_args', 'mypy_dir', 'mypy_extensions', 'mypy_command_prefix', 'oitnb', 'oitnb_args', 'oitnb_dir', 'oitnb_extensions', 'oitnb_command_prefix', 'rubocop', 'rubocop_args', 'rubocop_dir', 'rubocop_extensions', 'rubocop_command_prefix', 'erblint', 'erblint_args', 'erblint_dir', 'erblint_extensions', 'erblint_command_prefix', 'swiftformat', 'swiftformat_args', 'swiftformat_dir', 'swiftformat_extensions', 'swiftformat_command_prefix', 'swift_format_lockwood', 'swift_format_lockwood_args', 'swift_format_lockwood_dir', 'swift_format_lockwood_extensions', 'swift_format_lockwood_command_prefix', 'swift_format_official', 'swift_format_official_args', 'swift_format_official_dir', 'swift_format_official_extensions', 'swift_format_official_command_prefix', 'swiftlint', 'swiftlint_args', 'swiftlint_dir', 'swiftlint_extensions', 'swiftlint_command_prefix', 'dotnet_format', 'dotnet_format_args', 'dotnet_format_dir', 'dotnet_format_extensions', 'dotnet_format_command_prefix']
|