层次分析法(AHP)在多准则决策中的应用
层次分析法(AHP)在多准则决策中的应用
摘要
本文针对两类多准则决策问题建立层次分析(AHP)模型。问题一为三款手机在四个指标上的综合评价,问题二为四个旅游目的地的选择。建模过程包括:构建目标层—准则层—方案层的层次结构;采用 1–9 标度法构造判断矩阵;通过最大特征值计算一致性指标 CI 与一致性比例 CR 并做检验;分别用算术平均法、几何平均法与特征值法计算权重并取均值。结果表明:手机案例中小米(0.359)> 华为(0.353)> 苹果(0.288);旅游案例中张家界(0.381)> 青岛(0.238)> 丽江(0.222)> 厦门(0.159)。一致性检验能够有效识别判断矩阵中的逻辑矛盾——问题一中首个判断矩阵 CR = 0.225 未通过,修正后降至 0.0054,说明该步骤是保证权重合理性的关键环节。
关键词:层次分析法;判断矩阵;一致性检验;特征值;权重
一、问题描述
问题一 对三款手机(小米、华为、苹果)进行综合评价。原始数据为三款手机在四个指标上的打分矩阵,原数据未标注各指标的具体含义,本文按位置记为指标①②③④。
问题二 暑假出游目的地在丽江、厦门、青岛、张家界四地中选择。需综合考虑四个准则:交通便利性、旅游资源丰富程度、旅途开销、安全和卫生情况。要求自行构造准则层判断矩阵与方案层得分,建立综合评价模型。
二、模型假设
- 各评价指标之间相互独立,不存在显著的交互作用;
- 决策者给出的两两比较判断具有内在一致性倾向,即不存在根本性的逻辑矛盾;
- 判断矩阵中的标度值能真实反映决策者的偏好强度;
- 方案层各指标得分均已统一方向,即均为"数值越大越优";
- 不考虑指标数据本身的测量误差。
三、符号说明
| 符号 | 含义 |
|---|---|
| $A$ | 判断矩阵,$n \times n$ 正互反矩阵 |
| $a_{ij}$ | 第 $i$ 个元素相对第 $j$ 个元素的重要程度 |
| $n$ | 判断矩阵阶数 |
| $\lambda_{max}$ | 判断矩阵的最大特征值 |
| $CI$ | 一致性指标 |
| $RI$ | 平均随机一致性指标 |
| $CR$ | 一致性比例 |
| $\mathbf{w}$ | 权重向量 |
| $m$ | 方案(备选)个数 |
| $res1$ | 方案层归一化得分矩阵 |
四、模型建立与求解
4.1 层次结构构建
将问题分解为三个层次:
| 层级 | 问题一 | 问题二 |
|---|---|---|
| 目标层 | 选择最优手机 | 选择最优旅游地 |
| 准则层 | 指标①②③④ | 交通便利性、旅游资源、旅途开销、安全卫生 |
| 方案层 | 小米、华为、苹果 | 丽江、厦门、青岛、张家界 |
4.2 判断矩阵构造
对同一层元素两两比较,按 1–9 标度法赋值,构造正互反矩阵 $A = (a_{ij})_{n \times n}$,满足 $a_{ij} = 1/a_{ji}$,$a_{ii} = 1$。
问题二的准则层判断矩阵为:
| 交通 | 资源 | 开销 | 安全 | |
|---|---|---|---|---|
| 交通 | 1 | 2 | 1/2 | 3 |
| 资源 | 1/2 | 1 | 1/2 | 2 |
| 开销 | 2 | 2 | 1 | 3 |
| 安全 | 1/3 | 1/2 | 1/3 | 1 |
4.3 一致性检验
判断矩阵由主观赋值产生,可能出现"甲优于乙、乙优于丙、而丙又优于甲"的逻辑矛盾,因此必须检验一致性。
由最大特征值计算一致性指标:
$$ CI = \frac{\lambda_{max} - n}{n - 1} $$
查表得平均随机一致性指标 $RI$(本文取 $n=4$ 时 $RI = 0.90$),计算一致性比例:
$$ CR = \frac{CI}{RI} $$
当 $CR < 0.1$ 时认为一致性可以接受。
问题一的一致性检验(含失败案例)
首个判断矩阵经计算得 $\lambda_{max} = 4.6075$,$CI = 0.2025$,$CR = 0.225 > 0.1$,未通过检验。分析其矛盾来源后调整指标②与指标③的相对重要性,得到修正矩阵,重算得 $\lambda_{max} = 4.0145$,$CI = 0.0048$,$CR = 0.0054 < 0.1$,通过检验。
$CR$ 由 0.225 降至 0.0054,说明修正后判断矩阵的内部矛盾基本消除。
问题二的一致性检验
$\lambda_{max} = 4.0710$,$CI = 0.0237$,$CR = 0.0263 < 0.1$,通过检验。
4.4 权重计算
采用三种方法分别计算权重,以便相互验证。
(1)算术平均法:判断矩阵按列归一化后,对每行求平均。
$$ w_i = \frac{1}{n}\sum_{j=1}^{n}\frac{a_{ij}}{\sum_{k=1}^{n}a_{kj}} $$
(2)几何平均法:每行元素连乘后开 $n$ 次方,再归一化。
$$ w_i = \frac{\left(\prod_{j=1}^{n}a_{ij}\right)^{1/n}}{\sum_{k=1}^{n}\left(\prod_{j=1}^{n}a_{kj}\right)^{1/n}} $$
(3)特征值法:取最大特征值对应的特征向量,归一化后作为权重。
$$ A\mathbf{w} = \lambda_{max}\mathbf{w} $$
三种方法计算结果如下。
问题一(修正后的判断矩阵)
| 指标 | 算术平均法 | 几何平均法 | 特征值法 |
|---|---|---|---|
| ① | 0.482407 | 0.483189 | 0.482886 |
| ② | 0.088287 | 0.088218 | 0.088150 |
| ③ | 0.157508 | 0.156876 | 0.156990 |
| ④ | 0.271798 | 0.271717 | 0.271974 |
问题二
| 准则 | 算术平均法 | 几何平均法 | 特征值法 |
|---|---|---|---|
| 交通便利性 | 0.293031 | 0.292222 | 0.292590 |
| 旅游资源 | 0.187190 | 0.186714 | 0.184948 |
| 旅途开销 | 0.411820 | 0.413265 | 0.415493 |
| 安全卫生 | 0.107958 | 0.107799 | 0.106969 |
三种方法结果高度一致(差异在小数点后第三位),说明判断矩阵较为规整。取三者均值作为最终权重:
问题一:$\mathbf{w} = [0.482827,\ 0.088218,\ 0.157125,\ 0.271830]^\top$
问题二:$\mathbf{w} = [0.292615,\ 0.186284,\ 0.413526,\ 0.107575]^\top$
4.5 综合得分计算
方案层得分矩阵按列归一化,消除各指标的量纲差异:
$$ b_{ij} = \frac{x_{ij}}{\sum_{i=1}^{m} x_{ij}} $$
再与权重向量加权求和得到各方案综合得分:
$$ S_i = \sum_{j=1}^{n} b_{ij} \cdot w_j $$
问题一方案层原始数据与归一化结果
| 手机 | 指标① | 指标② | 指标③ | 指标④ |
|---|---|---|---|---|
| 小米 | 0.322709 | 0.436364 | 0.290323 | 0.437908 |
| 华为 | 0.278884 | 0.454545 | 0.387097 | 0.431373 |
| 苹果 | 0.398406 | 0.109091 | 0.322581 | 0.130719 |
问题二方案层得分
| 城市 | 交通 | 资源 | 开销 | 安全 |
|---|---|---|---|---|
| 丽江 | 7 | 9 | 1 | 7 |
| 厦门 | 9 | 8 | 0 | 9 |
| 青岛 | 9 | 8 | 1 | 8 |
| 张家界 | 6 | 9 | 3 | 8 |
五、结果分析
问题一结果
| 手机 | 综合得分 | 排名 |
|---|---|---|
| 小米 | 0.359 | 1 |
| 华为 | 0.353 | 2 |
| 苹果 | 0.288 | 3 |
小米与华为得分接近(0.359 与 0.353),苹果明显落后。指标①权重最高(48.3%),苹果虽在指标①上取得最高分,但在权重第二高的指标④上仅为 0.131,被显著拉低。
问题二结果
| 城市 | 综合得分 | 排名 |
|---|---|---|
| 张家界 | 0.3810 | 1 |
| 青岛 | 0.2384 | 2 |
| 丽江 | 0.2216 | 3 |
| 厦门 | 0.1590 | 4 |
「旅途开销」权重最高(41.4%),张家界在该准则上得分为 3(其余三地分别为 1、0、1),因此在加权求和后明显领先。厦门在交通与安全两项均取得最高分,但开销得分为 0,被权重最高的准则直接拉至末位。
这一结果揭示 AHP 的一个显著特征:最终排序往往由权重最高的准则主导,因此判断矩阵的合理性比计算方法的选择更为重要——这正是必须进行一致性检验的原因。
六、模型评价
优点
- 将定性判断定量化,能够处理难以直接量化的评价准则;
- 一致性检验提供了判断矩阵自洽性的量化判据,避免主观赋值中的逻辑矛盾;
- 三种权重计算方法结果接近,可相互验证,提高结果可信度;
- 模型结构清晰,计算量小,易于实现与推广。
局限
- 权重仍来源于决策者的主观赋值,不同决策者可能给出不同结果;
- 当准则或方案数量较多时,判断矩阵的数量与规模迅速增大;
- 当 $n > 9$ 时一致性难以保证;
- 增加或删除备选方案可能引起排序逆转现象;
- 问题一中四个指标未明确命名,方案层得分是否已统一方向无法核验,若其中存在成本型指标则需先做正向化处理。
附录:Python 代码
附录 A 问题一(三款手机评价)
"""
对手机的结果进行评分
"""
# 注意前面的代码没有使用numpy
# 对数据进行归一化
a = [
[81, 48, 9, 67],
[70, 50, 12, 66],
[100, 12, 10, 20]
]
# 对每一列进行求和
a_sum = []
# 控制列
for j in range(len(a[0])):
temp = 0
# 控制行
for i in range(len(a)):
temp += a[i][j]
a_sum.append(temp)
#print(a_sum)
# 数据归一化结果
res1 = []
for x in a:
temp = []
i = 0
for y in x:
# 每一个数据
temp.append(y / a_sum[i])
i += 1
res1.append(temp)
print('数据归一化结果:')
for x in res1:
print(x)
print()
#############################################
print('-----------------------特征值---------------------')
# 求特征值
import numpy as np
# AHP 只能是方阵
A = np.array(
[
[1, 5, 3, 2],
[1/5, 1, 2, 1/3],
[1/3, 1/2, 1, 2],
[1/2, 3, 1/2, 1]
]
)
# 特征值(包含虚部)
eigenvalues = np.linalg.eigvals(A)
# 只取实部
eigenvalues_real = np.real(eigenvalues)
print(eigenvalues_real)
# 最大特征值
print("最大特征值:" + str(np.max(eigenvalues_real)))
eigenvalues_real_max = np.max(eigenvalues_real)
"""
注意,我们有了最大特征值就可以去求 CI 了
"""
def fun(ci, ri):
# 一致性检验
print('-------------------一致性检验---------------------')
print(f'CI = {ci}')
print(f'CR = CI/RI = {ci / ri}')
if ci / ri > 0.1:
print("一致性检验不通过!!!")
print("-->需要重新调整")
else:
print("一致性检验通过")
n = 4
# 警告⚠️:这个4是阶数,需要根据实际调整
CI = (eigenvalues_real_max - n) / (n - 1)
RI = 0.9 # 特征值:不用计算,根据RI特征值表来取值
fun(CI, RI)
# 重新计算合乎逻辑的矩阵
A1 = np.array(
[
[1, 5, 3, 2],
[1/5, 1, 1/2, 1/3],
[1/3, 2, 1, 1/2],
[1/2, 3, 2, 1]
]
)
# 正确的最大特征值
x = np.max(np.real(np.linalg.eigvals(A1)))
CI = (x - n) / (n - 1)
RI = 0.9
fun(CI, RI)
"""
求权重
"""
print('--------------------算数平均法--------------------')
A1_norm = A1 / A1.sum(axis=0) # 这样子可以快速进行归一化计算
print('归一化(按列):')
print(A1_norm)
print('权重(求平均值):')
w1 = A1_norm.mean(axis=1)
print(w1) # mean是求均值(axis=1是按行)
print('--------------------几何平均法--------------------')
w2 = np.prod(A1, axis=1) ** (1 / n) # np的连乘函数 并且 开n次根
w2 = w2 / w2.sum(axis=0)
print('权重:')
print(w2)
print('--------------------特征值法--------------------')
# 特征值、特征向量
eigenvalues, eigenvectors = np.linalg.eig(A1)
# 最大特征值的下标
k = np.argmax(np.real(eigenvalues))
# 对应特征向量(单位长度)
w3 = np.real(eigenvectors[:, k])
w3 = w3 / w3[-1] # (可去除的操作)除以最后一个分量,使得最后一个分量为1,复刻b站的数据
print('特征向量')
print(w3)
print('权重:')
w3 = w3 / w3.sum(axis=0)
print(w3)
print('############### 三个方案的结果对比 ###############')
print(w1)
print(w2)
print(w3)
print('############### 计算最终的权重 ###############')
A2 = np.array(
[w1, w2, w3]
)
A3 = np.array(
A2.sum(axis=0) / 3
)
print(A3)
print('############### 最终结果 ###############')
# 归一化结果:res1
result = np.array(res1) @ A3 # 归一化矩阵 × 权重向量
for name, score in zip(['小米', '华为', '苹果'], result):
print(f'{name}: {score:.3f}')附录 B 问题二(旅游地评价)
import numpy as np
"""
暑假想和朋友一起出去旅游,
暂定计划有
丽江、厦门、青岛、张家界,
需要考虑
交通便利性、
旅游资源丰富程度、
旅途开销、
安全和卫生情况,
请自行构建方案层、准则层判断矩阵,建立综合评价模型进行评价
"""
# 构建目标层、准则层、方案层
"""
目标层:旅游
准则层:交通便利性、旅游资源丰富程度、旅途开销、安全和卫生情况
方案层:丽江、厦门、青岛、张家界
"""
# 先主观(或者客观)构建权重的矩阵
"""
交通便利性 旅游资源丰富程度 旅途开销 安全和卫生情况
交通便利性 1 2 1/2 3
旅游资源丰富程度 1/2 1 1/2 2
旅途开销 2 2 1 3
安全和卫生情况 1/3 1/2 1/3 1
"""
# 构建这个判断矩阵
# 这个是判断矩阵
A = np.array([
[1, 2, 1/2, 3],
[1/2, 1, 1/2, 2],
[2, 2, 1, 3],
[1/3, 1/2, 1/3, 1]
])
n = len(A)
# 对数据进行归一化处理
# 这个是判断矩阵的归一化
A_norm = A / A.sum(axis=0)
print(f'归一化处理后的矩阵为:\n{A_norm}')
"""
[[0.26086957 0.36363636 0.21428571 0.33333333]
[0.13043478 0.18181818 0.21428571 0.22222222]
[0.52173913 0.36363636 0.42857143 0.33333333]
[0.08695652 0.09090909 0.14285714 0.11111111]]
"""
# 判断是否通过一致性检验
# -求特征向量
# 特征值、特征向量
eigenvalues, eigenvectors = np.linalg.eig(A)
eigenvalues_max = np.max(np.real(eigenvalues))
print(f'最大特征值为:\n{eigenvalues_max}')
# 现在开始求CI
CI = (eigenvalues_max - n) / (n - 1)
print(f'一致性指标CI为:\n{CI}')
# 我们是 n = 4,所以我们使用RI = 0.90
RI = 0.90
CR = CI / RI
print(f'一致性指标CR为:\n{CR}')
if CR < 0.1:
print("--> 通过一致性检验")
else:
print("--> 不通过一致性检验")
print('--------------------------------------------------------')
print('开始求权重')
print('--------------------------------------------------------')
print('--> 算数平均法:')
# 1.判断矩阵按列归一化(已算)
w1 = A_norm
# 2.将归一化的各列相加(=一行求和)后除以n得到权重 --> 求每行的平均数
# w1 = w1.sum(axis=1) / n
w1 = w1.mean(axis=1)
print(f'权重:{w1}')
print('--> 几何平均法:')
# 1.判断矩阵的元素按行相乘得到一个新的列向量
w2 = np.prod(A, axis=1)
# 2.将列向量的每个元素开n次方
w2 = w2 ** (1/n)
# 3.对该列向量进行归一化即可得到权重向量
w2 = w2 / w2.sum(axis=0)
print(f'权重:{w2}')
print('--> 特征值法:')
# 1.求特征值、特征向量(已经求过了)
# eigenvalues, eigenvectors = np.linalg.eig(A)
# 2.计算出矩阵的最大特征值以及特征向量
k = np.argmax(np.real(eigenvalues)) # 最大特征值的下标
w3 = np.real(eigenvectors[:, k]) # 取最大特征值对应的特征向量(去掉虚部)
# 3.进行归一化
w3 = w3 / w3.sum(axis=0)
print(f'权重:{w3}')
print('--------------------------------------------------------')
print('三个方法计算的结果为')
print('--------------------------------------------------------')
W = np.array([w1, w2, w3])
print(W)
print('--------------------------------------------------------')
print('求最终的权重')
print('--------------------------------------------------------')
w = W.mean(axis=0)
print(f'最终的权重为:\n={w}\n')
print(f'交通便利性:\t{w[0]}')
print(f'旅游资源丰富程度:\t{w[1]}')
print(f'旅途开销:\t{w[2]}')
print(f'安全和卫生情况:\t{w[3]}')
print('--------------------------------------------------------')
print('计算得分')
print('--------------------------------------------------------')
# 这个是叫AI生成的(一般好像是自己填的)。
"""
交通 资源 开销 安全
丽江 [ 7, 9, 1, 7 ]
厦门 [ 9, 8, 0, 9 ]
青岛 [ 9, 8, 1, 8 ]
张家界 [ 6, 9, 3, 8 ]
"""
data = np.array(
[
[7, 9, 1, 7],
[9, 8, 0, 9],
[9, 8, 1, 8],
[6, 9, 3, 8]
]
)
data = data / data.sum(axis=0)
# 矩阵乘法
result = data @ w
print(result)附录 C 运行结果
附录 A(问题一)关键输出
最大特征值:4.6075371100223474
CI = 0.20251237000744915
CR = CI/RI = 0.22501374445272126
一致性检验不通过!!!
-->需要重新调整
CI = 0.004840319544088996
CR = CI/RI = 0.005378132826765551
一致性检验通过
############### 计算最终的权重 ###############
[0.48282707 0.08821841 0.15712474 0.27182977]
############### 最终结果 ###############
小米: 0.359
华为: 0.353
苹果: 0.288附录 B(问题二)关键输出
最大特征值为:
4.071012577499603
一致性指标CI为:
0.02367085916653444
一致性指标CR为:
0.02630095462948271
--> 通过一致性检验
最终的权重为:
=[0.29261469 0.18628403 0.41352589 0.10757538]
交通便利性: 0.2926146940122872
旅游资源丰富程度: 0.18628402925285126
旅途开销: 0.41352589411478413
安全和卫生情况: 0.10757538262007749
计算得分
[0.22162206 0.15903977 0.23838321 0.38095496]注:本文 $RI$ 取 Saaty 原始表与司守奎《数学建模算法与应用》中的 $RI(4) = 0.90$。部分文献(如 Salomon 与 Gomes 2024)给出 $0.89$,两者差异不影响一致性检验结论。