声明:文章参考数学建模清风的网课编写。
Topsis优劣解距离法
给定如下一张表,要求得出综合能力最强的人
姓名 | 高数 |
---|---|
张三 | 78 |
李四 | 62 |
小明 | 99 |
很显然排个序,然后统计排名:
姓名 | 高数 | 排名 |
---|---|---|
张三 | 78 | 2 |
李四 | 62 | 3 |
小明 | 99 | 1 |
此时很明显,小明的能力最强。方法并没有问题并且得出了正确的结果,但评分的标准是有一定的问题的。
此方法并没有反映真实的成绩信息。例如,小明的成绩改为80或李四的成绩改为0分,排名是仍然不会有任何改变的。
此时,我们定义一种新的评分准则 ( x i − m i n ) / ( m a x − m i n ) (x_{i} - min)/(max - min) (xi−min)/(max−min),在这种评分标准下表中的评分应为:
姓名 | 高数 | 评分 |
---|---|---|
张三 | 78 | 0.4324 |
李四 | 62 | 0 |
小明 | 99 | 1 |
( x i − m i n ) / ( m a x − x i + x i − m i n ) (x_{i} - min) / (max - x_{i} + x_{i} - min) (xi−min)/(max−xi+xi−min)
x与最小值之间的距离 / (x与最大值之间的距离 + x与最小值之间的距离)
Topsis步骤
1.指标正向化
姓名 | 高数 | 违纪次数 |
---|---|---|
张三 | 78 | 2 |
李四 | 62 | 3 |
小明 | 99 | 4 |
表中不同指标的评价标准是不同的。显然,高数成绩越高越好,但违纪次数应该越低越好。
指标通常可以分类为以下几种:
极大型指标:极大型指标又叫效益型指标。像表中的成绩,应当是越大越好。
极小型指标:极小型指标又叫成本型指标。像表中的违纪次数,越少越好。
中间型指标:例如评价湖水水质时,PH值应当越趋近中性越好(PH = 7)这就要求PH值越接近7越好。
区间型指标:评价一个人的健康指标时,体温应当位于36 - 37度最好。
将各种指标统一为极大型指标,有利于统一对表中数据进行评价。
极小型指标标准化:
z
i
=
m
a
x
−
x
i
z_{i} = max - x_{i}
zi=max−xi极小型指标标准化代码(trans_min.m):
% 将极小型转化为极大型
function [C] = trans_min(A)
% A列向量,为极小型
C = max(A) - A;
end
中间型指标标准化,假设中间值为a:
M
=
m
a
x
(
a
b
s
(
x
i
−
a
)
)
z
i
=
1
−
a
b
s
(
x
i
−
a
)
/
M
M = max(abs(x_{i} - a)) \\ z_{i} = 1 - abs(x_{i} - a)/M
M=max(abs(xi−a))zi=1−abs(xi−a)/M中间型指标标准化代码(trans_mid.m):
% 将中间型转化为极大型
function [C] = trans_mid(A, a)
% A为待转化的中间型列向量
% a为中间值 如:ph = 7
M = max(abs(A - a));
C = 1 - abs(A - a) ./ M;
end
区间型指标标准化, 假设a:区间左端点,b:区间右端点:
M
=
m
a
x
(
m
a
x
−
b
,
a
−
m
i
n
)
z
i
=
{
1
−
(
a
−
x
i
)
/
M
,
x
i
<
a
1
,
a
<
=
x
i
<
=
b
1
−
(
x
i
−
b
)
/
M
,
a
<
x
i
M = max(max - b, a - min) \\ z_{i} = \left\{\begin{matrix} 1 - (a - x_{i})/M \ \ \ \ \ ,x_{i} < a \\ 1 \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ,a <= x_{i} <= b \\ 1 - (x_{i} - b)/M \ \ \ \ \ ,a < x_{i} \end{matrix}\right.
M=max(max−b,a−min)zi=⎩
⎨
⎧1−(a−xi)/M ,xi<a1 ,a<=xi<=b1−(xi−b)/M ,a<xi区间型指标标准化代码(trans_seg.m):
% 区间型转化为极大型
function [C] = trans_seg(A, s)
% A为带转化的区间型列向量
% s(1)为区间左端点; s(2)为区间右端点
a = s(1);
b = s(2);
M = max(max(A) - b, a - min(A));
C = A;
for i = 1 : size(A)
if A(i) < a
C(i) = 1 - (a - A(i))/M;
elseif A(i) > b
C(i) = 1 - (A(i) - b)/M;
else
C(i) = 1;
end
end
end
2.指标标准化
姓名 | 高数 | 违纪次数 | 正向化后违纪指标 |
---|---|---|---|
张三 | 78 | 2 | 2 |
李四 | 62 | 3 | 1 |
小明 | 99 | 4 | 0 |
得到正向化的数据如何评价三个人的综合能力水平?很明显直接进行相加得到的并不是我们想要的结果。
标准化:因为这里还有一个待解决的问题,那就是各个指标间的量纲是不同的,统一量纲,就是标准化。
标准化公式,元素除以元素所在列的平方和再开根: x i j / ( ∑ i = 1 n x i j 2 ) 1 2 x_{ij} \ / \ (\sum_{i = 1}^{n} \ x_{ij}^2)^{\frac{1}{2}} xij / (∑i=1n xij2)21
3.计算指标得分
假设有n个要评价的对象,m个评价指标已经正向化且标准化的矩阵:
Z
=
[
z
11
z
12
.
.
.
z
1
n
z
21
z
22
.
.
.
z
2
n
⋮
⋮
⋱
⋮
z
n
1
z
n
2
.
.
.
z
n
n
]
Z = \begin{bmatrix} z_{11} & z_{12} & ... & z_{1n}\\ z_{21} & z_{22} & ... & z_{2n}\\ \vdots & \vdots & \ddots & \vdots\\ z_{n1} & z_{n2} & ... & z_{nn} \end{bmatrix}
Z=⎣
⎡z11z21⋮zn1z12z22⋮zn2......⋱...z1nz2n⋮znn⎦
⎤
定义最大值:
Z
+
=
(
Z
1
+
,
Z
2
+
,
…
,
Z
m
+
)
=
(
m
a
x
(
z
11
,
z
21
,
.
.
.
,
z
n
1
)
,
m
a
x
(
z
12
,
z
22
,
.
.
.
,
z
n
2
)
,
.
.
.
,
m
a
x
(
z
1
m
,
z
2
m
,
.
.
.
,
z
n
m
)
)
\begin{align*} Z^{+} &= (Z_{1}^{+},Z_{2}^{+},\dots ,Z_{m}^{+}) \\ &= (max(z_{11}, z_{21},...,z_{n1}),max(z_{12}, z_{22},...,z_{n2}),...,max(z_{1m}, z_{2m},...,z_{nm}) ) \end{align*}
Z+=(Z1+,Z2+,…,Zm+)=(max(z11,z21,...,zn1),max(z12,z22,...,zn2),...,max(z1m,z2m,...,znm))
定义最小值:
Z
−
=
(
Z
1
−
,
Z
2
−
,
…
,
Z
m
−
)
=
(
m
i
n
(
z
11
,
z
21
,
.
.
.
,
z
n
1
)
,
m
i
n
(
z
12
,
z
22
,
.
.
.
,
z
n
2
)
,
.
.
.
,
m
i
n
(
z
1
m
,
z
2
m
,
.
.
.
,
z
n
m
)
)
\begin{align*} Z^{-} &= (Z_{1}^{-},Z_{2}^{-},\dots ,Z_{m}^{-}) \\ &= (min(z_{11}, z_{21},...,z_{n1}),min(z_{12}, z_{22},...,z_{n2}),...,min(z_{1m}, z_{2m},...,z_{nm}) ) \end{align*}
Z−=(Z1−,Z2−,…,Zm−)=(min(z11,z21,...,zn1),min(z12,z22,...,zn2),...,min(z1m,z2m,...,znm))
定义第i个评价对象与最大值的距离为:
D
i
+
=
∑
j
=
1
m
(
Z
j
+
−
z
i
j
)
2
D_{i}^{+} = \sqrt{\sum_{j=1}^{m}(Z_{j}^{+} - z_{ij} )^2 }
Di+=j=1∑m(Zj+−zij)2
定义第i个评价对象与最小值的距离为:
D
i
−
=
∑
j
=
1
m
(
Z
j
−
−
z
i
j
)
2
D_{i}^{-} = \sqrt{\sum_{j=1}^{m}(Z_{j}^{-} - z_{ij} )^2 }
Di−=j=1∑m(Zj−−zij)2
则第i个对象的未归一化得分为:
S
i
=
D
i
−
D
i
+
+
D
i
−
S_{i} = \frac{D_{i}^{-}}{D_{i}^{+}+D_{i}^{-}}
Si=Di++Di−Di−topsis完整matlab代码(注意还有指标正向化的函数):
% clear;clc
% 输入为n行m列的矩阵, 每一行是一个待评价项目, 每一列是一种评价指标
% A = input('请输入待评价的矩阵[]:');
[n, m] = size(A);
% 正向化
% 待正向化的列
col = input('请输入待正向化的列[]:');
for i = 1 : size(col, 2)
kind = input(['请输入' num2str(col(i)) '列所属类型(1:极小型;2:中间型;3:区间型):']);
% 列
c = col(i);
if kind == 1
A(:, c) = trans_min(A(:, c));
elseif kind == 2
a = input('请输入中间型的中间值:');
A(:, c) = trans_mid(A(:, c), a);
elseif kind == 3
s = input('请输入区间型的两个端点[a, b]:');
A(:, c) = trans_seg(A(:, c), s);
else
disp('输入类型有误!');
end
end
disp('正向化后的矩阵:');
disp(A);
% 标准化
stan_A = A ./ repmat(sum(A.^2).^0.5, n, 1);
disp('标准化后的矩阵:');
disp(stan_A);
% 计算得分
z_max = repmat(max(stan_A), n, 1);
z_min = repmat(min(stan_A), n, 1);
% 与最大值的距离
D_max = sum((z_max - stan_A).^2, 2).^0.5;
% 与最小值的距离
D_min = sum((z_min - stan_A).^2, 2).^0.5;
score = D_min ./ (D_max + D_min);
score = score ./ sum(score);
disp('最终得分为:');
disp(score);
% 计算位序
[score, ind] = sort(score, 'descend');
disp('每个项目的位序为:');
disp(ind);