目录
一、TOPSIS法
1-基本概念
TOPSIS法可以翻译为逼近理想解排序法,国内称为优劣解距离法,TOPSIS法是一种常用的综合评价方法,其能充分应用原始数据的的信息,其结果能精确的反映各评价方案之间的差距。
我们之前学习了层次分析法去作评价,但是层次分析法有如下缺点:
第一,n不能太大,最多只能是15,否则不能通过一致性检验,RI只能查到n=15的值。
第二,层次分析法的判断矩阵是主观填写的,如果题目中已有相关数据,不适合用层次分析法作为评价模型。
2-TOPSIS方法的具体步骤
下面介绍通过正向化将极小型转换为极大型指标,具体如下:
下面介绍如何将中间型指标转换为极大型指标,具体如下:
下面学习区间型转换成极大型指标,具体如下:
正向化之后我们需要进行标准化处理,消除量纲的影响,具体如下:
标准化处理数据后,计算得分并作归一化处理,具体如下:
注意:上述指标默认每个指标的权重一样,如果考虑指标权重的话,得到的公式如下所示:
最后一句话有误,是Di+越小,越接近最大值。
权重确定的方法:客观法:变异系数法,熵权法;主观法:层次分析法的三种求权重方式
二、TOPSIS法的应用案例
1-案例题目
看一下下面的题目,含氧量是极大型指标,PH值是中间型指标,细菌总数是极小型指标,植物性营养物量是区间型指标。
MATLAB代码如下所示:
2-TOPSIS主程序
%主程序
clear; clc
load('data_water_quality.mat') ;
%正向化处理,全部转换成极大型
[n,m] = size(X) ;
disp(['一共有' num2str(n) '个评价对象,' num2str(m) '个评价指标']) ;
position = [2,3,4] ; %需要正向化处理的指标所在的列
type = [2,1,3] ; %三个类型分别是中间型、极小型、区间型
for i = 1 : size(position, 2)
X(:,position(i)) = Positivization(X(:,position(i)),type(i),position(i));
end
disp('正向化后的矩阵 = ') ;
disp(X) ;
%对正向化处理后的矩阵进行标准化处理
z = X ./ repmat(sum(X.*X) .^ 0.5, n, 1);
disp('标准化矩阵 = ') ;
disp(z) ;
disp('需要给指标加相应的权重?需要输入1,不需要输入2') ;
judge2 = input('请输入1或者2:') ;
%计算与最大值和最小值的距离,计算得分,并降序排序
if judge2 == 2
D1 = sum((z - repmat(max(z),n,1)) .^ 2 ,2) .^ 0.5;
D2 = sum((z - repmat(min(z),n,1)) .^ 2,2) .^ 0.5;
end
if judge2 == 1
w = input('请按照向量形式输入各个指标权重:') ;
D1 = sum(repmat(w,n,1) .* (z - repmat(max(z),n,1)) .^ 2 ,2) .^ 0.5;
D2 = sum(repmat(w,n,1) .* (z - repmat(min(z),n,1)) .^ 2,2) .^ 0.5;
end
s = D2 ./ (D1 + D2) ;
disp('最后的得分:') ;
ss = s / sum(s) ;
disp(ss) ;
[s1, I] = sort(ss, 1, 'descend') ;
disp('最后的排名由高到底依次是:') ;
disp(I) ;
3-正向化处理函数
function [position_x] = Positivization(x, type, i)
if type == 1
position_x = min_max(x) ;
end
if type == 2
best = 7 ;
position_x = mid_max(x,best) ;
end
if type == 3
left = 10 ;
right = 20 ;
position_x = inter_max(x,left,right) ;
end
end
4-极小型转换为极大型的函数
function [position_x] = min_max(x)
position_x = max(x) - x ;
end
5-中间型转换为极大型的函数
function [positon_x] = mid_max(x, best)
M = max(abs(x-best)) ;
positon_x = 1 - abs(x-best) / M ;
end
6-区间型转换为极大型的函数
function [position_x] = inter_max(x, left, right)
row = size(x, 1) ;
M = max([left - min(x),max(x) - right]) ;
position_x = zeros(row, 1) ;
for i = 1 : row
if x(i) < left
position_x(i) = 1 - (left - x(i)) / M ;
else if x(i) > right
position_x(i) = 1 - (x(i) - right) / M ;
else
position_x(i) = 1 ;
end
end
end
end