is_normalized_matrix
def is_normalized_matrix(
z_matrix:<built-in function array>, # Matrix to check
)->bool:True if every element of z_matrix is in [0, 1].
The functions in this module turn a decision matrix into a ranking. Each row of the matrix is an alternative, such as an area to sample, and each column is a criterion. Ranking takes three steps:
normalize rescales every criterion to [0, 1].weigh computes the importance of each criterion. You can also set the weights yourself.score gives each alternative a score.Optimizer.get_rank runs the three steps. Every step takes its method as a name, such as LINEAR2 or TOPSIS, in any case.
The functions use these parameter names throughout:
x_matrix is a decision matrix before normalization.z_matrix is a normalized decision matrix, with every value in [0, 1].is_benefit_x and is_benefit_z flag each criterion as a benefit (True, a high value is better) or a cost (False, a low value is better).w_vector holds the weight of each criterion. The weights sum to 1.This module adapts code from mcdm, Copyright (c) 2020-2022 Dimitrios-Georgios Akestoridis, released under the MIT License.
Each method checks its inputs first and raises ValueError if they do not suit it.
True if every element of z_matrix is in [0, 1].
True if no weight in w_vector is negative and the weights sum to 1.
Raise ValueError if the inputs do not suit scoring method s_method.
Raise ValueError if the inputs do not suit weighting method w_method.
Raise ValueError if the inputs do not suit normalization method n_method.
Normalization rescales each criterion so that criteria measured in different units can be compared. LINEAR1 and LINEAR2 also turn every cost criterion into a benefit criterion.
Divide each benefit criterion by its maximum, and the minimum of each cost criterion by its values. Every criterion becomes a benefit criterion.
Rescale each criterion to [0, 1] between its minimum and maximum, reversed for cost criteria. Every criterion becomes a benefit criterion.
Divide each criterion by its sum. Benefit and cost flags are unchanged.
Divide each criterion by its Euclidean norm. Benefit and cost flags are unchanged.
def normalize(
x_matrix:<built-in function array>, # Decision matrix
is_benefit_x:list, # Benefit (`True`) or cost (`False`) flag of each criterion
n_method:str, # `LINEAR1`, `LINEAR2`, `LINEAR3`, `VECTOR`, or `None` to keep a matrix already in [0, 1]
)->tuple: # The normalized matrix and the new benefit flags, `(z_matrix, is_benefit_z)`Normalize x_matrix with n_method.
The examples below use three areas and three criteria: the highest measured value, the number of measurements and a prior estimate. The number of measurements is a cost criterion, because areas with fewer measurements need more sampling:
LINEAR2 maps the lowest value of each criterion to 0 and the highest to 1. It reverses the scale of the cost criterion. Area 2 has the most measurements and gets 0:
array([[1. , 0.66666667, 0.42857143],
[0. , 1. , 1. ],
[0.6 , 0. , 0. ]])
Missing values stay NaN. Each normalizer computes its column statistics from the values that are present. A missing value does not change how the rest of its column is normalized:
The CRITIC and VIC weighting methods measure how much criteria overlap by correlating the columns of the decision matrix.
Absolute Pearson correlation between every pair of columns of z_matrix.
Distance correlation between every pair of columns of z_matrix.
Squared distance covariance between every pair of columns of z_matrix.
Absolute difference between every pair of elements of z_vector.
Double-centre dmatrix: subtract its row and column means, then add its grand mean.
Squared distance covariance of two columns.
Squared distance correlation of two columns.
Pearson correlation between every pair of columns of z_matrix.
Correlation between every pair of columns of z_matrix, computed with c_method.
Weighting methods derive the importance of each criterion from the data. Every method returns weights that sum to 1.
Criterion weights from the Entropy Measure (EM) method.
Equal weights for every criterion, from the Mean Weights (MW) method.
Criterion weights proportional to the standard deviation of each column, from the Standard Deviation (SD) method.
Criterion weights from the Variability and Interdependencies of Criteria (VIC) method.
Criterion weights from the Criteria Importance Through Intercriteria Correlation (CRITIC) method.
Criterion weights of z_matrix, computed with w_method.
MW gives every criterion the same weight. CRITIC gives more weight to criteria that vary more and correlate less with the others. Here it gives the first criterion almost half of the total weight:
Scoring methods combine the normalized criteria and their weights into one score per alternative.
Score each alternative by its relative closeness to the ideal alternative, from 0 to 1, with the Technique for Order Preference by Similarity to Ideal Solution (TOPSIS). Higher is better.
Score each alternative by its Euclidean distance to the ideal alternative, with Compromise Programming (CP). Lower is better.
def score(
z_matrix:<built-in function array>, # Normalized decision matrix
is_benefit_z:list, # Benefit (`True`) or cost (`False`) flag of each criterion
w_vector:list, # Weight of each criterion
s_method:str, # `CP` or `TOPSIS`
)->tuple: # The scores, and `True` if higher scores rank first, as `(s_vector, desc_order)`Score each alternative of z_matrix with s_method.
score returns the scores and desc_order. desc_order is True when higher scores rank first. TOPSIS ranks area 0 first, then area 1, then area 2:
array([0.75394406, 0.42133458, 0.41935961])
CP also ranks area 0 first, but it ranks area 2 above area 1. Lower CP scores rank first: