desdeo_mcdm.interactive

This module contains interactive methods and related requests implemented as classes.

Submodules

Package Contents

Classes

ParetoNavigator

Paretonavigator as described in 'Pareto navigator for interactive nonlinear

ParetoNavigatorInitialRequest

A request class to handle the Decision Maker's initial preferences for the first iteration round.

ParetoNavigatorRequest

A request class to handle navigation preferences after the first iteration round.

ParetoNavigatorSolutionRequest

A request class to handle requests to see pareto optimal solution.

ParetoNavigatorStopRequest

A request class to handle termination.

ENautilus

The base class for interactive methods.

ENautilusInitialRequest

A request class to handle the initial preferences.

ENautilusRequest

A request class to handle the intermediate requests.

ENautilusStopRequest

A request class to handle termination.

Nautilus

Implements the basic NAUTILUS method as presented in |Miettinen_2010|.

NautilusV2

Implements the NAUTILUS 2 method as presented in |Miettinen_2015|.

NautilusInitialRequest

A request class to handle the Decision maker's initial preferences for the first iteration round.

NautilusRequest

A request class to handle the Decision maker's preferences after the first iteration round.

NautilusStopRequest

A request class to handle termination.

NautilusNavigator

NautilusNavigatorRequest

Request to handle interactions with NAUTILUS Navigator. See the

NIMBUS

NimbusClassificationRequest

A request to handle the classification of objectives in the synchronous NIMBUS method.

NimbusIntermediateSolutionsRequest

A request to handle the computation of intermediate points between two previously computed points.

NimbusMostPreferredRequest

A request to handle the indication of a preferred point.

NimbusSaveRequest

A request to handle archiving of the solutions computed with NIMBUS.

NimbusStopRequest

A request to handle the termination of Synchronous NIMBUS.

RPMInitialRequest

A request class to handle the Decision Maker's initial preferences for the first iteration round.

RPMRequest

A request class to handle the Decision Maker's preferences after the first iteration round.

RPMStopRequest

A request class to handle termination.

ReferencePointMethod

Implements the Reference Point Method as presented in |Wierzbicki_1982|.

Functions

validate_preferences(→ None)

Validate decision maker's preferences.

validate_response(→ None)

Validate decision maker's response.

validate_n2_preferences(→ None)

Validate decision maker's preferences in NAUTILUS 2.

validate_n_iterations(→ None)

Validate decision maker's preference for number of iterations.

class desdeo_mcdm.interactive.ParetoNavigator(problem: desdeo_problem.problem.MOProblem | desdeo_problem.problem.DiscreteDataProblem, pareto_optimal_solutions: numpy.ndarray | None = None, scalar_method: desdeo_tools.solver.ScalarSolver.ScalarMethod | None = None)[source]

Bases: desdeo_mcdm.interactive.InteractiveMethod.InteractiveMethod

Paretonavigator as described in ‘Pareto navigator for interactive nonlinear multiobjective optimization’ (2008) [Petri Eskelinen · Kaisa Miettinen · Kathrin Klamroth · Jussi Hakanen].

Parameters:
  • problem (MOProblem) – The problem to be solved.

  • pareto_optimal_solutions (np.ndarray) – Some pareto optimal solutions to construct the polyhedral set.

  • scalar_method – (Optional[ScalarMethod], optional): The scalar method used to solve asf

Note

pareto_optimal_solutions must be provided for problems of type MOProblem.

For DiscreteDataProblems if no pareto optimal solutions are provided the method will use the objective values from the problem.

start()

Start the solving process

Returns:

Initial request

Return type:

ParetoNavigatorInitialRequest

iterate(request: ParetoNavigatorInitialRequest | ParetoNavigatorRequest | ParetoNavigatorSolutionRequest | ParetoNavigatorStopRequest) ParetoNavigatorRequest | ParetoNavigatorSolutionRequest | ParetoNavigatorStopRequest

Perform the next logical iteration step based on the given request type.

Parameters:
  • (Union[ParetoNavigatorInitialRequest (request) – ParetoNavigatorSolutionRequest, ParetoNavigatorStopRequest]): A ParetoNavigatorRequest

  • ParetoNavigatorRequest – ParetoNavigatorSolutionRequest, ParetoNavigatorStopRequest]): A ParetoNavigatorRequest

:paramParetoNavigatorSolutionRequest, ParetoNavigatorStopRequest]):

A ParetoNavigatorRequest

Returns:

A new request with content depending on the Decision Maker’s preferences.

Return type:

Union[ParetoNavigatorRequest, ParetoNavigatorSolutionRequest, ParetoNavigatorStopRequest]

handle_initial_request(request: ParetoNavigatorInitialRequest) ParetoNavigatorRequest

Handles the initial request.

Parameters:

request (ParetoNavigatorInitialRequest) – Initial request

Returns:

A navigation request

Return type:

ParetoNavigatorRequest

handle_request(request: ParetoNavigatorRequest) ParetoNavigatorRequest | ParetoNavigatorSolutionRequest | ParetoNavigatorStopRequest

Handles a navigation request.

Parameters:

request (ParetoNavigatorRequest) – A request

Returns:

Next request corresponding the DM’s preferences

Return type:

Union[ParetoNavigatorRequest, ParetoNavigatorSolutionRequest, ParetoNavigatorStopRequest]

handle_solution_request(request: ParetoNavigatorSolutionRequest) ParetoNavigatorRequest | ParetoNavigatorStopRequest

Handle a solution request

Parameters:

request (ParetoNavigatorSolutionRequest) – A solution request

Returns:

A navigation request or a stop request depending on whether the DM wishes to continue or stop

Return type:

Union[ParetoNavigatorRequest, ParetoNavigatorStopRequest]

calculate_extremes(points: numpy.ndarray) Tuple[numpy.ndarray, numpy.ndarray]

Calculate the minimum and maximum points of a given array.

Parameters:

points (np.ndarray) – A two dimensional array

Returns:

The min and max values of each column

Return type:

Tuple[np.ndarray, np.ndarray]

calculate_speed(given_speed: int) float

Calculate a speed value from given integer value.

Parameters:

given_speed (int) – a speed value where 1 is slowest and 5 fastest

Returns:

A speed value calculated from given integer value.

Is between 0 and 1

Return type:

float

Note

The denominator 10 is not mentioned in the article, but it is included because the navigation speed seems to be too fast without it.

calculate_weights(ideal: numpy.ndarray, nadir: numpy.ndarray)

Calculate the scaling coefficients w from ideal and nadir.

Parameters:
  • ideal (np.ndarray) – Ideal vector

  • nadir (np.ndarray) – Nadir vector

Returns:

The scaling coefficients

Return type:

np.ndarray

polyhedral_set_eq(po_solutions: numpy.ndarray) Tuple[numpy.ndarray, numpy.ndarray]

Construct a polyhedral set as convex hull from the set of pareto optimal solutions

Parameters:

po_solutions (np.ndarray) – Some pareto optimal solutions

Returns:

Matrix A and vector b from the

convex hull inequality representation Az <= b

Return type:

Tuple[np.ndarray, np.ndarray]

construct_lppp_A(weights, A)

The matrix A used in the linear parametric programming problem

Parameters:
  • weights (np.ndarray) – Scaling coefficients

  • A (np.ndarray) – Matrix A from the convex hull representation Ax < b

Returns:

The matrix A’ in the linear parametric programming problem A’x<b’

Return type:

np.ndarray

calculate_direction(current_solution: numpy.ndarray, ref_point: numpy.ndarray)

Calculate a new direction from current solution and a given reference point

Parameters:
  • current_solution (np.ndarray) – The current solution

  • ref_point (np.ndarray) – A reference point

Returns:

A new direction

Return type:

np.ndarray

classification_to_ref_point(classifications, ideal, nadir, current_solution)

Transform classifications to a reference point

Parameters:
  • classifications (np.ndarray) – Classification for each objective

  • ideal (np.ndarray) – Ideal point

  • nadir (np.ndarray) – Nadir point

  • current_solution (np.ndarray) – Current solution

Returns:

A reference point which is constructed from the classifications

Return type:

np.ndarray

solve_linear_parametric_problem(current_sol: numpy.ndarray, ideal: numpy.ndarray, nadir: numpy.ndarray, direction: numpy.ndarray, a: float, A: numpy.ndarray, b: numpy.ndarray) numpy.ndarray

Solves the linear parametric programming problem as defined in (3)

Parameters:
  • current_sol (np.ndarray) – Current solution

  • ideal (np.ndarray) – Ideal vector

  • nadir (np.ndarray) – Nadir vector

  • direction (np.ndarray) – Navigation direction

  • a (float) – Alpha in problem (3)

  • A (np.ndarray) – Matrix A from Az <= b

  • b (np.ndarray) – Vector b from Az <= b

Returns:

Optimal vector from the linear parametric programming problem.

This is the new solution to be used in the navigation.

Return type:

np.ndarray

solve_asf(problem: desdeo_problem.problem.MOProblem | desdeo_problem.problem.DiscreteDataProblem, ref_point: numpy.ndarray, method: desdeo_tools.solver.ScalarSolver.ScalarMethod | None = None)

Solve the achievement scalarizing function

Parameters:
  • problem (MOProblem) – The problem

  • ref_point – A reference point

  • method (Optional[ScalarMethod], optional) – A method provided to the scalar minimizer

Returns:

The decision vector which solves the achievement scalarizing function

Return type:

np.ndarray

exception desdeo_mcdm.interactive.ParetoNavigatorException[source]

Bases: Exception

Raised when an exception related to Pareto Navigator is encountered.

class desdeo_mcdm.interactive.ParetoNavigatorInitialRequest(ideal: numpy.ndarray, nadir: numpy.ndarray, allowed_speeds: numpy.ndarray, po_solutions: numpy.ndarray)[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request class to handle the Decision Maker’s initial preferences for the first iteration round.

Parameters:
  • ideal (np.ndarray) – Ideal vector

  • nadir (np.ndarray) – Nadir vector

  • allowed_speeds (np.ndarray) – Allowed movement speeds

  • po_solutions – (np.ndarray): A set of pareto optimal solutions

msg = Please specify a starting point as 'preferred_solution'.

Or specify a reference point as ‘reference_point’.

classmethod init_with_method(method: desdeo_mcdm.interactive.InteractiveMethod.InteractiveMethod)

Initialize request with given instance of ParetoNavigator.

Parameters:

method (ParetoNavigator) – Instance of ReferencePointMethod-class.

Returns:

Initial request.

Return type:

ParetoNavigatorInitialRequest

class desdeo_mcdm.interactive.ParetoNavigatorRequest(current_solution: numpy.ndarray, ideal: numpy.ndarray, nadir: numpy.ndarray, allowed_speeds: numpy.ndarray, valid_classifications: numpy.ndarray)[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request class to handle navigation preferences after the first iteration round.

Parameters:
  • current_solution (np.ndarray) – Current solution.

  • ideal (np.ndarray) – Ideal vector.

  • nadir (np.ndarray) – Nadir vector.

  • allowed_speeds (np.ndarray) – Allowed movement speeds

  • valid_classifications (np.ndarray) – Valid classifications

classmethod init_with_method(method: desdeo_mcdm.interactive.InteractiveMethod.InteractiveMethod)

Initialize request with given instance of ParetoNavigator.

Parameters:

method (ParetoNavigator) – Instance of ParetoNavigator-class.

Returns:

Initial request.

Return type:

ParetoNavigatorRequest

class desdeo_mcdm.interactive.ParetoNavigatorSolutionRequest(approx_solution: numpy.ndarray, pareto_optimal_solution: numpy.ndarray, objective_values: numpy.ndarray)[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request class to handle requests to see pareto optimal solution.

Parameters:
  • approx_solution (np.ndarray) – The approximated solution received by navigation

  • pareto_optimal_solution (np.ndarray) – A pareto optimal solution (decision variables).

  • objective_values (np.ndarray) – Objective vector.

class desdeo_mcdm.interactive.ParetoNavigatorStopRequest(approx_solution: numpy.ndarray, final_solution: numpy.ndarray, objective_values: numpy.ndarray)[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request class to handle termination.

Parameters:
  • approx_solution (np.ndarray) – The approximated solution received by navigation.

  • final_solution (np.ndarray) – Solution (decision variables).

  • objective_values (np.ndarray) – Objective values.

class desdeo_mcdm.interactive.ENautilus(pareto_front: numpy.ndarray, ideal: numpy.ndarray, nadir: numpy.ndarray, objective_names: List[str] | None = None, variables: numpy.ndarray | None = None)[source]

Bases: desdeo_mcdm.interactive.InteractiveMethod.InteractiveMethod

The base class for interactive methods.

Parameters:

problem (MOProblem) – The problem being solved in an interactive method.

start() ENautilusInitialRequest
iterate(request: ENautilusInitialRequest | ENautilusRequest) ENautilusRequest | ENautilusStopRequest

Perform the next logical iteration step based on the given request type.

handle_initial_request(request: ENautilusInitialRequest) ENautilusRequest

Handles the initial request by parsing the response appropriately.

handle_request(request: ENautilusRequest) ENautilusRequest | ENautilusStopRequest

Handles the intermediate requests.

calculate_representative_points(pareto_front: numpy.ndarray, subset_indices: List[int], n_points: int) numpy.ndarray

Calculates the most representative points on the Pareto front. The points are clustered using k-means.

Parameters:
  • pareto_front (np.ndarray) – The Pareto front.

  • subset_indices (List[int]) – A list of indices representing the subset of the points on the Pareto front for which the representative points should be calculated.

  • n_points (int) – The number of representative points to be calculated.

Returns:

A 2D array of the most representative points. If the

subset of Pareto efficient points is less than n_points, returns the subset of the Pareto front.

Return type:

np.ndarray

calculate_intermediate_points(preferred_point: numpy.ndarray, zbars: numpy.ndarray, n_iterations_left: int) numpy.ndarray

Calculates the intermediate points between representative points an a preferred point.

Parameters:
  • preferred_point (np.ndarray) – The preferred point, 1D array.

  • zbars (np.ndarray) – The representative points, 2D array.

  • n_iterations_left (int) – The number of iterations left.

Returns:

The intermediate points as a 2D array.

Return type:

np.ndarray

calculate_bounds(pareto_front: numpy.ndarray, intermediate_points: numpy.ndarray) Tuple[numpy.ndarray, numpy.ndarray]

Calculate the new bounds of the reachable points on the Pareto optimal front from each of the intermediate points.

Parameters:
  • pareto_front (np.ndarray) – The Pareto optimal front.

  • intermediate_points (np.ndarray) – The current intermediate points as a 2D array.

Returns:

The lower and upper bounds for each of the intermediate points.

Return type:

Tuple[np.ndarray, np.ndarray]

calculate_distances(intermediate_points: numpy.ndarray, zbars: numpy.ndarray, nadir: numpy.ndarray) numpy.ndarray
calculate_reachable_point_indices(pareto_front: numpy.ndarray, lower_bounds: numpy.ndarray, upper_bounds: numpy.ndarray) List[int]

Calculate the indices of the reachable Pareto optimal solutions based on lower and upper bounds.

Returns:

List of the indices of the reachable solutions.

Return type:

List[int]

exception desdeo_mcdm.interactive.ENautilusException[source]

Bases: Exception

Raised when an exception related to ENautilus is encountered.

class desdeo_mcdm.interactive.ENautilusInitialRequest(ideal: numpy.ndarray, nadir: numpy.ndarray)[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request class to handle the initial preferences.

validator(response: Dict) None
classmethod init_with_method(method)
class desdeo_mcdm.interactive.ENautilusRequest(ideal: numpy.ndarray, nadir: numpy.ndarray, points: numpy.ndarray, lower_bounds: numpy.ndarray, upper_bounds: numpy.ndarray, n_iterations_left: int, distances: numpy.ndarray)[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request class to handle the intermediate requests.

validator(response: Dict) None
class desdeo_mcdm.interactive.ENautilusStopRequest(preferred_point: numpy.ndarray, solution: numpy.ndarray | None = None)[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request class to handle termination.

desdeo_mcdm.interactive.validate_preferences(n_objectives: int, response: Dict) None[source]

Validate decision maker’s preferences.

Parameters:
  • n_objectives (int) – Number of objectives in problem.

  • response (Dict) – Decision maker’s response containing preference information.

Raises:

NautilusException – In case preference info is not valid.

class desdeo_mcdm.interactive.Nautilus(problem: desdeo_problem.problem.MOProblem, ideal: numpy.ndarray, nadir: numpy.ndarray, epsilon: float = 1e-06, objective_names: List[str] | None = None, minimize: List[int] | None = None)[source]

Bases: desdeo_mcdm.interactive.InteractiveMethod.InteractiveMethod

Implements the basic NAUTILUS method as presented in |Miettinen_2010|.

In NAUTILUS, starting from the nadir point, a solution is obtained at each iteration which dominates the previous one. Although only the last solution will be Pareto optimal, the decision maker never looses sight of the Pareto optimal set, and the search is oriented so that (s)he progressively focusses on the preferred part of the Pareto optimal set. Each new solution is obtained by minimizing an achievement scalarizing function including preferences about desired improvements in objective function values.

The decision maker has two possibilities to provide her/his preferences:

1. The decision maker can rank the objectives according to the relative importance of improving each current objective value.

Note

This ranking is not a global preference ranking of the objectives, but represents the local importance of improving each of the current objective values at that moment.

2. The decision maker can specify percentages reflecting how (s)he would like to improve the current objective values, by answering to the following question:

“Assuming you have one hundred points available, how would you distribute them among the current objective values so that the more points you allocate, the more improvement on the corresponding current objective value is desired?”

After each iteration round, the decision maker specifies whether (s)he wishes to continue with the previous preference information, or define a new one.

In addition to this, the decision maker can influence the solution finding process by taking a step back to previous iteration point. This enables the decision maker to provide new preferences and change the direction of solution seeking process. Furthermore, the decision maker can also take a half-step in case (s)he feels that a full step limits the reachable area of Pareto optimal set too much.

NAUTILUS is specially suitable for avoiding undesired anchoring effects, for example in negotiation support problems, or just as a means of finding an initial Pareto optimal solution for any interactive procedure.

Parameters:
  • problem (MOProblem) – Problem to be solved.

  • ideal (np.ndarray) – The ideal objective vector of the problem.

  • nadir (np.ndarray) – The nadir objective vector of the problem. This may also be the “worst” objective vector provided by the Decision maker if the approximation of Nadir vector is not applicable or if the Decision maker wishes to provide even worse objective vector than what the approximated Nadir vector is.

  • epsilon (float) – A small number used in calculating the utopian point.

  • objective_names (Optional[List[str]], optional) – Names of the objectives. List must match the number of columns in ideal.

  • minimize (Optional[List[int]], optional) – Multipliers for each objective. ‘-1’ indicates maximization and ‘1’ minimization. Defaults to all objective values being minimized.

Raises:

NautilusException – One or more dimension mismatches are encountered among the supplies arguments.

start() NautilusInitialRequest

Start the solution process with initializing the first request.

Returns:

Initial request.

Return type:

NautilusInitialRequest

iterate(request: NautilusInitialRequest | NautilusRequest | NautilusStopRequest) NautilusRequest | NautilusStopRequest

Perform the next logical iteration step based on the given request type.

Parameters:

request (Union[NautilusInitialRequest, NautilusRequest]) – Either initial or intermediate request.

Returns:

A new request with content depending on the Decision maker’s preferences.

Return type:

Union[NautilusRequest, NautilusStopRequest]

handle_initial_request(request: NautilusInitialRequest) NautilusRequest

Handles the initial request by parsing the response appropriately.

Parameters:

request (NautilusInitialRequest) – Initial request including Decision maker’s initial preferences.

Returns:

New request with updated solution process information.

Return type:

NautilusRequest

handle_request(request: NautilusRequest) NautilusRequest | NautilusStopRequest

Handle Decision maker’s requests after the first iteration round, so called intermediate requests.

Parameters:

request (NautilusRequest) – Intermediate request including Decision maker’s response.

Returns:

In case last iteration, request to stop the solution process. Otherwise, new request with updated solution process information.

Return type:

Union[NautilusRequest, NautilusStopRequest]

calculate_preferential_factors(pref_method: int, pref_info: numpy.ndarray, nadir: numpy.ndarray, utopian: numpy.ndarray) numpy.ndarray

Calculate preferential factors based on the Decision maker’s preference information. These preferential factors are used as weights for objectives when solving an Achievement scalarizing function. The Decision maker (DM) has two possibilities to provide her/his preferences:

1. The DM can rank the objectives according to the relative importance of improving each current objective value.

Note

This ranking is not a global preference ranking of the objectives, but represents the local importance of improving each of the current objective values at that moment.

2. The DM can specify percentages reflecting how (s)he would like to improve the current objective values, by answering to the following question:

“Assuming you have one hundred points available, how would you distribute them among the current objective values so that the more points you allocate, the more improvement on the corresponding current objective value is desired?”

Parameters:
  • pref_method (int) – Preference information method (either ranks (1) or percentages (2)).

  • pref_info (np.ndarray) – Preference information on how the DM wishes to improve the values of each objective function.

  • nadir (np.ndarray) – Nadir vector.

  • utopian (np.ndarray) – Utopian vector.

Returns:

Weights assigned to each of the objective functions in achievement scalarizing function.

Return type:

np.ndarray

Examples

>>> pref_method = 1  # ranks
>>> pref_info = np.array([2, 2, 1, 1])  # first and second objective are the most important to improve
>>> nadir = np.array([-4.75, -2.87, -0.32, 9.71])
>>> utopian = np.array([-6.34, -3.44, -7.5, 0.])
>>> calculate_preferential_factors(pref_method, pref_info, nadir, utopian)
array([0.31446541, 0.87719298, 0.13927577, 0.10298661])
>>> pref_method = 2  # percentages
>>> pref_info = np.array([10, 30, 40, 20])  # DM wishes to improve most the value of objective 3, then 2,4,1
>>> nadir = np.array([-4.75, -2.87, -0.32, 9.71])
>>> utopian = np.array([-6.34, -3.44, -7.5, 0.])
>>> calculate_preferential_factors(pref_method, pref_info, nadir, utopian)
array([6.28930818, 5.84795322, 0.34818942, 0.51493306])
solve_asf(ref_point: numpy.ndarray, x0: numpy.ndarray, preferential_factors: numpy.ndarray, nadir: numpy.ndarray, utopian: numpy.ndarray, objectives: Callable, variable_bounds: numpy.ndarray | None, method: desdeo_tools.solver.ScalarSolver.ScalarMethod | str | None) dict

Solve Achievement scalarizing function.

Parameters:
  • ref_point (np.ndarray) – Reference point.

  • x0 (np.ndarray) – Initial values for decision variables.

  • preferential_factors (np.ndarray) – preferential factors on how much would the decision maker wish to improve the values of each objective function.

  • nadir (np.ndarray) – Nadir vector.

  • utopian (np.ndarray) – Utopian vector.

  • objectives (np.ndarray) – The objective function values for each input vector.

  • variable_bounds (Optional[np.ndarray) – Lower and upper bounds of each variable as a 2D numpy array. If undefined variables, None instead.

  • method (Union[ScalarMethod, str, None) – The optimization method the scalarizer should be minimized with

Returns:

A dictionary with at least the following entries: ‘x’ indicating the optimal variables found, ‘fun’ the optimal value of the optimized function, and ‘success’ a boolean indicating whether the optimization was conducted successfully.

Return type:

Dict

calculate_iteration_point(itn: int, z_prev: numpy.ndarray, f_current: numpy.ndarray) numpy.ndarray

Calculate next iteration point towards the Pareto optimal solution.

Parameters:
  • itn (int) – Number of iterations left.

  • z_prev (np.ndarray) – Previous iteration point.

  • f_current (np.ndarray) – Current optimal objective vector.

Returns:

Next iteration point.

Return type:

np.ndarray

calculate_bounds(objectives: Callable, n_objectives: int, x0: numpy.ndarray, epsilons: numpy.ndarray, bounds: numpy.ndarray | None, constraints: Callable | None, method: desdeo_tools.solver.ScalarSolver.ScalarMethod | str | None) numpy.ndarray

Calculate the new bounds using Epsilon constraint method.

Parameters:
  • objectives (np.ndarray) – The objective function values for each input vector.

  • n_objectives (int) – Total number of objectives.

  • x0 (np.ndarray) – Initial values for decision variables.

  • epsilons (np.ndarray) – Previous iteration point.

  • bounds (Union[np.ndarray, None) – Bounds for decision variables.

  • constraints (Callable) – Constraints of the problem.

  • method (Union[ScalarMethod, str, None]) – The optimization method the scalarizer should be minimized with.

Returns:

New lower bounds for objective functions.

Return type:

new_lower_bounds (np.ndarray)

calculate_distance(z_current: numpy.ndarray, nadir: numpy.ndarray, f_current: numpy.ndarray) numpy.ndarray

Calculates the distance from current iteration point to the Pareto optimal set.

Parameters:
  • z_current (np.ndarray) – Current iteration point.

  • nadir (np.ndarray) – Nadir vector.

  • f_current (np.ndarray) – Current optimal objective vector.

Returns:

Distance to the Pareto optimal set.

Return type:

np.ndarray

desdeo_mcdm.interactive.validate_response(n_objectives: int, z_current: numpy.ndarray, nadir: numpy.ndarray, response: Dict, first_iteration_bool: bool) None[source]

Validate decision maker’s response.

Parameters:
  • n_objectives (int) – Number of objectives.

  • z_current (np.ndarray) – Current iteration point.

  • nadir (np.ndarray) – Nadir point.

  • response (Dict) – Decision maker’s response containing preference information.

  • first_iteration_bool (bool) – Indicating whether the iteration round is the first one (True) or not (False).

Raises:

NautilusException – In case Decision maker’s response is not valid.

desdeo_mcdm.interactive.validate_n2_preferences(n_objectives: int, response: Dict) None[source]

Validate decision maker’s preferences in NAUTILUS 2.

Parameters:
  • n_objectives (int) – Number of objectives in problem.

  • response (Dict) – Decision maker’s response containing preference information.

Raises:

NautilusException – In case preference info is not valid.

desdeo_mcdm.interactive.validate_n_iterations(n_it: int) None[source]

Validate decision maker’s preference for number of iterations.

Parameters:

n_it (int) – Number of iterations.

Raises:

NautilusException – If number of iterations given is not a positive integer greater than zero.

class desdeo_mcdm.interactive.NautilusV2(problem: desdeo_problem.problem.MOProblem, starting_point: numpy.ndarray, ideal: numpy.ndarray, nadir: numpy.ndarray, epsilon: float = 1e-06, objective_names: List[str] | None = None, minimize: List[int] | None = None)[source]

Bases: desdeo_mcdm.interactive.InteractiveMethod.InteractiveMethod

Implements the NAUTILUS 2 method as presented in |Miettinen_2015|.

Similarly to NAUTILUS, starting from the nadir point, a solution is obtained at each iteration which dominates the previous one. Although only the last solution will be Pareto optimal, the Decision Maker (DM) never looses sight of the Pareto optimal set, and the search is oriented so that (s)he progressively focusses on the preferred part of the Pareto optimal set. Each new solution is obtained by minimizing an achievement scalarizing function including preferences about desired improvements in objective function values.

NAUTILUS 2 introduces a new preference handling technique which is easily understandable for the DM and allows the DM to conveniently control the solution process. Preferences are given as direction of improvement for objectives. In NAUTILUS 2, the DM has three ways to do this:

  1. The DM sets the direction of improvement directly.

  2. The DM defines the improvement ratio between two different objectives fi and fj. For example, if the DM wishes that the improvement of fi by one unit should be accompanied with the improvement of fj by θij units. Here, the DM selects an objective fi (i=1,…,k) and for each of the other objectives fj sets the value θij. Then, the direction of improvement is defined by

    δi=1 and δj=θij, j≠i.

  3. As a generalization of the approach 2, the DM sets values of improvement ratios freely for some selected pairs of objective functions.

As with NAUTILUS, after each iteration round, the decision maker specifies whether (s)he wishes to continue with the previous preference information, or define a new one.

In addition to this, the decision maker can influence the solution finding process by taking a step back to the previous iteration point. This enables the decision maker to provide new preferences and change the direction of the solution seeking process. Furthermore, the decision maker can also take a half-step in case (s)he feels that a full step limits the reachable area of the Pareto optimal set too much.

Parameters:
  • problem (MOProblem) – Problem to be solved.

  • starting_point (np.ndarray) – Objective vector used as a starting point for method.

  • ideal (np.ndarray) – The ideal objective vector of the problem being represented by the Pareto front.

  • nadir (np.ndarray) – The nadir objective vector of the problem being represented by the Pareto front.

  • epsilon (float) – A small number used in calculating the utopian point. By default 1e-6.

  • objective_names (Optional[List[str]], optional) – Names of the objectives. The length of the list must match the number of columns in ideal.

  • minimize (Optional[List[int]], optional) – Multipliers for each objective. ‘-1’ indicates maximization and ‘1’ minimization. Defaults to all objective values being minimized.

Raises:

NautilusException – One or more dimension mismatches are encountered among the supplies arguments.

start() NautilusInitialRequest

Start the solution process with initializing the first request.

Returns:

Initial request.

Return type:

NautilusInitialRequest

iterate(request: NautilusInitialRequest | NautilusRequest | NautilusStopRequest) NautilusRequest | NautilusStopRequest

Perform the next logical iteration step based on the given request type.

Parameters:

request (Union[NautilusInitialRequest, NautilusRequest]) – Either initial or intermediate request.

Returns:

A new request with content depending on the Decision maker’s

preferences.

Return type:

Union[NautilusRequest, NautilusStopRequest]

handle_initial_request(request: NautilusInitialRequest) NautilusRequest

Handles the initial request by parsing the response appropriately.

Parameters:

request (NautilusInitialRequest) – Initial request including Decision maker’s initial preferences.

Returns:

New request with updated solution process information.

Return type:

NautilusRequest

handle_request(request: NautilusRequest) NautilusRequest | NautilusStopRequest

Handle Decision maker’s requests after the first iteration round, so-called intermediate requests.

Parameters:

request (NautilusRequest) – Intermediate request including Decision maker’s response.

Returns:

In case of last iteration, request to stop the solution process.

Otherwise, new request with updated solution process information.

Return type:

Union[NautilusRequest, NautilusStopRequest]

calculate_preferential_factors(n_objectives: int, pref_method: int, pref_info: numpy.ndarray) numpy.ndarray

Calculate preferential factors based on decision maker’s preference information.

Parameters:
  • n_objectives (int) – Number of objectives in problem.

  • pref_method (int) – Preference information method, either: Direction of improvement (1), improvement ratios between a selected objective and rest of the objectives (2), or improvement ratios freely for some selected pairs of objectives (3).

  • pref_info (np.ndarray) – Preference information on how the DM wishes to improve the values of each objective function. See the examples below.

Returns:

Direction of improvement. Used as weights assigned to each of the objective functions in the achievement scalarizing function.

Return type:

np.ndarray

Examples

>>> n_objectives = 4
>>> pref_method = 1  # deltas directly
>>> pref_info = np.array([1, 2, 1, 2]),  # second and fourth objective are the most important to improve
>>> calculate_preferential_factors(n_objectives, pref_method, pref_info)
np.array([1, 2, 1, 2])
>>> n_objectives = 4
>>> pref_method = 2  # improvement ratios between one selected objective and each other objective
>>> pref_info = np.array([1, 1.5, (7/3), 0.5])  # first objective's ratio is set to one
>>> calculate_preferential_factors(n_objectives, pref_method, pref_info)
np.array([1, 1.5, (7/3), 0.5])
>>> n_objectives = 4
>>> pref_method = 3  # improvement ratios between freely selected pairs of objectives
# format the tuples like this: (('index of objective', 'index of objective'), 'improvement ratio between the objectives')
>>> pref_info = np.array([((1, 2), 0.5), ((3, 4), 1), ((2, 3), 1.5)], dtype=object)
>>> calculate_preferential_factors(n_objectives, pref_method, pref_info)
np.array([1., 0.5, 0.75, 0.75])

Note

Remember to specify “dtype=object” in pref_info array when using preference

method 3.

calculate_doi(n_objectives: int, pref_info: numpy.ndarray) numpy.ndarray

Calculate direction of improvement based on improvement ratios between pairs of objective functions.

Parameters:
  • n_objectives (int) – Number of objectives.

  • pref_info (np.ndarray) – Preference information on how the DM wishes to improve the values of each objective function.

Returns:

Direction of improvement.

Return type:

np.ndarray

solve_asf(ref_point: numpy.ndarray, x0: numpy.ndarray, preferential_factors: numpy.ndarray, nadir: numpy.ndarray, utopian: numpy.ndarray, objectives: Callable, variable_bounds: numpy.ndarray | None = None, method: desdeo_tools.solver.ScalarSolver.ScalarMethod | str | None = None) dict

Solve achievement scalarizing function.

Parameters:
  • ref_point (np.ndarray) – Reference point.

  • x0 (np.ndarray) – Initial values for decision variables.

  • preferential_factors (np.ndarray) – Preferential factors indicating how much would the decision maker wish to improve the values of each objective function.

  • nadir (np.ndarray) – Nadir vector.

  • utopian (np.ndarray) – Utopian vector.

  • objectives (np.ndarray) – The objective function values for each input vector.

  • variable_bounds (Optional[np.ndarray]) – Lower and upper bounds of each variable as a 2D numpy array. If undefined variables, None instead.

  • method (Union[ScalarMethod, str, None]) – The optimization method the scalarizer should be minimized with.

Returns:

A dictionary with at least the following entries: ‘x’ indicating the optimal variables found, ‘fun’ the optimal value of the optimized function, and ‘success’ a boolean indicating whether the optimization was conducted successfully.

Return type:

Dict

calculate_iteration_point(itn: int, z_prev: numpy.ndarray, f_current: numpy.ndarray) numpy.ndarray

Calculate next iteration point towards the Pareto optimal solution.

Parameters:
  • itn (int) – Number of iterations left.

  • z_prev (np.ndarray) – Previous iteration point.

  • f_current (np.ndarray) – Current optimal objective vector.

Returns:

Next iteration point.

Return type:

np.ndarray

calculate_bounds(objectives: Callable, n_objectives: int, x0: numpy.ndarray, epsilons: numpy.ndarray, bounds: numpy.ndarray | None, constraints: Callable | None, method: desdeo_tools.solver.ScalarSolver.ScalarMethod | str | None) numpy.ndarray

Calculate the new bounds using Epsilon constraint method.

Parameters:
  • objectives (np.ndarray) – The objective function values for each input vector.

  • n_objectives (int) – Total number of objectives.

  • x0 (np.ndarray) – Initial values for decision variables.

  • epsilons (np.ndarray) – Previous iteration point.

  • bounds (Union[np.ndarray, None]) – Bounds for decision variables.

  • constraints (Callable) – Constraints of the problem.

  • method (Union[ScalarMethod, str, None]) – The optimization method the scalarizer should be minimized with.

Returns:

New lower bounds for objective functions.

Return type:

np.ndarray

calculate_distance(z_current: numpy.ndarray, starting_point: numpy.ndarray, f_current: numpy.ndarray) numpy.ndarray

Calculates the distance from current iteration point to the Pareto optimal set.

Parameters:
  • z_current (np.ndarray) – Current iteration point.

  • starting_point (np.ndarray) – Starting iteration point.

  • f_current (np.ndarray) – Current optimal objective vector.

Returns:

Distance to the Pareto optimal set.

Return type:

np.ndarray

exception desdeo_mcdm.interactive.NautilusException[source]

Bases: Exception

Raised when an exception related to Nautilus is encountered.

class desdeo_mcdm.interactive.NautilusInitialRequest(ideal: numpy.ndarray, nadir: numpy.ndarray)[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request class to handle the Decision maker’s initial preferences for the first iteration round.

Parameters:
  • ideal (np.ndarray) – Ideal vector.

  • nadir (np.ndarray) – Nadir vector.

classmethod init_with_method(method: desdeo_mcdm.interactive.InteractiveMethod.InteractiveMethod)

Initialize request with given instance of Nautilus method.

Parameters:

method (Nautilus) – Instance of Nautilus-class.

Returns:

Initial request.

Return type:

NautilusInitialRequest

class desdeo_mcdm.interactive.NautilusRequest(z_current: numpy.ndarray, nadir: numpy.ndarray, lower_bounds: numpy.ndarray, upper_bounds: numpy.ndarray, distance: numpy.ndarray)[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request class to handle the Decision maker’s preferences after the first iteration round.

class desdeo_mcdm.interactive.NautilusStopRequest(x_h: numpy.ndarray, f_h: numpy.ndarray)[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request class to handle termination.

Parameters:
  • x_h (np.ndarray) – Solution (decision variables).

  • f_h (np.ndarray) – Objective vector.

class desdeo_mcdm.interactive.NautilusNavigator(pareto_front: numpy.ndarray, ideal: numpy.ndarray, nadir: numpy.ndarray, decision_variables: numpy.ndarray | None = None)

Bases: desdeo_mcdm.interactive.InteractiveMethod.InteractiveMethod

Implementations of the NAUTILUS Navigator algorithm.

Parameters:
  • pareto_front (np.ndarray) – A two dimensional numpy array representing a Pareto front with objective vectors on each of its rows.

  • ideal (np.ndarray) – The ideal objective vector of the problem being represented by the Pareto front.

  • nadir (np.ndarray) – The nadir objective vector of the problem being represented by the Pareto front.

  • decision_variables (Optional[np.ndarray]) – Two dimensinoal numpy array of decision variables that can be optionally supplied. The i’th vector in decision_variables should result in the i’th objective vector in pareto_front. Defaults to None.

Raises:
start() NautilusNavigatorRequest

Returns the first Request object to begin iterating.

Returns:

The Request.

Return type:

NautilusNavigatorRequest

iterate(request: NautilusNavigatorRequest) NautilusNavigatorRequest

Perform the next logical step based on the response in the Request.

handle_request(request: NautilusNavigatorRequest) NautilusNavigatorRequest | NautilusNavigatorStopRequest

Handle the Request and its contents.

Parameters:

request (NautilusNavigatorRequest) – A Request with a defined response.

Returns:

Some of the contents of the response are invalid.

Return type:

NautilusNavigatorRequest

update(ref_point: numpy.ndarray, speed: int, go_to_previous: bool, stop: bool, step_number: int | None = None, nav_point: numpy.ndarray | None = None, lower_bounds: numpy.ndarray | None = None, upper_bounds: numpy.ndarray | None = None, user_bounds: numpy.ndarray | None = None, reachable_idx: List[int] | None = None, distance: float | None = None, steps_remaining: int | None = None) NautilusNavigatorRequest | None

Update the internal state of self.

Parameters:
  • ref_point (np.ndarray) – A reference point given by a decision maker.

  • speed (int) – An integer value between 1-5 indicating the navigation speed.

  • go_to_previous (bool) – If True, the parameters indicate the state of a previous state, and the request is handled accordingly.

  • stop (bool) – If the navigation should stop. If True, returns a request with self’s current state.

  • step_number (Optional[int], optional) – Current step number, or previous step number if go_to_previous is True. Defaults to None.

  • nav_point (Optional[np.ndarray], optional) – The current navigation point. Relevant if go_to_previous is True. Defaults to None.

  • lower_bounds (Optional[np.ndarray], optional) – Lower bounds of the reachable objective vector values. Relevant if go_to_previous is True. Defaults to None.

  • upper_bounds (Optional[np.ndarray], optional) – Upper bounds of the reachable objective vector values. Relevant if go_to_previous is True. Defaults to None.

  • user_bounds (Optional[np.ndarray], optional) – The user given bounds for each objective. The reachable lower limit with attempt to not exceed the given bounds for each objective value.

  • reachable_idx (Optional[List[int]], optional) – Indices of the reachable Pareto optimal solutions. Relevant if go_to_previous is True. Defaults to None.

  • distance (Optional[float], optional) – Distance to the Pareto optimal front. Relevant if go_to_previous is True. Defaults to None.

  • steps_remaining (Optional[int], optional) – Remaining steps in the navigation. Relevant if go_to_previous is True. Defaults to None.

Returns:

Some of the given parameters are erroneous.

Return type:

NautilusNavigatorRequest

calculate_reachable_point_indices(pareto_front: numpy.ndarray, lower_bounds: numpy.ndarray, upper_bounds: numpy.ndarray) List[int]

Calculate the indices of the reachable Pareto optimal solutions based on lower and upper bounds.

Returns:

List of the indices of the reachable solutions.

Return type:

List[int]

static solve_nautilus_asf_problem(pareto_f: numpy.ndarray, subset_indices: List[int], ref_point: numpy.ndarray, ideal: numpy.ndarray, nadir: numpy.ndarray, user_bounds: numpy.ndarray) int

Forms and solves the achievement scalarizing function to find the closest point on the Pareto optimal front to the given reference point.

Parameters:
  • pareto_f (np.ndarray) – The whole Pareto optimal front.

  • subset_indices ([type]) – Indices of the currently reachable solutions.

  • ref_point (np.ndarray) – The reference point indicating a decision maker’s preference.

  • ideal (np.ndarray) – Ideal point.

  • nadir (np.ndarray) – Nadir point.

  • user_bounds (np.ndarray) – Bounds given by the user (the DM) for each objective,which should not be exceeded. A 1D array where NaN’s indicate ‘no bound is given’ for the respective objective value.

Returns:

Index of the closest point according the minimized value of the ASF.

Return type:

int

calculate_navigation_point(projection: numpy.ndarray, nav_point: numpy.ndarray, steps_remaining: int) numpy.ndarray

Calculate a new navigation point based on the projection of the preference point to the Pareto optimal front.

Parameters:
  • projection (np.ndarray) – The point on the Pareto optimal front closest to the preference point given by a decision maker.

  • nav_point (np.ndarray) – The previous navigation point.

  • steps_remaining (int) – How many steps are remaining in the navigation.

Returns:

The new navigation point.

Return type:

np.ndarray

static calculate_bounds(pareto_front: numpy.ndarray, nav_point: numpy.ndarray, user_bounds: numpy.ndarray, previous_lb: numpy.ndarray, previous_ub: numpy.ndarray) Tuple[numpy.ndarray, numpy.ndarray]

Calculate the new bounds of the reachable points on the Pareto optimal front from a navigation point.

Parameters:
  • pareto_front (np.ndarray) – The Pareto optimal front.

  • nav_point (np.ndarray) – The current navigation point.

  • user_bounds (np.ndarray) – Bounds given by the user (the DM) for each objective,which should not be exceeded. A 1D array where NaN’s indicate ‘no bound is given’ for the respective objective value.

  • previous_lb (np.ndarray) – If no new lower bound can be found for an objective, this value is used.

  • previous_ub (np.ndarray) – If no new upper bound can be found for an objective, this value is used.

Returns:

The lower and upper bounds.

Return type:

Tuple[np.ndarray, np.ndarray]

calculate_distance(nav_point: numpy.ndarray, projection: numpy.ndarray, nadir: numpy.ndarray) float

Calculate the distance to the Pareto optimal front from a navigation point. The distance is calculated to the supplied projection which is assumed to lay on the front.

Parameters:
  • nav_point (np.ndarray) – The navigation point.

  • projection (np.ndarray) – The point of the Pareto optimal front the distance is calculated to.

  • nadir (np.ndarray) – The nadir point of the Pareto optimal set.

Returns:

The distance.

Return type:

float

exception desdeo_mcdm.interactive.NautilusNavigatorException[source]

Bases: Exception

Raised when an exception related to NAUTILUS Navigator is encountered.

class desdeo_mcdm.interactive.NautilusNavigatorRequest(ideal: numpy.ndarray, nadir: numpy.ndarray, reachable_lb: numpy.ndarray, reachable_ub: numpy.ndarray, user_bounds: List[float], reachable_idx: List[int], step_number: int, steps_remaining: int, distance: float, allowed_speeds: List[int], current_speed: int, navigation_point: numpy.ndarray)[source]

Bases: desdeo_tools.interaction.request.BaseRequest

Request to handle interactions with NAUTILUS Navigator. See the NautilusNavigator class for further details.

classmethod init_with_method(method)
validator(response: Dict) None
class desdeo_mcdm.interactive.NIMBUS(problem: desdeo_problem.problem.MOProblem | desdeo_problem.problem.DiscreteDataProblem, scalar_method: desdeo_tools.solver.ScalarSolver.ScalarMethod | str | None = 'scipy_de', starting_point: numpy.ndarray | None = None)

Bases: desdeo_mcdm.interactive.InteractiveMethod.InteractiveMethod

Implements the synchronous NIMBUS algorithm.

Parameters:
  • problem (MOProblem) – The problem to be solved.

  • scalar_method (Optional[Union[ScalarMethod, str]], optional) – The method used to solve the various ASF minimization problems present in the method. Defaults to ‘scipy_de’ (differential evolution).

  • starting_point (Optional[np.ndarray], optional) – The initial solution (objectives) to start classification from. If None, a neutral starting point will be computed.

Note

When a starting point is supplied, decision variables of that point will be approximated to be the variables of the solution closest to the starting point. In other words, the decision variables associated to the initial point may be inaccurate!

start() Tuple[NimbusClassificationRequest, desdeo_tools.interaction.request.SimplePlotRequest]

Return the first request to start iterating NIMBUS.

Returns:

The first request and and a plot request to visualize relevant data.

Return type:

Tuple[NimbusClassificationRequest, SimplePlotRequest]

request_classification() Tuple[NimbusClassificationRequest, desdeo_tools.interaction.request.SimplePlotRequest]
create_plot_request(objectives: numpy.ndarray, msg: str) desdeo_tools.interaction.request.SimplePlotRequest

Used to create a plot request for visualizing objective values.

Parameters:
  • objectives (np.ndarray) – A 2D numpy array containing objective vectors to be visualized.

  • msg (str) – A message to be displayed in the context of a visualization.

Returns:

A plot request to create a visualization.

Return type:

SimplePlotRequest

handle_classification_request(request: NimbusClassificationRequest) Tuple[NimbusSaveRequest, desdeo_tools.interaction.request.SimplePlotRequest]

Handles a classification request.

Parameters:

request (NimbusClassificationRequest) – A classification request with the response attribute set.

Returns:

A NIMBUS save request and a plot request with the solutions the decision maker can choose from to save for alter use.

Return type:

Tuple[NimbusSaveRequest, SimplePlotRequest]

handle_save_request(request: NimbusSaveRequest) Tuple[NimbusIntermediateSolutionsRequest, desdeo_tools.interaction.request.SimplePlotRequest]

Handles a save request.

Parameters:

request (NimbusSaveRequest) – A save request with the response attribute set.

Returns:

Return an intermediate solution request where the decision maker can specify whether they would like to see intermediate solution between two previously computed solutions. The plot request has the available solutions.

Return type:

Tuple[NimbusIntermediateSolutionsRequest, SimplePlotRequest]

handle_intermediate_solutions_request(request: NimbusIntermediateSolutionsRequest) Tuple[NimbusSaveRequest | NimbusMostPreferredRequest, desdeo_tools.interaction.request.SimplePlotRequest]

Handles an intermediate solutions request.

Parameters:

request (NimbusIntermediateSolutionsRequest) – A NIMBUS intermediate solutions request with the response attribute set.

Returns:

Return either a save request or a preferred solution request. The former is returned if the decision maker wishes to see intermediate points, the latter otherwise. Also a plot request is returned with the solutions available in it.

Return type:

Tuple[Union[NimbusSaveRequest, NimbusMostPreferredRequest], SimplePlotRequest,]

handle_most_preferred_request(request: NimbusMostPreferredRequest) Tuple[NimbusClassificationRequest | NimbusStopRequest, desdeo_tools.interaction.request.SimplePlotRequest]

Handles a preferred solution request.

Parameters:

request (NimbusMostPreferredRequest) – A NIMBUS preferred solution request with the response attribute set.

Returns:

Return a classification request if the decision maker wishes to continue. If the decision maker wishes to stop, return a stop request. Also return a plot request with all the solutions saved so far.

Return type:

Tuple[Union[NimbusClassificationRequest, NimbusStopRequest], SimplePlotRequest]

request_stop() Tuple[NimbusStopRequest, desdeo_tools.interaction.request.SimplePlotRequest]

Create a NimbusStopRequest based on self.

Returns:

A stop request and a plot request with the final solution chosen in it.

Return type:

Tuple[NimbusStopRequest, SimplePlotRequest]

request_most_preferred_solution(solutions: numpy.ndarray, objectives: numpy.ndarray) Tuple[NimbusMostPreferredRequest, desdeo_tools.interaction.request.SimplePlotRequest]

Create a NimbusMostPreferredRequest.

Parameters:
  • solutions (np.ndarray) – A 2D numpy array of decision variable vectors.

  • objectives (np.ndarray) – A 2D numpy array of objective value vectors.

Returns:

The requests based on the given arguments.

Return type:

Tuple[NimbusMostPreferredRequest, SimplePlotRequest]

Note

The ‘i’th decision variable vector in solutions should correspond to the ‘i’th objective value vector in objectives.

compute_intermediate_solutions(solutions: numpy.ndarray, n_desired: int) Tuple[NimbusSaveRequest, desdeo_tools.interaction.request.SimplePlotRequest]

Computes intermediate solution between two solutions computed earlier.

Parameters:
  • solutions (np.ndarray) – The solutions between which the intermediate solutions should be computed.

  • n_desired (int) – The number of intermediate solutions desired.

Raises:

NimbusException

Returns:

A save request with the computed intermediate points, and a plot request to visualize said points.

Return type:

Tuple[NimbusSaveRequest, SimplePlotRequest]

save_solutions_to_archive(objectives: numpy.ndarray, decision_variables: numpy.ndarray, indices: List[int]) Tuple[NimbusIntermediateSolutionsRequest, None]

Save solutions to the archive. Saves also the corresponding objective function values.

Parameters:
  • objectives (np.ndarray) – Available objectives.

  • decision_variables (np.ndarray) – Available solutions.

  • indices (List[int]) – Indices of the solutions to be saved.

Returns:

An intermediate solutions request asking the decision maker whether they would like to generate intermediata solutions between two existing solutions. Also returns a plot request to visualize the available solutions between which the intermediate solutions should be computed.

Return type:

Tuple[NimbusIntermediateSolutionsRequest, None]

calculate_new_solutions(number_of_solutions: int, levels: numpy.ndarray, improve_inds: numpy.ndarray, improve_until_inds: numpy.ndarray, acceptable_inds: numpy.ndarray, impaire_until_inds: numpy.ndarray, free_inds: numpy.ndarray) Tuple[NimbusSaveRequest, desdeo_tools.interaction.request.SimplePlotRequest]
Calculates new solutions based on classifications supplied by the decision maker by

solving ASF problems.

Parameters:
  • number_of_solutions (int) – Number of solutions, should be between 1 and 4.

  • levels (np.ndarray) – Aspiration and upper bounds relevant to the some of the classifications.

  • improve_inds (np.ndarray) – Indices corresponding to the objectives which should be improved.

  • improve_until_inds (np.ndarray) – Like above, but improved until an aspiration level is reached.

  • acceptable_inds (np.ndarray) – Indices of objectives which are acceptable as they are now.

  • impaire_until_inds (np.ndarray) – Indices of objectives which may be impaired until an upper limit is reached.

  • free_inds (np.ndarray) – Indices of objectives which may change freely.

Returns:

A save request with the newly computed solutions, and a plot request to visualize said solutions.

Return type:

Tuple[NimbusSaveRequest, SimplePlotRequest]

update_current_solution(solutions: numpy.ndarray, objectives: numpy.ndarray, index: int) None

Update the state of self with a new current solution and the corresponding objective values. This solution is used in the classification phase of synchronous NIMBUS.

Parameters:
  • solutions (np.ndarray) – A 2D numpy array of decision variable vectors.

  • objectives (np.ndarray) – A 2D numpy array of objective value vectors.

  • index (int) – The index of the solution in solutions and objectives.

Returns:

The requests based on the given arguments.

Return type:

Tuple[NimbusMostPreferredRequest, SimplePlotRequest]

Note

The ‘i’th decision variable vector in solutions should correspond to the ‘i’th objective value vector in objectives.

iterate(request: NimbusClassificationRequest | NimbusSaveRequest | NimbusIntermediateSolutionsRequest | NimbusMostPreferredRequest | NimbusStopRequest) Tuple[NimbusClassificationRequest | NimbusSaveRequest | NimbusIntermediateSolutionsRequest, desdeo_tools.interaction.request.SimplePlotRequest | None]

Implements a finite state machine to iterate over the different steps defined in Synchronous NIMBUS based on a supplied request.

Parameters:

request (Union[NimbusClassificationRequest,NimbusSaveRequest,NimbusIntermediateSolutionsRequest,NimbusMostPreferredRequest,NimbusStopRequest,]) – A request based on the next step in the NIMBUS algorithm is taken.

Raises:

NimbusException – If a wrong type of request is supplied based on the current state NIMBUS is in.

Returns:

The next logically sound request.

Return type:

Tuple[Union[NimbusClassificationRequest,NimbusSaveRequest,NimbusIntermediateSolutionsRequest,],Union[SimplePlotRequest, None],]

class desdeo_mcdm.interactive.NimbusClassificationRequest(method: NIMBUS, ref: numpy.ndarray)[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request to handle the classification of objectives in the synchronous NIMBUS method.

Parameters:
  • method (NIMBUS) – The instance of the NIMBUS method the request should be initialized for.

  • ref (np.ndarray) – Objective values used as a reference the decision maker is classifying the objectives.

self._valid_classifications

The valid classifications. Defaults is [‘<’, ‘<=’, ‘=’, ‘>=’, ‘0’]

Type:

List[str]

validator(response: Dict) None

Validates a dictionary containing the response of a decision maker. Should contain the keys ‘classifications’, ‘levels’, and ‘number_of_solutions’.

‘classifications’ should be a list of strings, where the number of elements is equal to the number of objectives being classified, and the elements are found in _valid_classifications. ‘levels’ should have either aspiration levels or bounds for each objective depending on that objective’s classification. ‘number_of_solutions’ should be an integer between 1 and 4 indicating the number of intermediate solutions to be computed.

Parameters:

response (Dict) – See the documentation for validator.

Raises:

NimbusException – Some discrepancy is encountered in the parsing of the response.

exception desdeo_mcdm.interactive.NimbusException[source]

Bases: Exception

Risen when an error related to NIMBUS is encountered.

class desdeo_mcdm.interactive.NimbusIntermediateSolutionsRequest(solution_vectors: List[numpy.ndarray], objective_vectors: List[numpy.ndarray])[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request to handle the computation of intermediate points between two previously computed points.

Parameters:
  • solution_vectors (List[np.ndarray]) – A list of numpy arrays each representing a decision variable vector.

  • objective_vectors (List[np.ndarray]) – A list of numpy arrays each representing an objective vector.

Note

The objective vector at position ‘i’ in objective_vectors should correspond to the decision variables at position ‘i’ in solution_vectors. Only the two first entries in each of the lists is relevant. The rest is ignored.

validator(response: Dict)

Validates a response dictionary. The dictionary should contain the keys ‘indices’ and ‘number_of_solutions’.

‘indices’ should be a list of integers representing an index to the lists solutions_vectors and objective_vectors. ‘number_of_solutions’ should be an integer greater or equal to 1.

Parameters:

response (Dict) – See the documentation for validator.

Raises:

NimbusException – Some discrepancy is encountered in the parsing of response.

class desdeo_mcdm.interactive.NimbusMostPreferredRequest(solution_vectors: List[numpy.ndarray], objective_vectors: List[numpy.ndarray])[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request to handle the indication of a preferred point.

Parameters:
  • solution_vectors (List[np.ndarray]) – A list of numpy arrays each representing a decision variable vector.

  • objective_vectors (List[np.ndarray]) – A list of numpy arrays each representing an objective vector.

Note

The objective vector at position ‘i’ in objective_vectors should correspond to the decision variables at position ‘i’ in solution_vectors. Only the two first entries in each of the lists are relevant. The preferred solution will be selected from objective_vectors.

validator(response: Dict)

Validates a response dictionary. The dictionary should contain the keys ‘index’ and ‘continue’.

‘index’ is an integer and should indicate the index of the preferred solution is objective_vectors. ‘continue’ is a boolean and indicates whether to stop or continue the iteration of Synchronous NIMBUS.

Parameters:

response (Dict) – See the documentation for validator.

Raises:

NimbusException – Some discrepancy is encountered in the parsing of response.

class desdeo_mcdm.interactive.NimbusSaveRequest(solution_vectors: List[numpy.ndarray], objective_vectors: List[numpy.ndarray])[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request to handle archiving of the solutions computed with NIMBUS.

Parameters:
  • solution_vectors (List[np.ndarray]) – A list of numpy arrays each representing a decision variable vector.

  • objective_vectors (List[np.ndarray]) – A list of numpy arrays each representing an objective vector.

Note

The objective vector at position ‘i’ in objective_vectors should correspond to the decision variables at position ‘i’ in solution_vectors.

validator(response: Dict) None

Validates a response dictionary. The dictionary should contain the keys ‘indices’.

‘indices’ should be a list of integers representing an index to the lists solutions_vectors and objective_vectors.

Parameters:

response (Dict) – See the documentation for validator.

Raises:

NimbusException – Some discrepancy is encountered in the parsing of response.

class desdeo_mcdm.interactive.NimbusStopRequest(solution_final: numpy.ndarray, objective_final: numpy.ndarray)[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request to handle the termination of Synchronous NIMBUS.

Parameters:
  • solutions_final (np.ndarray) – A numpy array containing the final decision variable values.

  • objective_final (np.ndarray) – A numpy array containing the final objective variables which correspond to

  • solution_final.

Note

This request expects no response.

exception desdeo_mcdm.interactive.RPMException[source]

Bases: Exception

Raised when an exception related to Reference Point Method (RFM) is encountered.

class desdeo_mcdm.interactive.RPMInitialRequest(ideal: numpy.ndarray, nadir: numpy.ndarray)[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request class to handle the Decision Maker’s initial preferences for the first iteration round.

classmethod init_with_method(method: desdeo_mcdm.interactive.InteractiveMethod.InteractiveMethod)

Initialize request with given instance of ReferencePointMethod.

Parameters:

method (ReferencePointMethod) – Instance of ReferencePointMethod-class.

Returns:

Initial request.

Return type:

RPMInitialRequest

class desdeo_mcdm.interactive.RPMRequest(f_current: numpy.ndarray, f_additionals: numpy.ndarray, ideal: numpy.ndarray, nadir: numpy.ndarray)[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request class to handle the Decision Maker’s preferences after the first iteration round.

Parameters:
  • f_current (np.ndarray) – Current solution.

  • f_additionals (np.ndarray) – Additional solutions.

  • ideal (np.ndarray) – Idea vector.

  • nadir (np.ndarray) – Nadir vector.

class desdeo_mcdm.interactive.RPMStopRequest(x_h: numpy.ndarray, f_h: numpy.ndarray)[source]

Bases: desdeo_tools.interaction.request.BaseRequest

A request class to handle termination.

class desdeo_mcdm.interactive.ReferencePointMethod(problem: desdeo_problem.problem.MOProblem | desdeo_problem.problem.DiscreteDataProblem, ideal: numpy.ndarray, nadir: numpy.ndarray, epsilon: float = 1e-06, objective_names: List[str] | None = None, minimize: List[int] | None = None)[source]

Bases: desdeo_mcdm.interactive.InteractiveMethod.InteractiveMethod

Implements the Reference Point Method as presented in |Wierzbicki_1982|.

In the Reference Point Method, the Decision Maker (DM) specifies desirable aspiration levels for objective functions. Vectors formed of these aspiration levels are then used to derive scalarizing functions having minimal values at weakly, properly or Pareto optimal solutions. It is important that reference points are intuitive and easy for the DM to specify, their consistency is not an essential requirement. Before the solution process starts, some information is given to the DM about the problem. If possible, the ideal objective vector and the (approximated) nadir objective vector are presented.

At each iteration, the DM is asked to give desired aspiration levels for the objective functions. Using this information to formulate a reference point, achievement function is minimized and a (weakly, properly or) Pareto optimal solution is obtained. This solution is then presented to the DM. In addition, k other (weakly, properly or) Pareto optimal solutions are calculated using perturbed reference points, where k is the number of objectives in the problem. The alternative solutions are also presented to the DM. If (s)he finds any of the k + 1 solutions satisfactory, the solution process is ended. Otherwise, the DM is asked to present a new reference point and the iteration described above is repeated.

The idea in perturbed reference points is that the DM gets better understanding of the possible solutions around the current solution. If the reference point is far from the Pareto optimal set, the DM gets a wider description of the Pareto optimal set and if the reference point is near the Pareto optimal set, then a finer description of the Pareto optimal set is given.

In this method, the DM has to specify aspiration levels and compare objective vectors. The DM is free to change her/his mind during the process and can direct the solution process without being forced to understand complicated concepts and their meaning. On the other hand, the method does not necessarily help the DM to find more satisfactory solutions.

Parameters:
  • problem (MOProblem) – Problem to be solved.

  • ideal (np.ndarray) – The ideal objective vector of the problem.

  • nadir (np.ndarray) – The nadir objective vector of the problem. This may also be the “worst” objective vector provided by the Decision Maker if the approximation of Nadir vector is not applicable or if the Decision Maker wishes to provide even worse objective vector than what the approximated Nadir vector is.

  • epsilon (float) – A small number used in calculating the utopian point.

  • epsilon – A small number used in calculating the utopian point. Default value is 1e-6.

  • objective_names (Optional[List[str]], optional) – Names of the objectives. The length of the list must match the number of elements in ideal vector.

  • minimize (Optional[List[int]], optional) – Multipliers for each objective. ‘-1’ indicates maximization and ‘1’ minimization. Defaults to all objective values being minimized.

Raises:

RPMException – Dimensions of ideal, nadir, objective_names, and minimize-list do not match.

start() RPMInitialRequest

Start the solution process with initializing the first request.

Returns:

Initial request.

Return type:

RPMInitialRequest

iterate(request: RPMInitialRequest | RPMRequest | RPMStopRequest) RPMRequest | RPMStopRequest

Perform the next logical iteration step based on the given request type.

Parameters:

request (Union[RPMInitialRequest, RPMRequest]) – Either initial or intermediate request.

Returns:

A new request with content depending on the Decision Maker’s preferences.

Return type:

Union[RPMRequest, RPMStopRequest]

handle_initial_request(request: RPMInitialRequest) RPMRequest

Handles the initial request by parsing the response appropriately.

Parameters:

request (RPMInitialRequest) – Initial request including the Decision Maker’s initial preferences.

Returns:

New request with updated solution process information.

Return type:

RPMRequest

handle_request(request: RPMRequest) RPMRequest | RPMStopRequest

Handle the Decision Maker’s requests after the first iteration round, so-called intermediate requests.

Parameters:

request (RPMRequest) – Intermediate request including the Decision Maker’s response.

Returns:

In case last iteration, request to stop the solution process. Otherwise, new request with updated solution process information.

Return type:

Union[RPMRequest, RPMStopRequest]

calculate_prp(ref_point: numpy.ndarray, f_current: numpy.ndarray) numpy.ndarray

Calculate perturbed reference points.

Parameters:
  • ref_point (np.ndarray) – Current reference point.

  • f_current (np.ndarray) – Current solution.

Returns:

Perturbed reference points.

Return type:

np.ndarray

solve_asf(ref_point: numpy.ndarray, x0: numpy.ndarray, preferential_factors: numpy.ndarray, nadir: numpy.ndarray, utopian: numpy.ndarray, objectives: Callable, variable_vectors: numpy.ndarray | None = None, variable_bounds: numpy.ndarray | None = None, method: desdeo_tools.solver.ScalarSolver.ScalarMethod | str | None = None) dict

Solve Achievement scalarizing function.

Parameters:
  • ref_point (np.ndarray) – Reference point.

  • x0 (np.ndarray) – Initial values for decision variables.

  • preferential_factors (np.ndarray) – Preferential factors on how much would the Decision Maker wish to improve the values of each objective function.

  • nadir (np.ndarray) – Nadir vector.

  • utopian (np.ndarray) – Utopian vector.

  • objectives (np.ndarray) – The objective function values for each input vector.

  • variable_bounds (Optional[np.ndarray) – Lower and upper bounds of each variable as a 2D numpy array. If undefined variables, None instead.

  • method (Union[ScalarMethod, str, None]) – The optimization method the scalarizer should be minimized with.

Returns:

A dictionary with at least the following entries: ‘x’ indicating the optimal variables found, ‘fun’ the optimal value of the optimized function, and ‘success’ a boolean indicating whether the optimization was conducted successfully.

Return type:

dict