Illustrative example of Temporal PROMETHEE II

This example demonstrates how to use the Temporal PROMETHEE II method implemented in pyrepo-mcda.

The method evaluates alternatives over multiple time periods. First, PROMETHEE II net flows are calculated separately for each period. Then, variability and direction of changes are analyzed using DARIA. Finally, the scores from the most recent period are adjusted according to temporal variability.

Import required packages

[1]:
import numpy as np
import pandas as pd

from pyrepo_mcda.mcda_methods import Temporal_PROMETHEE_II, DARIA
from pyrepo_mcda.additions import rank_preferences
from pyrepo_mcda.weighting_methods import equal_weighting
from pyrepo_mcda.promethee_preference_functions import (
    preference_usual_function
)

Decision matrices

Three decision matrices are prepared for three consecutive years.

Rows represent alternatives and columns represent criteria. The same alternatives and criteria must be present in all periods.

[2]:
matrices = {
    "2022": np.array([
        [70, 70, 70],
        [50, 55, 60],
        [90, 90, 85],
        [86, 88, 87]
    ]),
    "2023": np.array([
        [71, 70, 69],
        [68, 70, 72],
        [78, 76, 74],
        [86, 88, 87]
    ]),
    "2024": np.array([
        [70, 71, 70],
        [86, 88, 87],
        [65, 63, 60],
        [86, 88, 87]
    ])
}

alternative_names = ["A1", "A2", "A3", "A4"]

Weights and criteria types

The first criterion is a profit criterion. The second criterion is a cost criterion. The third criterion is a profit criterion.

Equal weighting is used.

[3]:
weights = equal_weighting(matrices["2022"])

types = np.array([
    1,   # profit criterion
   -1,   # cost criterion
    1   # profit criterion
])

Create the Temporal PROMETHEE II object

[4]:
tp = Temporal_PROMETHEE_II()

Calculate temporal preference scores

Standard deviation is used as the default variability measure.

[5]:
scores, (variability, direction, net_flows) = tp(
    matrices = matrices,
    weights = weights,
    types = types,
    preference_functions = [
        preference_usual_function,
        preference_usual_function,
        preference_usual_function
    ],
    alt_names = alternative_names
)

Display results

[6]:
results = pd.DataFrame(
    {
        "Score": scores,
        "Variability": variability,
        "Direction": direction,
        "Rank": rank_preferences(scores, reverse=True)
    },
    index = alternative_names
)

results
[6]:
Score Variability Direction Rank
A1 -0.111111 0.052378 0.0 3
A2 0.462250 0.240027 1.0 1
A3 -0.542846 0.209513 -1.0 4
A4 0.169844 0.052378 -1.0 2

PROMETHEE II net flows in all periods

[7]:
net_flows
[7]:
2022 2023 2024
Alternatives
A1 -0.111111 -0.222222 -0.111111
A2 -0.333333 -0.222222 0.222222
A3 0.111111 0.111111 -0.333333
A4 0.333333 0.333333 0.222222

Use the Gini coefficient as a variability measure

Temporal PROMETHEE II allows any variability measure compatible with DARIA.

[8]:
daria = DARIA()

scores_gini, (variability_gini, direction_gini, _) = tp(
    matrices = matrices,
    weights = weights,
    types = types,
    variability_function = daria._gini,
    preference_functions = [
        preference_usual_function,
        preference_usual_function,
        preference_usual_function
    ],
    alt_names = alternative_names
)

Compare variability measures

[9]:
comparison = pd.DataFrame(
    {
        "STD scores": scores,
        "Gini scores": scores_gini
    },
    index = alternative_names
)

comparison
[9]:
STD scores Gini scores
A1 -0.111111 -0.111111
A2 0.462250 -0.888889
A3 -0.542846 2.333333
A4 0.169844 0.138889
[10]:
comparison_rankings = pd.DataFrame(
    {
        "STD rank": rank_preferences(scores, reverse = True),
        "Gini rank": rank_preferences(scores_gini, reverse = True)
    },
    index = alternative_names
)

comparison_rankings
[10]:
STD rank Gini rank
A1 3 3
A2 1 4
A3 4 1
A4 2 2
[ ]: