59 lines
1.9 KiB
Python
59 lines
1.9 KiB
Python
"""TOPSIS 逼近理想解排序。
|
||||
|
|
|
|||
|
|
原建议把标准化(`benefit_normalize` 等 4 个函数)单列一节,
|
|||
|
|
这里合并进 `topsis` 的 `method` 参数——因为它们是同一个流程的步骤,
|
|||
|
|
拆开反而容易出现"标准化用了一套、权重算的时候又换一套"的错位。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
from typing import Any
|
|||
|
|
|
|||
|
|
__all__ = ["topsis"]
|
|||
|
|
|
|||
|
|
|
|||
|
|
def topsis(
|
|||
|
|
X: Any,
|
|||
|
|
weights: Any = None,
|
|||
|
|
benefit_columns: Any = None,
|
|||
|
|
method: str = "vector",
|
|||
|
|
labels: Any = None,
|
|||
|
|
) -> Any:
|
|||
|
|
"""TOPSIS 综合评价。
|
|||
|
|
|
|||
|
|
Parameters
|
|||
|
|
----------
|
|||
|
|
X:
|
|||
|
|
决策矩阵,行 = 待评价方案,列 = 指标。
|
|||
|
|
weights:
|
|||
|
|
权重。`None` 时用等权(并在 `message` 里提示)。
|
|||
|
|
benefit_columns:
|
|||
|
|
效益型指标的列名/下标,其余按成本型处理。
|
|||
|
|
**必填或显式全选**,不允许默认假设——方向搞反会让排名完全颠倒。
|
|||
|
|
method:
|
|||
|
|
列向量的无量纲化方式:`"vector"`(`x/√Σx²`,TOPSIS 原始做法,默认)
|
|||
|
|
或 `"minmax"`。
|
|||
|
|
labels:
|
|||
|
|
方案名,用于结果表。
|
|||
|
|
|
|||
|
|
Returns
|
|||
|
|
-------
|
|||
|
|
`Result`:`data` 是含 `D+ / D- / closeness / rank` 四列、按 `rank` 排好的表,
|
|||
|
|
`params["weights"]` 回显实际使用的权重。
|
|||
|
|
|
|||
|
|
Notes
|
|||
|
|
-----
|
|||
|
|
* 正理想解 = 各指标最优值,负理想解 = 各指标最劣值;
|
|||
|
|
贴近度 `C = D- / (D+ + D-)`,**C 越大越好**。
|
|||
|
|
* TOPSIS 的排名对权重敏感。论文里应附"权重扰动 ±10% 后排名是否稳定"的
|
|||
|
|
敏感性分析——直接调 `solve.robustness_test`。
|
|||
|
|
|
|||
|
|
Examples
|
|||
|
|
--------
|
|||
|
|
>>> import numpy as np
|
|||
|
|
>>> r = topsis(np.array([[1., 2.], [3., 1.], [2., 3.]]), benefit_columns=[0, 1])
|
|||
|
|
>>> list(r.data["rank"])
|
|||
|
|
[2, 3, 1]
|
|||
|
|
"""
|
|||
|
|
# TODO(L1) ★ S 档:配完整函数卡片
|
|||
|
|
raise NotImplementedError
|