Source code for skcriteria.agg.waspas

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# License: BSD-3 (https://tldrlegal.com/license/bsd-3-clause-license-(revised))
# Copyright (c) 2016-2021, Cabral, Juan; Luczywo, Nadia
# Copyright (c) 2022-2025 QuatroPe
# All rights reserved.

# =============================================================================
# DOCS
# =============================================================================

"""WASPAS method."""

# =============================================================================
# IMPORTS
# =============================================================================

from ..utils import hidden

with hidden():
    import numpy as np

    from ._agg_base import RankResult, SKCDecisionMakerABC
    from ..core import Objective
    from ..utils import doc_inherit, rank
    from .simple import wsm, wpm

# =============================================================================
# WASPAS
# =============================================================================


[docs] def waspas(matrix, weights, lambda_value): """Execute WASPAS without any validation.""" _, wsm_scores = wsm(matrix, weights) _, log10_wpm_scores = wpm(matrix, weights) wpm_scores = np.power(10, log10_wpm_scores) score = lambda_value * wsm_scores + (1 - lambda_value) * wpm_scores ranking = rank.rank_values(score, reverse=True) return ( ranking, wsm_scores, log10_wpm_scores, score, )
[docs] class WASPAS(SKCDecisionMakerABC): r"""The Weighted Aggregated Sum Product ASsessment method. WASPAS is a multicriteria decision analysis method that combines the Weighted Sum Model (WSM) and the Weighted Product Model (WPM) using an aggregation parameter :math:`\lambda \in [0, 1]`. It is very important to state here that it is applicable only when all the data are expressed in exactly the same unit. If this is not the case, then the final result is equivalent to "adding apples and oranges". To avoid this problem a previous normalization step is necessary. In general, suppose that a given MCDA problem is defined on :math:`m` alternatives and :math:`n` decision criteria. Let :math:`w_j` denote the weight of criterion :math:`C_j`, and :math:`a_{ij}` be the performance value of alternative :math:`A_i` with respect to criterion :math:`C_j`. The WASPAS score of alternative :math:`A_i` is defined as: .. math:: A_i^{WASPAS} = \lambda \cdot \sum_{j=1}^{n} w_j a_{ij} + (1 - \lambda) \cdot \prod_{j=1}^{n} a_{ij}^{w_j} By default, :math:`\lambda = 0.5`. Raises ------ ValueError: If some objective is for minimization, or some value in the matrix is <= 0, or if the parameter `lambda_value` is not in the range [0, 1]. References ---------- :cite:p:`zavadskas2012optimization` """ _skcriteria_parameters = ["lambda_value"] def __init__(self, *, lambda_value=0.5): lambda_value = float(lambda_value) if not (1 >= lambda_value >= 0): raise ValueError( "WASPAS requires 'lambda_value' to be " f"between 0 and 1, but found {lambda_value}." ) self._lambda_value = lambda_value @property def lambda_value(self): """Aggregation parameter in [0, 1] that balances WSM and WPM.""" return self._lambda_value @doc_inherit(SKCDecisionMakerABC._evaluate_data) def _evaluate_data(self, matrix, weights, objectives, **kwargs): if Objective.MIN in objectives: raise ValueError("WASPAS can't operate with minimize objective") if np.any(matrix <= 0): raise ValueError("WASPAS can't operate with values <= 0") (rank, wsm_scores, log10_wpm_scores, score) = waspas( matrix, weights, self.lambda_value ) return rank, { "wsm_scores": wsm_scores, "log10_wpm_scores": log10_wpm_scores, "score": score, } @doc_inherit(SKCDecisionMakerABC._make_result) def _make_result(self, alternatives, values, extra): return RankResult( "WASPAS", alternatives=alternatives, values=values, extra=extra, )