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 |
[ ]: