Verbose MCDA and output

The pymcdm library provides a feature that enables users to generate and document all the internal steps of MCDA methods, offering insights into the intermediate calculations and processes. This functionality is particularly useful for understanding how the final results are derived, verifying the correctness of computations, or preparing detailed reports.

In this example, we demonstrate how to use this functionality to output the intermediate steps of an MCDA method in either LaTeX or plain text format.

Decision problem definition

First, we need to define the decision problem. There are also options to create pretty formatted table with criteria descriptions.

Consider example, where we want to choose used car, based on mileage, price and manufacturing year.

[1]:
import numpy as np
import pymcdm as pm

# This two are lists are optional, only for criteria description table
# You don't neet to define them, if you don't want
criteria_names = ['Mileage', 'Price', 'Year']
criteria_units = ['k km', 'k PLN', 'Year']

# Define the decision matrix or input it from the file
matrix = np.array([
    [ 94.0, 69.9, 2017],
    [297.0, 42.0, 2013],
    [205.0, 68.9, 2015],
    [360.0, 36.9, 2014],
    [ 86.0, 59.9, 2017],
    [ 79.6, 63.8, 2017],
    [113.0, 56.9, 2015],
    [171.0, 58.0, 2016]
])

# We define criteria weights using RANCOM method:
rancom = pm.weights.subjective.RANCOM(scoring=[3, 5, 1])
weights = rancom()

# We define types as min, min, max:
types = [-1, -1, 1]

# Next, use pymcdm.io module for genereting criteria description table and output it
problem = pm.io.MCDA_problem(matrix=matrix,
                             weights=weights,
                             types=types,
                             criteria_names=criteria_names,
                             criteria_units=criteria_units)
# Normal output as str
print(problem, '\n')

# Output as LaTeX
print(problem.to_latex())
Criteria description.
  $C_i$ Criterion Name  Unit  Weight Type
$C_{1}$        Mileage  k km  0.3333  Min
$C_{2}$          Price k PLN  0.5556  Min
$C_{3}$           Year  Year  0.1111  Max

\begin{table}[h]
\caption{Criteria description.}
\label{crit_desc}
\begin{tabular}{lllrl}
\toprule
$C_i$ & Criterion Name & Unit & Weight & Type \\
\midrule
$C_{1}$ & Mileage & k km & 0.3333 & Min \\
$C_{2}$ & Price & k PLN & 0.5556 & Min \\
$C_{3}$ & Year & Year & 0.1111 & Max \\
\bottomrule
\end{tabular}
\end{table}

Application of the MCDM methods with verbose argument

Next, we can apply chosed decision method to create preference vector and then ranking. In this example we will use the TOPSIS method with default normalization (min-max).

[2]:
topsis = pm.methods.TOPSIS()

pref = topsis(matrix, weights, types)
rank = topsis.rank(pref)

print(rank)
[7. 2. 8. 1. 4. 6. 3. 5.]

Hovewer, if we want to investigate the process of the calculations we should add verbose=True parameter to the call.

This makes the TOPSIS method return not preferences, but MCDA_Results object, which contains and manage all intermediate results and allow to format them in different output formats.

[3]:
results = topsis(matrix, weights, types, verbose=True)

print(results)
Results for the TOPSIS method.

Decision matrix ($x_{ij}$)
$A_{i}$  $C_{1}$  $C_{2}$  $C_{3}$
$A_{1}$  94.0000  69.9000     2017
$A_{2}$ 297.0000  42.0000     2013
$A_{3}$ 205.0000  68.9000     2015
$A_{4}$ 360.0000  36.9000     2014
$A_{5}$  86.0000  59.9000     2017
$A_{6}$  79.6000  63.8000     2017
$A_{7}$ 113.0000  56.9000     2015
$A_{8}$ 171.0000  58.0000     2016

Normalized decision matrix ($r_{ij}$)
$A_{i}$  $C_{1}$  $C_{2}$  $C_{3}$
$A_{1}$   0.9486   0.0000   1.0000
$A_{2}$   0.2247   0.8455   0.0000
$A_{3}$   0.5528   0.0303   0.5000
$A_{4}$   0.0000   1.0000   0.2500
$A_{5}$   0.9772   0.3030   1.0000
$A_{6}$   1.0000   0.1848   1.0000
$A_{7}$   0.8809   0.3939   0.5000
$A_{8}$   0.6740   0.3606   0.7500

Weighted normalized decision matrix ($v_{ij}$)
$A_{i}$  $C_{1}$  $C_{2}$  $C_{3}$
$A_{1}$   0.3162   0.0000   0.1111
$A_{2}$   0.0749   0.4697   0.0000
$A_{3}$   0.1843   0.0168   0.0556
$A_{4}$   0.0000   0.5556   0.0278
$A_{5}$   0.3257   0.1684   0.1111
$A_{6}$   0.3333   0.1027   0.1111
$A_{7}$   0.2936   0.2189   0.0556
$A_{8}$   0.2247   0.2003   0.0833

Negative Ideal Solution, Positive Ideal Solution
$C_{j}$  $v^{-}_{j}$  $v^{+}_{j}$
$C_{1}$       0.0000       0.3333
$C_{2}$       0.0000       0.5556
$C_{3}$       0.0000       0.1111

Distance from NIS, Distance from PIS, Final preference values, Final ranking
$A_{i}$  $D_i^-$  $D_i^+$  $P_i$  $R_{i}$
$A_{1}$   0.3352   0.5558 0.3762        7
$A_{2}$   0.4756   0.2941 0.6179        2
$A_{3}$   0.1932   0.5617 0.2559        8
$A_{4}$   0.5562   0.3436 0.6182        1
$A_{5}$   0.3831   0.3873 0.4973        4
$A_{6}$   0.3661   0.4529 0.4470        6
$A_{7}$   0.3704   0.3436 0.5188        3
$A_{8}$   0.3123   0.3725 0.4561        5

Total 5 tables.

[4]:
print(results.to_latex())
Results for the TOPSIS method.

\begin{table}[h]
\centering
\caption{Decision matrix ($x_{ij}$)}
\label{tab:topsis_matrix}
\begin{tabular}{lrrr}
\toprule
$A_{i}$ & $C_{1}$ & $C_{2}$ & $C_{3}$ \\
\midrule
$A_{1}$ & 94.0000 & 69.9000 & 2017 \\
$A_{2}$ & 297.0000 & 42.0000 & 2013 \\
$A_{3}$ & 205.0000 & 68.9000 & 2015 \\
$A_{4}$ & 360.0000 & 36.9000 & 2014 \\
$A_{5}$ & 86.0000 & 59.9000 & 2017 \\
$A_{6}$ & 79.6000 & 63.8000 & 2017 \\
$A_{7}$ & 113.0000 & 56.9000 & 2015 \\
$A_{8}$ & 171.0000 & 58.0000 & 2016 \\
\bottomrule
\end{tabular}
\end{table}


\begin{table}[h]
\centering
\caption{Normalized decision matrix ($r_{ij}$)}
\label{tab:topsis_nmatrix}
\begin{tabular}{lrrr}
\toprule
$A_{i}$ & $C_{1}$ & $C_{2}$ & $C_{3}$ \\
\midrule
$A_{1}$ & 0.9486 & 0.0000 & 1.0000 \\
$A_{2}$ & 0.2247 & 0.8455 & 0.0000 \\
$A_{3}$ & 0.5528 & 0.0303 & 0.5000 \\
$A_{4}$ & 0.0000 & 1.0000 & 0.2500 \\
$A_{5}$ & 0.9772 & 0.3030 & 1.0000 \\
$A_{6}$ & 1.0000 & 0.1848 & 1.0000 \\
$A_{7}$ & 0.8809 & 0.3939 & 0.5000 \\
$A_{8}$ & 0.6740 & 0.3606 & 0.7500 \\
\bottomrule
\end{tabular}
\end{table}


\begin{table}[h]
\centering
\caption{Weighted normalized decision matrix ($v_{ij}$)}
\label{tab:topsis_wnmatrix}
\begin{tabular}{lrrr}
\toprule
$A_{i}$ & $C_{1}$ & $C_{2}$ & $C_{3}$ \\
\midrule
$A_{1}$ & 0.3162 & 0.0000 & 0.1111 \\
$A_{2}$ & 0.0749 & 0.4697 & 0.0000 \\
$A_{3}$ & 0.1843 & 0.0168 & 0.0556 \\
$A_{4}$ & 0.0000 & 0.5556 & 0.0278 \\
$A_{5}$ & 0.3257 & 0.1684 & 0.1111 \\
$A_{6}$ & 0.3333 & 0.1027 & 0.1111 \\
$A_{7}$ & 0.2936 & 0.2189 & 0.0556 \\
$A_{8}$ & 0.2247 & 0.2003 & 0.0833 \\
\bottomrule
\end{tabular}
\end{table}


\begin{table}[h]
\centering
\caption{Negative Ideal Solution, Positive Ideal Solution}
\label{tab:topsis_nis_pis}
\begin{tabular}{lrr}
\toprule
$C_{j}$ & $v^{-}_{j}$ & $v^{+}_{j}$ \\
\midrule
$C_{1}$ & 0.0000 & 0.3333 \\
$C_{2}$ & 0.0000 & 0.5556 \\
$C_{3}$ & 0.0000 & 0.1111 \\
\bottomrule
\end{tabular}
\end{table}


\begin{table}[h]
\centering
\caption{Distance from NIS, Distance from PIS, Final preference values, Final ranking}
\label{tab:topsis_dnis_dpis_pref_ranking}
\begin{tabular}{lrrrr}
\toprule
$A_{i}$ & $D_i^-$ & $D_i^+$ & $P_i$ & $R_{i}$ \\
\midrule
$A_{1}$ & 0.3352 & 0.5558 & 0.3762 & 7 \\
$A_{2}$ & 0.4756 & 0.2941 & 0.6179 & 2 \\
$A_{3}$ & 0.1932 & 0.5617 & 0.2559 & 8 \\
$A_{4}$ & 0.5562 & 0.3436 & 0.6182 & 1 \\
$A_{5}$ & 0.3831 & 0.3873 & 0.4973 & 4 \\
$A_{6}$ & 0.3661 & 0.4529 & 0.4470 & 6 \\
$A_{7}$ & 0.3704 & 0.3436 & 0.5188 & 3 \\
$A_{8}$ & 0.3123 & 0.3725 & 0.4561 & 5 \\
\bottomrule
\end{tabular}
\end{table}


Total 5 tables.