topsis的全称是“逼近于理想之的排序方法”
是Hwang和Poon于1981年提出的一种适用于根据多项指标,对多个方案进行比较选择的分析方法,这种方法的中心思想在于首先确定各项指标的正理想值和负理想值,所谓正理想值是设想的最好值(方案),它的各个属性值都到达各候选方案中最好的值,而负理想值则相反,然后求出各个方案与理想值,负理想值之间的加权欧氏距离,由此得出个方案与最优方案的接近程度,作为评价方案的优劣标准
河流 | 含氧量(PPM) | PH值 | 细菌总数(个/ML) | 植物性营养物量(PPM) |
---|---|---|---|---|
A | 4.69 | 6.59 | 51 | 11.94 |
B | 2.03 | 7.86 | 19 | 6.46 |
C | 9.11 | 6.31 | 46 | 8.91 |
D | 8.61 | 7.05 | 46 | 26.43 |
E | 7.13 | 6.5 | 50 | 23.57 |
F | 2.39 | 6.77 | 38 | 24.62 |
G | 7.69 | 6.79 | 38 | 6.01 |
H | 9.3 | 6.81 | 27 | 31.57 |
I | 5.45 | 7.62 | 5 | 18.46 |
J | 6.19 | 7.27 | 17 | 7.51 |
K | 7.93 | 7.53 | 9 | 6.52 |
L | 4.4 | 7.28 | 17 | 25.3 |
M | 7.46 | 8.24 | 23 | 14.42 |
N | 2.01 | 5.55 | 47 | 26.31 |
O | 2.04 | 6.4 | 23 | 17.91 |
P | 7.73 | 6.14 | 52 | 15.72 |
Q | 6.35 | 7.58 | 25 | 29.46 |
R | 8.29 | 8.41 | 39 | 12.02 |
S | 3.54 | 7.27 | 54 | 3.16 |
T | 7.44 | 6.26 | 8 | 28.41 |
话不多说,以一个实际例子为例,题目描述的是有20条河流,并以四个指标来评定其水质,分别为含氧量,PH值,细菌数,营养物质含量,规定含氧量越大越好,PH值趋于7为宜,营养物质在10-20最佳,细菌数当然越少越好咯,
上述为已知材料,请你用合适的分析方法来评定出水质最佳的河流与最坏的。
在这里,显然数据已经给出,并且理想值也给出了,应该采用TOPSIS解法
在使用TOPSIS解题之前,我们需要知道基本步骤有三:
-
统一指标类型--通常我们统一为极大型(正向化处理)
-
消除量纲--标准化处理
-
求欧式距离
正向化处理
极小型转为极大型
先求出各对象中的最大值,然后用最大值去减原来的值就得到了正向化后的值了,即 max-x(i)
中间型转为极大型
用给定的中间理想值与各对象值做差,并在这些差中找到最大的那一个,定义为M,则最后可得正向化处理数据为 1 - |x(i)-best|/M
区间型转为最大型
假如给定的上最佳界为a,下最佳界为b,令 M= max{b-min(x),max(x)-a}
x(i) = 1-|b-x|/M ,x<b
=1 , b<x<a
= 1-|x-a|/M,x>a
标准化处理
计算欧氏距离
最后废话不多说,希望这些MATLAB代码可以帮助大家理解
代码分为五个文件
topsis.m
load water_quality_data.mat %导入数据成功
[n,m] = size(X);
disp(['研究对象为' num2str(n) '条河流''指标有' num2str(m) '个'])
Select=input('是否要进行正向化,是请输入1,否请输入0:');
if Select == 1
Position = input('请输入要正向化的指标所对应所在的列--如第二,三,四列需要正向化就输入[2,3,4]:');
Type = input('请输入各指标所对应的类型,1表示极小型,2表示中间型,3表示区间型:');
for i = 1:size(Position,2)
X(:,Position(i)) = zhengxianghua(Type(i),Position(i),X(:,Position(i)));
end
end
disp('正向化后的矩阵为:');
disp(X);
%对矩阵进行标准化
X = X./ repmat(sum(X.*X).^0.5,n,1);
disp('标准化后的矩阵为:');
%%
disp(X);
D_P = sum( ( X - repmat (max(X),n,1) ).^2 ,2) .^0.5;
D_N = sum( ( X - repmat (min(X),n,1) ).^2 ,2) .^0.5;
D_stand = D_N./(D_N+D_P);
disp('为归一化的得分:');
disp(D_stand);
disp('归一化后的得分:');
Stand = D_stand / sum(D_stand);
disp(Stand);
sum(Stand);
[sorted_S,index] = sort(Stand,'descend')
zhengxianghua.m
function [OK] = zhengxianghua (Type,i,x)
%1表示极小型,2表示中间型,3表示区间型
if Type==1
disp(['第' num2str(i) '列正在进行正向化--从极小型变为极大型']);
OK = min2max(x);
elseif Type==2
disp(['第' num2str(i) '列正在进行正向化--从中间型变为极大型']);
best = input('请输入PH最佳标准');
OK = mid2max(x,best);
elseif Type==3
disp(['第' num2str(i) '列正在进行正向化--从区间型变为极大型']);
shangjie = input('请输入上最佳界');
xiajie = input('请输入下最佳界');
OK = qujian2max(x,shangjie,xiajie);
else
disp('输入数据有误,没有此类型到极大型的转换方式');
end
end
min2max.m
function [min_2_max] = min2max(x)
min_2_max = max(x)-x;
end
%极小型转化为极大型
mid2max.m
function [xx] = mid2max(x,best)
M = max(abs(x-best));
xx = 1 - abs(x-best)/M;
end
%中间型到最大型的转化完成
qujian2max.m
function [xx] = qujian2max(x,shangjie,xiajie)
r_x = size(x,1);
M = max(xiajie - min(x),max(x)-shangjie);
xx = zeros(r_x,1);
for i = 1:r_x
if x(i)>shangjie
xx(i) = 1 - ( x(i) - shangjie )/M;
elseif x(i)<xiajie
xx(i) = 1 - ( xiajie - x(i) )/M;
else
xx(i) = 1;
end
end
end
根据最后降序排列的结果可知水质最佳的河流为第11条