TOPSIS法(Technique for Order Preference by Similarity to Ideal Solution,优劣解距离法)是一种多准则决策分析方法,它基于这样一个概念:最理想的方案应该是距离理想解最近而距离负理想解最远的方案。以下是使用TOPSIS法的详细步骤:
TOPSIS法的基本步骤
- 构建决策矩阵:
-
- 将所有方案在各个准则下的性能数据组织成一个决策矩阵。每一行代表一个方案,每一列代表一个评价准则。
- 标准化决策矩阵:
-
- 为了消除不同准则间的量纲影响,需要对决策矩阵进行标准化处理。标准化方法取决于准则的属性(收益型或成本型):
-
-
- 收益型准则:[x_{ij}' = \frac{x_{ij}}{\sqrt{\sum_{j=1}{n} x_{ij}2}}]
- 成本型准则:[x_{ij}' = \frac{1}{x_{ij}}] 或 [x_{ij}' = \frac{1/x_{ij}}{\sqrt{\sum_{j=1}{n} (1/x_{ij})2}}]
-
- 构建加权标准化决策矩阵:
-
- 用各个准则的权重乘以标准化后的决策矩阵中的对应元素,得到加权标准化决策矩阵。
- 确定理想解和负理想解:
-
- 理想解(Positive Ideal Solution, PIS):在加权标准化决策矩阵中,每个准则的最大值构成的理想方案。
- 负理想解(Negative Ideal Solution, NIS):在加权标准化决策矩阵中,每个准则的最小值构成的负理想方案。
- 计算每个方案与理想解和负理想解的距离:
-
- 计算每个方案与理想解的距离((d_i+))和与负理想解的距离((d_i-)):
-
-
- (d_i+ = \sqrt{\sum_{j=1}{n} (x_{ij}' - x_j+)2})
- (d_i- = \sqrt{\sum_{j=1}{n} (x_{ij}' - x_j-)2})
-
- 计算相对接近度:
-
- 计算每个方案的相对接近度(Closeness Coefficient, CC):
-
-
- (CC_i = \frac{d_i-}{d_i- + d_i^+})
-
-
- (CC_i) 的值越大,表明该方案越接近理想解,越远离负理想解。
- 排序和选择:
-
- 根据每个方案的相对接近度进行排序,选择相对接近度最大的方案作为最优方案。
举例说明
假设我们有以下河流水质评价问题,包含四个评价准则:含氧量、pH值、细菌总数和植物性营养物量。目标是最优的水质状况。
- 构建决策矩阵:
-
- 决策矩阵如下:
|河流|含氧量(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|
- 标准化决策矩阵:
-
- 对于收益型准则(含氧量、pH值、植物性营养物量)进行标准化,对于成本型准则(细菌总数)进行逆标准化。
- 构建加权标准化决策矩阵:
-
- 假设权重分别为:含氧量0.4,pH值0.2,细菌总数0.2,植物性营养物量0.2。
- 确定理想解和负理想解:
-
- 理想解:[x_j^+ = (0.835, 0.979, 0.05, 0.82)]
- 负理想解:[x_j^- = (0.165, 0.021, 0.95, 0.18)]
- 计算距离:
-
- 例如,对于河流A,计算与理想解和负理想解的距离:
-
-
- (d_A+ = \sqrt{(0.835 - 0.613)2 + (0.979 - 0.609)2 + (0.05 - 0.849)2 + (0.82 - 0.649)^2})
- (d_A- = \sqrt{(0.165 - 0.613)2 + (0.021 - 0.609)2 + (0.95 - 0.849)2 + (0.18 - 0.649)^2})
-
- 计算相对接近度:
-
- 例如,河流A的相对接近度为:
-
-
- (CC_A = \frac{d_A-}{d_A- + d_A^+})
-
- 排序和选择:
-
- 根据相对接近度对所有河流进行排序,选择相对接近度最大的河流作为水质最优的河流。
结论
通过以上步骤,可以使用TOPSIS法对河流水质情况进行评价,并选择最优的河流。这种方法适用于处理包含多个评价准则的决策问题,能够直观地展示每个方案与理想状态的距离,从而帮助决策者做出最佳选择。根据提供的资料,以下是TOPSIS法(优劣解距离法)的详细介绍,包括每一部分的内容:
1. 模型介绍
1.1 什么是TOPSIS法
- TOPSIS法是一种综合评价方法,其全称为“Technique for Order Preference by Similarity to Ideal Solution”,中文可译为“逼近理想解排序法”,国内常简称为优劣解距离法。
- 该方法能充分利用原始数据信息,结果能够精确反映各评价方案之间的差距。
- TOPSIS法的基本思想是基于每个方案与理想解(最优解)和负理想解(最劣解)的距离来评价方案的好坏。
2. 温馨提示
- 提供了获取视频附件、软件下载方法、数据获取方法和画图方法等实用信息。
3. 层次分析法的一些局限性
- 当决策层过多时,判断矩阵与一致矩阵之间的差异可能会很大。
- 如果决策层中的指标数据已知,如何利用这些数据使评价更加准确是一个问题。
4. 一个小例子
- 小明同宿舍四名同学的成绩需要评分,要求评分能合理描述他们的成绩高低。
- 使用一个简单的想法,即根据排名来分配评分,但这种方法存在问题,因为它忽略了成绩的实际数值。
5. 一个更好的想法
- 提出一个公式,根据成绩与最高分和最低分之间的关系来计算评分,从而更好地反映成绩的实际差距。
- 使用公式 ( \frac{x - \text{min}}{\text{max} - \text{min}} ) 来计算评分,其中 ( x ) 是学生的成绩,(\text{min}) 和 (\text{max}) 分别是最小成绩和最大成绩。
6. 类比只有一个指标计算得分
- 类似地,对于只有一个指标的情况,可以使用距离理想解和负理想解的距离来计算得分。
- 得分公式为 (\frac{D_{-}}{D_{+} + D_{-}}),其中 (D_{+}) 是与最劣解的距离,(D_{-}) 是与最优解的距离。
7. TOPSIS的介绍
- TOPSIS法是由C.L.Hwang和K.Yoon于1981年提出的。
- 该方法的基本过程包括:
-
- 统一指标类型(正向化处理);
- 对正向化的矩阵进行标准化处理,以消除量纲的影响;
- 找到有限方案中的最优方案和最劣方案;
- 计算各评价对象与最优方案和最劣方案之间的距离;
- 根据与最优方案的相对接近程度进行评价。
8. 第一步:将原始矩阵正向化
- 将所有指标类型统一转化为极大型指标(即越大越好)。
- 不同类型的指标需要使用不同的转换公式来实现正向化:
-
- 极小型指标(越小越好)转换为极大型指标;
- 中间型指标(越接近某个值越好)转换为极大型指标;
- 区间型指标(落在某个区间最好)转换为极大型指标。
9. 极小型指标转换为极大型指标
- 极小型指标(越小越好)转换为极大型指标的公式为 (\frac{1}{x}) 或 (\frac{\text{max} - x}{\text{max} - \text{min}})。
- 示例:将争吵次数(越少越好)转换为正向化的争吵次数(越多越好)。
10. 中间型指标转换为极大型指标
- 中间型指标(越接近某个值越好)转换为极大型指标的公式为 (1 - \left|\frac{x - \text{target}}{\text{max} - \text{min}}\right|)。
- 示例:将pH值转换为正向化的pH值。
11. 区间型指标转换为极大型指标
- 区间型指标(落在某个区间最好)转换为极大型指标的公式为 (\frac{x - \text{min}}{\text{ideal max} - \text{min}}) 或 (\frac{\text{ideal max} - x}{\text{ideal max} - \text{ideal min}})。
- 示例:将体温转换为正向化的体温。
12. 第二步:正向化矩阵标准化
- 标准化的目的是消除不同指标量纲的影响。
- 标准化的方法是将正向化矩阵中的每个元素除以该列的平方和的平方根。
13. 第三步:计算得分并归一化
- 计算每个方案与最优解(PIS)和最劣解(NIS)的距离。
- 得分公式为 (\frac{D_{-}}{D_{+} + D_{-}}),其中 (D_{+}) 是与最劣解的距离,(D_{-}) 是与最优解的距离。
- 归一化的目的是让得分限制在0-1区间内,便于解释和理解。
14. 一起来做练习题
- 评价下表中20条河流的水质情况。
- 数据包括含氧量、pH值、细菌总数和植物性营养物量。
- 含氧量越高越好;pH值越接近7越好;细菌总数越少越好;植物性营养物量介于10-20之间最佳,超过20或低于10均不好。
- 需要进行正向化处理,然后标准化,最后计算得分。
15. 代码详解
- 提供了如何将Excel数据导入Matlab并保存为.mat文件的方法。
- 介绍了Matlab中函数的编写和调用、幻方矩阵、排序函数、零矩阵和单位矩阵的创建等知识点。
- 强调了观看代码讲解视频的重要性,并提供了额外的视频资源。
16. 模型拓展
- 提供了进一步扩展模型的方法和技术,包括企业资金分配问题和太阳镜产品质量评价中的应用案例。
%% 第一步:把数据复制到工作区,并将这个矩阵命名为X
% (1)在工作区右键,点击新建(Ctrl+N),输入变量名称为X
% (2)在Excel中复制数据,再回到Excel中右键,点击粘贴Excel数据(Ctrl+Shift+V)
% (3)关掉这个窗口,点击X变量,右键另存为,保存为mat文件(下次就不用复制粘贴了,只需使用load命令即可加载数据)
% (4)注意,代码和数据要放在同一个目录下哦,且Matlab的当前文件夹也要是这个目录。
clear;clc
load data_water_quality.mat
%% 注意:如果提示: 错误使用 load,无法读取文件 'data_water_quality.mat'。没有此类文件或目录。
% 那么原因是因为你的Matlab的当前文件夹中不存在这个文件
% 可以使用cd函数修改Matlab的当前文件夹
% 比如说,我的代码和数据放在了: D:第2讲.TOPSIS法(优劣解距离法)\代码和例题数据
% 那么我就可以输入命令:
% cd 'D:第2讲.TOPSIS法(优劣解距离法)\代码和例题数据'
% 也可以看我更新的视频:“更新9_Topsis代码为什么运行失败_得分结果怎么可视化以及权重的确定如何更加准确”,里面有介绍
%% 第二步:判断是否需要正向化
[n,m] = size(X);
disp(['共有' num2str(n) '个评价对象, ' num2str(m) '个评价指标'])
Judge = input(['这' num2str(m) '个指标是否需要经过正向化处理,需要请输入1 ,不需要输入0: ']);
if Judge == 1
Position = input('请输入需要正向化处理的指标所在的列,例如第2、3、6三列需要处理,那么你需要输入[2,3,6]: '); %[2,3,4]
disp('请输入需要处理的这些列的指标类型(1:极小型, 2:中间型, 3:区间型) ')
Type = input('例如:第2列是极小型,第3列是区间型,第6列是中间型,就输入[1,3,2]: '); %[2,1,3]
% 注意,Position和Type是两个同维度的行向量
for i = 1 : size(Position,2) %这里需要对这些列分别处理,因此我们需要知道一共要处理的次数,即循环的次数
X(:,Position(i)) = Positivization(X(:,Position(i)),Type(i),Position(i));
% Positivization是我们自己定义的函数,其作用是进行正向化,其一共接收三个参数
% 第一个参数是要正向化处理的那一列向量 X(:,Position(i)) 回顾上一讲的知识,X(:,n)表示取第n列的全部元素
% 第二个参数是对应的这一列的指标类型(1:极小型, 2:中间型, 3:区间型)
% 第三个参数是告诉函数我们正在处理的是原始矩阵中的哪一列
% 该函数有一个返回值,它返回正向化之后的指标,我们可以将其直接赋值给我们原始要处理的那一列向量
end
disp('正向化后的矩阵 X = ')
disp(X)
end
%% 作业:在这里增加是否需要算加权
% 补充一个基础知识:m*n维的矩阵A 点乘 n维行向量B,等于这个A的每一行都点乘B
% (注意:2017以及之后版本的Matlab才支持,老版本Matlab会报错)
% % 假如原始数据为:
% A=[1, 2, 3;
% 2, 4, 6]
% % 权重矩阵为:
% B=[ 0.2, 0.5 ,0.3 ]
% % 加权后为:
% C=A .* B
% 0.2000 1.0000 0.9000
% 0.4000 2.0000 1.8000
% 类似的,还有矩阵和向量的点除, 大家可以自己试试计算A ./ B
% 注意,矩阵和向量没有 .- 和 .+ 哦 ,大家可以试试,如果计算A.+B 和 A.-B会报什么错误。
%% 这里补充一个小插曲
% % 在上一讲层次分析法的代码中,我们可以优化以下的语句:
% % Sum_A = sum(A);
% % SUM_A = repmat(Sum_A,n,1);
% % Stand_A = A ./ SUM_A;
% % 事实上,我们把第三行换成:Stand_A = A ./ Sum_A; 也是可以的哦
% % (再次强调,新版本的Matlab才能运行哦)
%% 让用户判断是否需要增加权重
disp('请输入是否需要增加权重向量,需要输入1,不需要输入0')
Judge = input('请输入是否需要增加权重: ');
if Judge == 1
disp(['如果你有3个指标,你就需要输入3个权重,例如它们分别为0.25,0.25,0.5, 则你需要输入[0.25,0.25,0.5]']);
weigh = input(['你需要输入' num2str(m) '个权数。' '请以行向量的形式输入这' num2str(m) '个权重: ']);
OK = 0; % 用来判断用户的输入格式是否正确
while OK == 0
if abs(sum(weigh) - 1)<0.000001 && size(weigh,1) == 1 && size(weigh,2) == m % 这里要注意浮点数的运算是不精准的。
OK =1;
else
weigh = input('你输入的有误,请重新输入权重行向量: ');
end
end
else
weigh = ones(1,m) ./ m ; %如果不需要加权重就默认权重都相同,即都为1/m
end
%% 第三步:对正向化后的矩阵进行标准化
Z = X ./ repmat(sum(X.*X) .^ 0.5, n, 1);
disp('标准化矩阵 Z = ')
disp(Z)
%% 第四步:计算与最大值的距离和最小值的距离,并算出得分
D_P = sum([(Z - repmat(max(Z),n,1)) .^ 2 ] .* repmat(weigh,n,1) ,2) .^ 0.5; % D+ 与最大值的距离向量
D_N = sum([(Z - repmat(min(Z),n,1)) .^ 2 ] .* repmat(weigh,n,1) ,2) .^ 0.5; % D- 与最小值的距离向量
S = D_N ./ (D_P+D_N); % 未归一化的得分
disp('最后的得分为:')
stand_S = S / sum(S)
[sorted_S,index] = sort(stand_S ,'descend')
% A = magic(5) % 幻方矩阵
% M = magic(n)返回由1到n^2的整数构成并且总行数和总列数相等的n×n矩阵。阶次n必须为大于或等于3的标量。
% sort(A)若A是向量不管是列还是行向量,默认都是对A进行升序排列。sort(A)是默认的升序,而sort(A,'descend')是降序排序。
% sort(A)若A是矩阵,默认对A的各列进行升序排列
% sort(A,dim)
% dim=1时等效sort(A)
% dim=2时表示对A中的各行元素升序排列
% A = [2,1,3,8]
% Matlab中给一维向量排序是使用sort函数:sort(A),排序是按升序进行的,其中A为待排序的向量;
% 若欲保留排列前的索引,则可用 [sA,index] = sort(A,'descend') ,排序后,sA是排序好的向量,index是向量sA中对A的索引。
% sA = 8 3 2 1
% index = 4 3 1 2
% % 注意:代码文件仅供参考,一定不要直接用于自己的数模论文中
% % 国赛对于论文的查重要求非常严格,代码雷同也算作抄袭
% % 视频中提到的附件可在售后群(购买后收到的那个无忧自动发货的短信中有加入方式)的群文件中下载。包括讲义、代码、我视频中推荐的资料等。
% % 关注我的微信公众号《数学建模学习交流》,后台发送“软件”两个字,可获得常见的建模软件下载方法;发送“数据”两个字,可获得建模数据的获取方法;发送“画图”两个字,可获得数学建模中常见的画图方法。另外,也可以看看公众号的历史文章,里面发布的都是对大家有帮助的技巧。
% % 购买更多优质精选的数学建模资料,可关注我的微信公众号《数学建模学习交流》,在后台发送“买”这个字即可进入店铺(我的微店地址:https://weidian.com/?userid=1372657210)进行购买。
% % 视频价格不贵,但价值很高。单人购买观看只需要58元,三人购买人均仅需46元,视频本身也是下载到本地观看的,所以请大家不要侵犯知识产权,对视频或者资料进行二次销售。
% % 如何修改代码避免查重的方法:https://www.bilibili.com/video/av59423231(必看)
这段MATLAB代码实现了TOPSIS法的主要步骤,包括数据导入、正向化处理、标准化、计算距离以及最终得分的计算和排序。下面是详细的解释:
1. 数据导入
- 代码:
clear;clc
load data_water_quality.mat
- 解释:
-
clear;clc
:清除工作空间中的所有变量并清空命令窗口。load data_water_quality.mat
:加载名为data_water_quality.mat
的MATLAB数据文件,该文件包含了矩阵X
,即原始数据矩阵。
2. 判断是否需要正向化
- 代码:
[n,m] = size(X);
disp(['共有' num2str(n) '个评价对象, ' num2str(m) '个评价指标'])
Judge = input(['这' num2str(m) '个指标是否需要经过正向化处理,需要请输入1 ,不需要输入0: ']);
- 解释:
-
[n,m] = size(X)
:获取矩阵X
的行数n
和列数m
。disp(['共有' num2str(n) '个评价对象, ' num2str(m) '个评价指标'])
:显示有多少个评价对象和多少个评价指标。Judge = input(['这' num2str(m) '个指标是否需要经过正向化处理,需要请输入1 ,不需要输入0: '])
:询问用户是否需要进行正向化处理。
3. 正向化处理
- 代码:
if Judge == 1
Position = input('请输入需要正向化处理的指标所在的列,例如第2、3、6三列需要处理,那么你需要输入[2,3,6]: ');
disp('请输入需要处理的这些列的指标类型(1:极小型, 2:中间型, 3:区间型) ')
Type = input('例如:第2列是极小型,第3列是区间型,第6列是中间型,就输入[1,3,2]: ');
for i = 1 : size(Position,2)
X(:,Position(i)) = Positivization(X(:,Position(i)),Type(i),Position(i));
end
disp('正向化后的矩阵 X = ')
disp(X)
end
- 解释:
-
- 如果需要正向化处理,则:
-
-
- 输入需要处理的列号。
- 输入这些列的指标类型。
- 对指定列进行正向化处理。
- 显示正向化后的矩阵
X
。
-
4. 是否需要加权
- 代码:
disp('请输入是否需要增加权重向量,需要输入1,不需要输入0')
Judge = input('请输入是否需要增加权重: ');
if Judge == 1
weigh = input(['你需要输入' num2str(m) '个权数。' '请以行向量的形式输入这' num2str(m) '个权重: ']);
OK = 0;
while OK == 0
if abs(sum(weigh) - 1)<0.000001 && size(weigh,1) == 1 && size(weigh,2) == m
OK =1;
else
weigh = input('你输入的有误,请重新输入权重行向量: ');
end
end
else
weigh = ones(1,m) ./ m;
end
- 解释:
-
- 如果需要加权,则:
-
-
- 输入权重向量。
- 检查权重向量是否合法(和为1且为行向量)。
-
-
- 如果不需要加权,则:
-
-
- 默认权重相同,即每个指标的权重为
1/m
。
- 默认权重相同,即每个指标的权重为
-
5. 标准化
- 代码:
Z = X ./ repmat(sum(X.*X) .^ 0.5, n, 1);
disp('标准化矩阵 Z = ')
disp(Z)
- 解释:
-
- 标准化处理:将矩阵
X
标准化为矩阵Z
。
- 标准化处理:将矩阵
6. 计算距离并计算得分
- 代码:
D_P = sum([(Z - repmat(max(Z),n,1)) .^ 2 ] .* repmat(weigh,n,1) ,2) .^ 0.5; % D+ 与最大值的距离向量
D_N = sum([(Z - repmat(min(Z),n,1)) .^ 2 ] .* repmat(weigh,n,1) ,2) .^ 0.5; % D- 与最小值的距离向量
S = D_N ./ (D_P+D_N); % 未归一化的得分
disp('最后的得分为:')
stand_S = S / sum(S)
[sorted_S,index] = sort(stand_S ,'descend')
- 解释:
-
- 计算每个方案与最优解(PIS)和最劣解(NIS)的距离。
- 计算每个方案的得分。
- 对得分进行排序。
通过以上步骤,我们可以使用MATLAB实现TOPSIS法的完整流程,从数据预处理到最终结果的排序。这段代码是一个很好的起点,可以根据具体需求进行调整和优化。