Metadata-Version: 2.4
Name: mcda-promethee
Version: 0.4.1
Summary: PROMETHEE I/II/Gamma/Sort MCDA methods
Author-email: Gilles Dejaegere <gilles.dejaegere@ulb.be>
License-Expression: MIT
Project-URL: Repository, https://gitlab.ulb.be/smg/promethee
Keywords: mcda,mcdm,multi-criteria,decision,promethee
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: mcda-core>=0.2.1
Requires-Dist: numpy>=1.25
Provides-Extra: notebook
Requires-Dist: matplotlib>=3.7; extra == "notebook"
Dynamic: license-file

# promethee

Python implementation of the **PROMETHEE** family of MCDA (Multi-Criteria Decision Analysis) methods, maintained by the [SMG](https://cvchercheurs.ulb.ac.be/Site/unite/ULB806.php) research group at ULB. Built on [mcda-core](https://gitlab.ulb.be/smg/mcda-core).

Implements PROMETHEE I, II, III, Gamma, GAIA, FlowSort, and P2Clust, with all six standard preference functions.

## About SMG

The [Decision Support Systems (SMG)](https://cvchercheurs.ulb.ac.be/Site/unite/ULB806.php) group is a research lab at Université libre de Bruxelles (ULB) specialising in multi-criteria decision analysis. The group develops theoretical foundations and practical tools for MCDA, with a focus on the PROMETHEE methods.

If you are using this library for research, feel free to reach out at [gilles.dejaegere@ulb.be](mailto:gilles.dejaegere@ulb.be) — we are happy to help you apply the methods and to start scientific collaborations.

## Installation

```bash
pip install mcda-promethee
```

Python ≥ 3.9.

## Quick start

For a hands-on walkthrough, see the [demo notebook](notebooks/promethee_ii_intro.ipynb).

```python
import numpy as np
from promethee import PrometheeII, PerformanceTable, ParametersPromethee, build_preference_functions

# 4 countries evaluated on 2 indicators
table = PerformanceTable(
    values=np.array([
        [77.2, 0.887],
        [76.5, 0.832],
        [80.1, 0.919],
        [73.4, 0.798],
    ]),
    alternatives=["Country A", "Country B", "Country C", "Country D"],
    criteria=["life_expectancy", "education_index"],
    directions=[1, 1],  # maximise both
)

weights = np.array([0.5, 0.5])
prefs = build_preference_functions([
    ("v_shape_with_indifference", {"p": 5.0, "q": 1.0}),
    ("v_shape_with_indifference", {"p": 0.08, "q": 0.02}),
])

params = ParametersPromethee(weights=weights, preference_functions=prefs)
model = PrometheeII(performance_table=table, parameters=params)
model.fit()

print(model.net_flows)   # φ score per alternative
print(model.ranking)     # indices sorted best → worst
```

Parameters can also be loaded from a JSON file (see `tests/data/epi_parameters.json` for an example):

```python
import json
from promethee import ParametersPromethee

with open("parameters.json") as f:
    params = ParametersPromethee.from_dict(json.load(f))
```

## Preference functions

All six standard PROMETHEE preference functions are available:

| kind string | parameters | description |
|-------------|------------|-------------|
| `"usual"` | — | Full preference for any positive difference |
| `"u_shape"` | `q` | Step at indifference threshold |
| `"v_shape"` | `p` | Linear up to preference threshold |
| `"v_shape_with_indifference"` | `q`, `p` | Linear between indifference and preference thresholds |
| `"level"` | `q`, `p` | Half preference in the intermediate zone |
| `"gaussian"` | `s` | Smooth Gaussian curve (inflection point `s`) |

```python
from promethee import build_preference_functions

prefs = build_preference_functions([
    ("usual", {}),
    ("v_shape_with_indifference", {"q": 2.0, "p": 8.0}),
    ("gaussian", {"s": 3.0}),
])
```

## API reference

### `PrometheeII`

Computes a complete ranking via net flows φ.

| property | description |
|----------|-------------|
| `net_flows` | φ score per alternative, shape `(n,)` |
| `pairwise_preferences` | aggregated preference matrix π, shape `(n, n)` |
| `monocriterion_net_flows` | mono-criterion net flows φ_k, shape `(n, m)` |
| `ranking` | indices sorted best → worst |
| `result()` | returns `net_flows` |

All properties trigger `fit()` automatically if not already called.

### `ParametersPromethee`

| field | type | description |
|-------|------|-------------|
| `weights` | `ndarray (m,)` | criterion weights (need not sum to 1) |
| `preference_functions` | `Sequence[PreferenceFunction]` | one per criterion |

Constructors:
- `ParametersPromethee(weights, preference_functions)` — direct
- `ParametersPromethee.from_dict(data)` — from a parameter dictionary
- `ParametersPromethee.from_weights_and_criteria(weights, criteria_types, p, q)` — shorthand using V-shape with indifference

### Quality indicators

Four indicators measure how well the net flows capture the pairwise preference structure:

```python
from promethee import r_squared, additive_transitivity_index, pairwise_agreement_ratio, spectral_rank2_energy_ratio

pi  = model.pairwise_preferences
phi = model.net_flows

print(r_squared(pi, phi))                   # how well φ explains π (0–1, higher is better)
print(additive_transitivity_index(pi))      # transitivity violations (0 = perfect)
print(pairwise_agreement_ratio(pi, phi))    # pairs where pairwise order agrees with φ
print(spectral_rank2_energy_ratio(pi))      # spectral consistency of π (0–1, higher is better)
```

## Other algorithms

| class | description |
|-------|-------------|
| `PrometheeI` | Partial ranking via positive/negative flows |
| `PrometheeIII` | Interval-based preorder: each alternative gets [x(a), y(a)] centred on its net flow; overlapping intervals → indifference |
| `PrometheeGamma` | Extends II with γ-based incomparability detection ([Dejaegere & De Smet, 2023](https://onlinelibrary.wiley.com/doi/full/10.1002/mcda.1805)) |
| `PrometheeGAIA` | SVD biplot of monocriterion net flows — visualises alternatives, criteria, and the decision stick δ |
| `FlowSort` | Assigns each alternative to an ordered category using limiting reference profiles (pessimistic rule) |
| `P2Clust` | Clusters alternatives by splitting the sorted net-flow sequence at the *k−1* largest gaps |

> Demos of `PrometheeIII`, `PrometheeGAIA`, `FlowSort`, and `P2Clust` are included in the [demo notebook](notebooks/promethee_ii_intro.ipynb).

All public classes and parameter types are importable directly from `promethee`.

### `PrometheeIII` — `ParametersPrometheeIII`

Extends `ParametersPromethee` with one optional field:

| field | type | default | description |
|-------|------|---------|-------------|
| `alpha` | `float` | `1.0` | interval half-width multiplier; larger → more indifferences |

Key properties: `net_flows`, `intervals` (shape `(n, 2)`), `relation` (binary `(n, n)` outranking matrix).

### `PrometheeGAIA` — `ParametersPromethee`

Key properties: `alternatives` (2D coordinates, shape `(n, 2)`), `criteria` (shape `(m, 2)`), `delta` (decision stick, shape `(2,)`), `quality` (fraction of variance explained by the plane).

### `FlowSort` — `ParametersFlowSort`

Extends `ParametersPromethee` with:

| field | type | description |
|-------|------|-------------|
| `reference_profiles` | `ndarray (p, m)` | limiting profiles ordered best → worst |
| `profile_names` | `Sequence[str]`, optional | labels for the *p* profiles |
| `category_names` | `Sequence[str]`, optional | labels for the *p+1* categories |

Key properties: `assignments` (category index per alternative), `net_flows`.

### `P2Clust` — `ParametersP2Clust`

Extends `ParametersPromethee` with:

| field | type | description |
|-------|------|-------------|
| `k` | `int` | number of clusters |

Key properties: `assignments` (cluster index 0 = best), `net_flows`, `ranking`.

## Ecosystem

Part of the modular MCDA Python ecosystem. See [mcda-core](https://gitlab.ulb.be/smg/mcda-core) for the full picture.

## License

MIT — see [LICENSE](LICENSE).
