文章目录
- 前言
- 原理
- 步骤
- 代码实例
前言
Vikor 归根到底其实属于一种综合评价方法。说到综合评价方法,TOPSIS(结合熵权法使用)、灰色关联度分析、秩和比法等方法你应该耳熟能详。Vikor 未必比这些方法更出色,但是可以拓展我们的视野。接下来先介绍 Vikor 方法的原理,再结合一个例子使用 Vikor 方法进行 Python 建模。
原理
Vikor 方法是一种基于多个标准,选择最好的(折中的)策略的方法。非常类似于 TOPSIS 综合评价方法。
多标准决策(MCDM)问题描述为:现有
n
n
n 个可行方案,每个方案均有
m
m
m 个指标,用
f
i
j
f_{ij}
fij 表示第
i
i
i 个方案的第
j
j
j 个指标。现在要求出多准则意义上的最佳(折衷)解决方案。例如,现在有
A
1
−
A
4
A_1-A_4
A1−A4 四架飞机(即
n
=
4
n=4
n=4),每架飞机有
m
=
6
m=6
m=6 个指标,如下表所示,请你选出多准则意义上最好的飞机。
飞机编号 | 最大速度 | 飞行半径 | 最大负载 | 费用 | 可靠性 | 灵敏度 |
---|---|---|---|---|---|---|
A 1 A_1 A1 | 2.0 2.0 2.0 | 1500 1500 1500 | 20000 20000 20000 | 5500000 5500000 5500000 | 0.5 0.5 0.5 | 1 1 1 |
A 2 A_2 A2 | 2.5 2.5 2.5 | 2700 2700 2700 | 18000 18000 18000 | 6500000 6500000 6500000 | 0.3 0.3 0.3 | 0.5 0.5 0.5 |
A 3 A_3 A3 | 1.8 1.8 1.8 | 2000 2000 2000 | 21000 21000 21000 | 4500000 4500000 4500000 | 0.7 0.7 0.7 | 0.7 0.7 0.7 |
A 4 A_4 A4 | 2.2 2.2 2.2 | 1800 1800 1800 | 20000 20000 20000 | 5000000 5000000 5000000 | 0.5 0.5 0.5 | 0.5 0.5 0.5 |
这是司守奎等的《Python 数学实验与建模》上的一个例题。
步骤
Vikor 评价法的步骤如下:
- 对每个指标 f i j f_{ij} fij 进行处理,使得处理后的指标都是极大型指标,仍用 f i j f_{ij} fij 表示。无需归一化、无量纲化。
极大型指标指的是值越大越好的指标,如效率、产能、可靠性等,又称“效益型指标”。相对地,极小型指标指的是值越小越好的指标,如能耗、费用等,又称“成本性指标”。还有一类中间型指标,其值太大太小都不好,位于一个区间才合适,例如人的 BMI。
- 对每个指标确定正理想解 f j + = max 1 ≤ i ≤ n ( f i j ) {{f}_{j}^{+}}={\max\limits_{1\le i\le n}(}{{f}_{ij}}) fj+=1≤i≤nmax(fij) ,以及负理想解 f j − = min 1 ≤ i ≤ n ( f i j ) {{f}_{j}^{-}}={\min\limits_{1\le i\le n}(}{{f}_{ij}}) fj−=1≤i≤nmin(fij)。
- 对于每个方案,计算 S S S 值(综合距离,表示方案与正理想解之间的综合距离)和 R R R 值(个体最大距离,表示方案在最不利标准下与正理想解之间的距离): S i = ∑ j = 1 m w j ( f j + − f i j ) f j + − f j − S_i=\sum_{j=1}^{m}{\cfrac{w_j(f_j^+-f_{ij})}{f_j^+-f_j^-}} Si=j=1∑mfj+−fj−wj(fj+−fij) R i = max 1 ≤ j ≤ m ( w j ( f j + − f i j ) f j + − f j − ) R_i=\max\limits_{1\leq j\leq m}\left(\cfrac{w_j(f_j^+-f_{ij})}{f_j^+-f_j^-}\right) Ri=1≤j≤mmax(fj+−fj−wj(fj+−fij))这里 w j w_j wj 是给每个标注取的权重,默认情况下那么都取 1 / m 1/m 1/m。
- 计算每个方案的
Q
Q
Q 值,这个值是综合所有方案的
S
S
S 值与
R
R
R 值得出的结果:
Q
i
=
v
×
S
i
−
S
+
S
−
−
S
+
+
(
1
−
v
)
×
R
i
−
R
+
R
−
−
R
+
{{Q}_{i}}=v\times \frac{{{S}_{i}}-{{S}^{+}}}{{{S}^{-}}-{{S}^{+}}}+(1-v)\times \frac{{{R}_{i}}-{{R}^{+}}}{{{R}^{-}}-{{R}^{+}}}
Qi=v×S−−S+Si−S++(1−v)×R−−R+Ri−R+其中,
- S + = min 1 ≤ i ≤ n ( S i ) S^+=\min\limits_{1\leq i\leq n}(S_i) S+=1≤i≤nmin(Si), S − = max 1 ≤ i ≤ n ( S i ) S^-=\max\limits_{1\leq i\leq n}(S_i) S−=1≤i≤nmax(Si), R + = min 1 ≤ i ≤ n ( R i ) R^+=\min\limits_{1\leq i\leq n}(R_i) R+=1≤i≤nmin(Ri), R − = max 1 ≤ i ≤ n ( R i ) R^-=\max\limits_{1\leq i\leq n}(R_i) R−=1≤i≤nmax(Ri)。
- v v v 是一个在 0 0 0 到 1 1 1 之间的权重,通常取 0.5 0.5 0.5,表示 S S S 值和 R R R 值的平衡。当 v > 0.5 v>0.5 v>0.5 时,表示根据最大群体效用的决策机制进行决策;当 v < 0.5 v<0.5 v<0.5 时,表示根据最小个体遗憾的决策机制进行决策。数学建模时,这个 v v v 可能适合拿来灵敏度分析。
- 对这个 Q Q Q 值进行升序排序,就是各个方案的最终排名。一般取 Q Q Q 值最小的为最优。
参考文献:VIKOR方法_vikor方法简介-CSDN博客
代码实例
就使用上面评价飞机的那个例子。首先观察到费用是一个极小型指标,需要极大化。书上直接给出了使用比例变换法将所有指标极大归一化的结果,因此下面的代码中直接使用这个结果:
import pandas as pd
import numpy as np
from sklearn import preprocessing
import matplotlib.pyplot as plt
# 这个就是极大归一化后的数据
data = pd.DataFrame([[0.8,0.5556,0.9524,0.8182,0.7143,1],
[1,1,0.8571,0.6923,0.4286,0.5],
[0.72,0.7407,1,1,1,0.7],
[0.88,0.6667,0.9524,0.9,0.7143,0.5]])
# 确定正负理想解
f_best = data.max(axis = 0)
f_worst = data.min(axis = 0)
# 计算 S 和 R
S = []
R = []
for i in range(data.index.size):
S.append(sum((f_best - data.iloc[i,:])/(f_best - f_worst))/data.columns.size)
R.append(max((f_best - data.iloc[i,:])/(f_best - f_worst))/data.columns.size)
# 计算 Q
S = np.array(S)
R = np.array(R)
qq = [[],[],[],[]]
v_arr = np.linspace(0,1,1000)
for v in v_arr:
Q = 0
if(S.max() - S.min() != 0):
Q += v * (S - S.min()) / (S.max() - S.min())
if(R.max() - R.min() != 0):
Q += (1 - v) * (R - R.min()) / (R.max() - R.min())
for i in range(len(Q)):
qq[i].append(Q[i])
# 作图部分
plt.rc('text',usetex = True)
plt.plot(v_arr,qq[0],label = '$A_1$')
plt.plot(v_arr,qq[1],label = '$A_2$')
plt.plot(v_arr,qq[2],label = '$A_3$')
plt.plot(v_arr,qq[3],label = '$A_4$')
plt.xlabel('$v$')
plt.ylabel('$Q_i$')
plt.legend()
plt.show()
上面的代码,我尝试了 ( 0 , 1 ) (0,1) (0,1) 中的许多 v v v 值,作出了 Q i ( i = 1 , 2 , 3 , 4 ) Q_i(i=1,2,3,4) Qi(i=1,2,3,4) 关于 v v v 的图线,如下图所示:
可以看出,无论 v v v 怎么选,结果都是固定的: A 3 > A 1 > A 4 > A 2 {{A}_{3}}>{{A}_{1}}>{{A}_{4}}>{{A}_{2}} A3>A1>A4>A2。这和熵权法的结果一样,而 TOPSIS 的结果是 A 3 > A 1 > A 2 > A 4 {{A}_{3}}>{{A}_{1}}>{{A}_{2}}>{{A}_{4}} A3>A1>A2>A4。总而言之 Vikor 还是个比较不错的方法。