一、前言
层次分析模型(AHP)是一种系统化的多准则决策分析方法,适用于需要在多个相互冲突或互补的准则下做出决策的情景。它通过构建层次结构来明确决策目标、准则和备选方案,并使用0~9标度法进行两两比较来确定各准则和方案的相对重要性,进而通过一致性检验保证比较的一致性。层次分析模型适用于各种复杂决策问题,如项目选择、资源分配、供应商选择等,特别是在需要整合定性和定量信息,以及涉及多个决策者意见的情况中尤为有效。
二、历年题型分析
上述就是这几年数学建模比赛所考察的算法,以及每个算法求解的模型。下面把这几类算法,给大家归纳出最常用的解决方法,供大家参考。
2.1 常用算法归纳
2.1.1 优化类算法
线性规划、非线性规划、多目标规划、最短路径、最小生成树、动态规划
2.1.2 预测类算法
灰色预测、时间序列、回归分析、支持向量机、神经网络、马尔科夫模型
2.1.3 评价决策类
层次分析、TOPSIS法、灰色关联分析、模糊综合评价、主成分分析、聚类分析
2.1.4 NP-hard类
蚁群算法、粒子群算法、遗传算法、模拟退火
2.2 评价类模型求解
对于这几年数学建模比赛,评价优化类题目出现的频率还是蛮多滴,其中评价优化类题目一个常用解法就是层次分析法 (AHP)和多指标评价法(MCDA)。我找了很多资源进行学习,自我感觉层次分析法和多指标评价法的用法和解题思路大差不差,都是将一个评价类问题分成几个指标进行评估,计算最后的得分进行排序,层次分析法将问题分成了三层,目标层、准则层和方案层,主要思想是分而治之,而多指标评价法更多的是针对数据本身特点进行分析,使得评价结果更具有客观性。以下就是我从其他地方copy过来的两者的对比介绍,大家用辩证的思想来看待。
2.2.1 层次分析法(AHP)
-
特点:
- 基于层次结构,将决策问题分为目标层、准则层和方案层。
- 使用0~9标度法进行两两比较,确定准则和方案的相对重要性。
- 强调一致性检验以确保比较的合理性。
- 适用于定性与定量信息的综合评估。
-
应用场景:
- 项目选择和优先级排序。
- 投资决策。
- 资源分配。
- 供应商选择等。
2.2.2 多指标评价法(MCDA)
-
特点:
- 包括多种方法,如TOPSIS、AHP、DEA(Data Envelopment Analysis)、MABAC(Multi-Attribute Border Approximation Area Comparison)等。
- 涉及多个评价指标,既包括定量也包括定性指标。
- 可以使用不同的权重确定方法,如专家判断、统计方法等。
- 目的是寻找最优方案或对备选方案进行排序。
-
应用场景:
- 产品设计与选择。
- 环境影响评估。
- 公共政策制定。
- 供应链管理等。
2.2.3 算法区别
-
方法论差异:
- AHP特别强调层次结构和两两比较,而MCDA涵盖的方法更多样化。
- AHP的两两比较方法确保了决策的一致性,而MCDA中的某些方法可能不需要这种一致性检查。
-
适用场景:
- AHP更适合需要专家判断和两两比较的情景,尤其是当决策者需要直观地理解指标间的关系时。
- MCDA则适用于更广泛的情况,特别是当需要考虑多种评价方法和技术时。
本次任务我将带大家了解层次分析法,如何构建层次结构,如何挑选准则层的指标,如何使用0~9标度法建立判断矩阵,如何对矩阵进行一致性检验,如何计算最后的得分。最后带大家运用这个方法进行实战。并对2021年数学建模大赛C类第一题进行分析求解。
三、层次分析法讲解
对于一个评价类题目,无非就是对它的一些方案进行评价打分,根据它的得分进行排名,分出个三六九等,选出一个最优秀的方案。这里就引申出了层次分析法的三个构造层,目标层---我今天要干点啥,是去吃饭嘞还是去旅游,准则层---评价每个方案所需要的指标,求出每个指标的重要性,方案层---针对我提出的目标,一些可供挑选的方案,今天该吃点啥呀(馒头,包子,鸡公煲),明天该去哪儿玩(北京、上海、武汉)。
3.1 层次分析法的做题步骤
下面就举出一个具体例子带大家分析。
比如,今天我想买一件衣服,但是我选择恐惧症犯了,目前我看中了几款衣服,为了方便描述,就按照衣服的品牌来指代具体的衣服,第一件是阿迪的衣服,第二件是耐克的衣服,第三件是驴牌衣服。我想挑一件很符合我心意的衣服,因此我提出了几个判断指标,第一衣服款式新颖,第二价格要优惠一点,第三衣服评价要好,第四看一下商家态度。
由以上的分析,我们将问题引入层次分析模型。
3.2 层次分析模型的解题思路
上面已经构建了一个层次分析模型,目前我们要解决的问题是,对于上述几个指标,如何计算他们的权重,对于每一件衣服对应的指标,又该如何打分呢。以下我们引入了一个方法,0~9标度法。大家记住它的作用就是量化指标,比如对于衣服新颖度来说,这是一个抽象的概念,如何将他代入数值进行具体计算呢,这里就用到了一个方法叫两两比较法,也就是0~9标度法的重要思想。
3.2.1 构造判断矩阵
0~9标度法对应的分数
现在就来构造判断矩阵,大家注意因为通过0~9标度法构造的判断矩阵具有一定的主观性,判断准则和打分也因人而异,所以对于判断矩阵的构造,常用的方法就是专家打分,要么就是查阅文献进行打分,大家在写论文时候,就算没有找到专家资料,或者文献啥的,大家可以写通过查阅***文献,或者进行调查问卷,或者国家**统计局数据分析,得到了以下判断指标及判断矩阵,千万千万不要啥也不说就把指标跟判断矩阵列上去,没有一点理论依据的,这里给大家推荐一个查阅指标和数据的宝藏网站:虫部落快搜 - 搜索快人一步,后面博文会给大家讲熵权法和TOPSIS法,那个权重计算会更加客观一点。
下面就是我得到一个判断矩阵,这里因为是给大家讲解模型背后的理论,所以不谈依据,买衣服纯个人感觉。
指标的判断矩阵 | 衣服新颖度 | 衣服价格 | 衣服评价 | 商家态度 |
衣服新颖度 | 1 | 1/5 | 1/3 | 1/3 |
衣服价格 | 5 | 1 | 1/3 | 1/5 |
衣服评价 | 3 | 3 | 1 | 1/3 |
商家态度 | 3 | 5 | 3 | 1 |
这里大家可以看到,判断矩阵中的主对角线上的元素都是1,因为自己跟自己对比肯定是同等重要的,然后关于主对角线对称的元素都是互为倒数,在上述矩阵中,衣服价格对于衣服新颖度来说,是明显重要的,因为对于我来说,我更想买到一个实惠的衣服,所以判断矩阵就是5,衣服新颖度对于衣服价格来说,就是明显不重要的,所以对应是1/5。
然后分别列出每个指标对应的方案的判断矩阵,将方案的判断值量化分析。这里需要列出衣服新颖度----三种衣服的判断矩阵,衣服价格---三种衣服的判断矩阵,衣服评价---三种衣服的判断矩阵,商家态度---三种衣服的判断矩阵。下面就列举一个样例,大家做题的时候需要把所有的判断矩阵列举出来。
3.2.2 一致性检验
将所有的判断矩阵计算出来后,紧接着就要对每个矩阵进行一致性检验了,一致性检验是因为我们对每个指标进行评价打分,当指标多的时候,可能存在相互矛盾的地方,我们要将这种矛盾控制在一个合理的范围之内。比如说在一个判断矩阵中,我认为A比B重要,B又比C重要,结果又出现了C比A重要。
我会带着大家了解计算过程,具体的理论分析大家可以参考东北大学张震教授写的一篇论文----层次分析法一致性检验。
第一步:计算一致性指标CI
表示判断矩阵的最大特征根,n表示指标个数
第二步:根据n值查找平均随机一致性指标RI
n | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
RI | 0 | 0 | 0.58 | 0.90 | 1.12 | 1.24 | 1.32 | 1.44 | 1.45 | 1.49 | 1.52 | 1.54 | 1.56 | 1.59 |
第三步:计算一致性比例CR
对于最后的计算结果,如果CR < 0.1,表示所构造的判断矩阵可以使用,否则判断矩阵需要继续修改。
对于的计算过程,张教授文章里面都有提到,具体计算过程不深究。判断矩阵进行一致性检验的时候需要归一化处理,计算过程就是每一个值除以所在列的和,为了方便大家计算,代码中都有处理,大家只需要添加原始数据即可。下面给大家安排上求解代码,大家只需要改写参数就好了,可以直接使用。
import numpy as np
# 判断矩阵
'''
judgment_matrix = np.array([
[1,1/5,1/3,1/5],
[5,1,3,3],
[3,1/3,1,1/3],
[5,1/3,3,1]
])
这里需要大家将自己的判断矩阵输入进去,变量名为judgment_matrix
'''
# 归一化判断矩阵
normalized_matrix = judgment_matrix / judgment_matrix.sum(axis=0)
# 计算特征向量(即各因素的权重)
weights = normalized_matrix.mean(axis=1)
# 输出权重
print("各因素的权重:", weights)
# 计算一致性指标 CI
lambda_max = np.linalg.eigvals(judgment_matrix).max().real
CI = (lambda_max - len(weights)) / (len(weights) - 1)
# 计算一致性比率 CR(假设 n=3, RI=0.58)
RI = 0.89 # 这里根据大家的n值,找出表格中对应的系数,修改为大家所需要的值即可
CR = CI / RI
print("一致性比率 CR:", CR)
# 一致性检验
if CR < 0.1:
print("判断矩阵的一致性通过")
else:
print("判断矩阵的一致性不通过,需要调整")
代码中大家将判断矩阵改为自己的判断矩阵,命名为:judgment_matrix,还有修改RI值,根据自己指标个数对照RI表就可以知道具体数值了。
运行结果如下:
这些计算过程都可以体现在论文里面。比如判断矩阵最后计算的权重,一致性比率CR。
未完待续