Skip to content

AHP (层次分析法)

数学建模中的“入门必修课”

AHP (Analytic Hierarchy Process,层次分析法) 由美国运筹学家 Thomas L. Saaty 创立。通过将复杂问题分解为若干层次和若干因素,对两两指标之间的重要程度作出比较判断(主观),建立判断矩阵,通过计算判断矩阵的最大特征值以及对应特征向量,就可得出不同方案重要性程度的权重,为最佳方案的选择提供依据。其应用领域极为广泛,涵盖了商业管理、项目评估、资源分配、公共政策制定、供应链管理、环境风险评估乃至军事领域的冲突解决等多个方面。

适用场景

  • 评价类问题:如优秀论文评选、员工绩效考核。
  • 选址类问题:如工厂选址、物流中心布局。
  • 风险评估:如投资项目可行性分析。

模型原理

层次分析法要求将一个复杂、非结构化的决策问题,拆解成若干个更小、更易于理解和管理的组成部分,并将这些部分按照其内在的逻辑关系,组织成一个自上而下的层次结构模型。一个典型的层次分析法层次结构包含以下三个主要层面:

  • 目标层:位于层次结构的最顶端,代表决策的最终目的期望达成的结果
  • 准则层:位于中间层次,包含了用于评估备选方案优劣的一系列标准影响因素
  • 方案层:位于层次结构的最底层,包含了所有可供选择的决策方案行动路径

主要步骤

第1步:建立递阶层级结构模型

把问题拆解为「目标层—准则层—方案层」的层次结构(见图1),并明确每一层包含的元素集合。

AHP 层次结构示意图
图1 层次结构示意图

第2步:构造出各层次中的所有判断矩阵

对同一层中的因素做两两重要性比较(通常用 1-9 标度法,见表1),构造判断矩阵 ,其中 代表第 个因素对第 个因素的重要程度。在设定判断矩阵的程度值时,可以使用德尔菲法 (Delphi Method),也可直接根据实际业务专家的建议来确定。

表1 Saaty 的 1-9 标度法
标度含义
1两个因素相比,具有同等重要性
3两个因素相比,前者比后者稍微重要
5两个因素相比,前者比后者明显重要
7两个因素相比,前者比后者强烈重要
9两个因素相比,前者比后者极端重要
2、4、6、8上述相邻判断之间的中间值,表示重要性程度介于两者之间
倒数如果因素 与因素 的比较值为 ,则因素 与因素 的比较值为
Eg:第1个因素比第4个因素明显重要

依据表1,当“第1个因素比第4个因素明显重要”时,可取 ,并满足互反性

例如(只展示与第1、4个因素相关的元素):

提示

两两比较的过程中因为忽略了其他因素,导致最后的结果会产生常理上的矛盾,所以需要进行一致性检验(防止某个因素既重要又不重要)。

  • 例如:第1个因素比第2个因素明显重要,第2个因素比第3个因素明显重要;若此时存在第3个因素比第1个因素重要的情况,就会在逻辑上产生矛盾。

第3步:一致性检验

注:在实际操作中,第3步与第4步紧密相连,一致性检验需要用到第4步中计算出的最大特征值

在解释一致性检验的原理前,我们需要先了解两个概念:正互反矩阵一致矩阵

  • 正互反矩阵:若在矩阵 中,每个元素 且满足:

我们称该矩阵为正互反矩阵。在层次分析法中,我们构造的判断矩阵都是正互反矩阵。

  • 一致矩阵:若在正互反矩阵 中,进一步满足:

我们称该矩阵为一致矩阵。

由于实际评价中指标数量较多,构建完美的一致矩阵十分困难。一致性检验的目的,就是检验我们主观构造的判断矩阵与理想的“一致矩阵”之间是否存在不可接受的偏差。

具体推导(选看):一致矩阵的充要条件证明

判断一个矩阵是否为一致矩阵的充要条件证明较为复杂,实际运用中只需了解即可。证明如下:

  • 先证必要性: 设矩阵 为一致矩阵。由一致矩阵的定义, 为正互反矩阵且满足 。 首先,由于 为正互反矩阵,显然有 。 其次,根据正互反矩阵的定义 ,令 可得 。 最后,在一致性关系中令 ,则 ,因此 。 特别地,取 ,得 。代回上式,有 。 令 (由于 ,此时 ),则第 行满足 。必要性证毕。

  • 再证充分性: 反过来,若 ,且 ,并存在 使得 。 则有 。取 ,由 ,从而 。 因此 。 于是 ,即 为一致矩阵。充分性证毕。

具体推导(选看):一致矩阵的一些特点

引理 阶方阵,且 ,则 有一个特征值为 ,其余特征值为

由秩-零化度定理可知,。因此 中存在 个线性无关的非零向量。对任意 ,都有 ,这说明 是特征值 的特征向量。于是特征值 的代数重数至少为 。 除去至少 个为 的特征值外,至多还剩下一个非零特征值 。又由“特征值之和等于迹”,得出

特点一:最大特征值 在一致矩阵中,由于对角线元素都为 ,因此 ,即:

特点二:对应的特征向量 特征值为 时,对应的特征向量刚好为

(注:此处省去了繁琐的解齐次方程组 的行变换过程,核心在于一致矩阵的行与行之间成比例,经过初等行变换后,仅需解第一行的约束即可得出上述特征向量。)

不一致性与最大特征值

在一致矩阵中,我们已经得出 。当判断矩阵出现不一致时(即存在 使 ),矩阵会导致最大特征值严格大于 ,即:

因此 可以用来刻画“偏离一致性”的程度:判断越不一致, 往往越大, 也越大。

基于这个思想,Saaty 提出了常用的一致性指标(Consistency Index, CI):

其中 时有 ,表示完全一致; 越大,表示不一致程度越高。

▌ 一致性检验的具体步骤

计算一致性指标

查表获取平均随机一致性指标 (由矩阵阶数 决定):

表2 平均随机一致性指标 RI
n123456789101112131415
RI000.5250.8821.1101.2501.3411.4041.4511.4861.5141.5361.5551.5701.584
注:RI 值采用近年来更受认可的 Franek and Kresta (2014) 的方式。实际运用中,n 很少超过 10,如果 n 过大,则可考虑建立多级评价体系或使用其他模型。

计算一致性比例

  • ,通常认为判断矩阵的一致性可以接受。
  • ,认为一致性较差,需要对判断矩阵进行适当调整。(调整方向:将矩阵元素尽可能向行与行呈倍数关系的“一致矩阵”方向修正)。
层次总排序及一致性检验(选看,通常不予考虑)

最终我们要得到各元素(特别是最低层中各方案)对于总目标的排序权重。总排序权重需要自上而下地将各准则下的权重进行合成。

设上一层次( 层)包含 个因素,总排序权重为 。下一层次( 层)包含 个因素,它们关于 的单排序权重为 。则 层中各因素关于总目标的层次总排序权重为:

对层次总排序也需要做一致性检验,以防止各层次的微小非一致性累积。

当总排序 时,接受分析结果。

第4步:计算权重向量

在得到判断矩阵 并确认一致性后,我们需要求出权重向量:

在一致性较好时,下述三种方法算出来的权重通常非常接近。

4.1 算术平均法(列归一化)

直观理解:先把每一列“缩放成同一个尺度”,再把每一行取平均。

  • 第 1 步:按列归一化
  • 第 2 步:对归一化后的矩阵按行取平均,得到权重

4.2 几何平均法(方根法)

直观理解:每一行代表“该因素相对其它因素的总体优势”,用几何平均更符合“成比例比较”的特点。

  • 第 1 步:计算每一行元素的几何平均
  • 第 2 步:归一化得到权重

4.3 特征值法(AHP 经典方法)

直观理解:寻找一个向量 ,使得 的方向尽量一致。这个方向由最大特征值对应的特征向量给出。

  • 第 1 步:求最大特征值 及对应特征向量
  • 第 2 步:将特征向量归一化,使其和为 1

优缺点与注意事项

  • 优点:结构化、系统化,能将复杂问题层层分解;将主观评价转化为客观的权重数值;自带一致性检验机制,能及时发现专家打分中的逻辑矛盾。
  • 局限:主观性较强,极度依赖专家的经验,如果打分偏颇结果会失真;指标数量不能过多,同一层次的指标如果超过 9 个(即使目前表格扩展到了 15 阶),由于人类思维的局限性,很难通过一致性检验;只能在给定的方案中评价优劣,不能生成新方案。
  • 实践建议
    • 在数学建模比赛中,通常没有真正的 “专家”,可以由团队成员讨论模拟 “专家打分” 的过程,并在论文中说明。
    • 当一致性检验通不过()时,可以检查判断矩阵中严重违背常理的比较项,将其向满足 的方向做微调。
    • 当评价指标不仅有定性描述,还有充足的定量客观数据时,建议将 AHP 与 熵权法TOPSIS 等客观评价方法结合使用(例如 AHP-TOPSIS 综合评价模型),以达到主客观相互印证、平衡的效果。

完整代码实现(Python / MATLAB)

下面给出一份可以直接复用的 AHP 代码模板。

Python(NumPy)

python
import numpy as np

def ahp_calculator(matrix):
    """
    计算 AHP 判断矩阵的权重及一致性检验
    """
    # 1. 获取输入并检查矩阵有效性
    A = np.array(matrix, dtype=float)
    n, m = A.shape
    if n != m:
        raise ValueError("错误:判断矩阵必须是方阵!")

    # 2. 求解特征值与特征向量
    eigvals, eigvecs = np.linalg.eig(A)
    
    # 提取最大特征值的索引及数值
    max_eig_idx = np.argmax(np.real(eigvals))
    max_eig = np.real(eigvals[max_eig_idx])

    # 3. 一致性检验
    # n=1 或 2 时,矩阵一定具有完全一致性
    if n <= 2:
        CR = 0.0
    else:
        CI = (max_eig - n) / (n - 1)
        # 标准RI表 (n=1~15)
        RI = [0, 0, 0.525, 0.882, 1.110, 1.250, 1.341, 1.404, 1.451, 1.486, 1.514, 1.536, 1.555, 1.570, 1.584]
        if n > len(RI):
            raise ValueError("错误:矩阵维度超出15,无法查表获取RI值!")
        CR = CI / RI[n - 1]

    print(f"\n=== 一致性检验结果 ===")
    print(f"最大特征值 Max_eig = {max_eig:.4f}")
    print(f"一致性比例 CR = {CR:.4f}")

    if CR < 0.10:
        print("-> 因为 CR < 0.10,该判断矩阵A的一致性通过检验!")
        print("\n=== 权重计算结果 ===")

        # 方法1:算术平均法 (按列求和归一化后,按行求平均)
        W_arith = np.mean(A / np.sum(A, axis=0), axis=1)
        
        # 方法2:几何平均法 (按行连乘求n次方根后,再归一化)
        W_geom = np.prod(A, axis=1) ** (1 / n)
        W_geom = W_geom / np.sum(W_geom)
        
        # 方法3:特征值法 (取最大特征值对应的特征向量进行归一化)
        W_eigen = np.real(eigvecs[:, max_eig_idx])
        W_eigen = W_eigen / np.sum(W_eigen)

        # 格式化输出结果
        print("1. 算术平均法权重:", np.round(W_arith, 4))
        print("2. 几何平均法权重:", np.round(W_geom, 4))
        print("3. 特征值法权重:",   np.round(W_eigen, 4))
        
        return W_arith, W_geom, W_eigen
    else:
        print("-> 警告:CR >= 0.10,该判断矩阵A未通过一致性检验,需要重新调整矩阵元素!")
        return None, None, None


if __name__ == "__main__":
    # TODO: 在此处手动输入或替换为你的判断矩阵
    A = [
        [1,   2,   3,   5],
        [1/2, 1,   1/2, 2],
        [1/3, 2,   1,   2],
        [1/5, 1/2, 1/2, 1]
    ]
    ahp_calculator(A)

MATLAB

matlab
clc, clear;

% TODO: 请在此处手动输入判断矩阵 A
A = [
    1,   2,   3,   5;
    1/2, 1,   1/2, 2;
    1/3, 2,   1,   1/2;
    1/5, 1/2, 2,   1
];

% 1. 获取输入并检查矩阵有效性
[n, m] = size(A);            
if n ~= m
    error('错误:判断矩阵必须是方阵!');
end

% 2. 求解特征值与特征向量
[V, D] = eig(A);

% 提取对角线元素(特征值),并直接获取最大特征值及其所在列的索引 c
[Max_eig, c] = max(diag(D));

% 3. 一致性检验
% n=1 或 2 时,矩阵一定具有完全一致性
if n <= 2
    CR = 0;
else
    CI = (Max_eig - n) / (n - 1);
    % 标准RI表(支持到 n=15 )
    RI = [0, 0, 0.525, 0.882, 1.110, 1.250, 1.341, 1.404, 1.451, 1.486, 1.514, 1.536, 1.555, 1.570, 1.584];
    if n > length(RI)
        error('错误:矩阵维度超出15,无法查表获取RI值!');
    end
    CR = CI / RI(n);
end

fprintf('\n=== 一致性检验结果 ===\n');
fprintf('最大特征值 Max_eig = %.4f\n', Max_eig);
fprintf('一致性比例 CR = %.4f\n', CR);

if CR < 0.10
    disp('-> 因为 CR < 0.10,该判断矩阵A的一致性通过检验!');
    fprintf('\n=== 权重计算结果 ===\n');

    % 方法1:算术平均法 (按列归一化后按行求平均)
    W_arith = sum(A ./ sum(A, 1), 2) / n; 
    
    % 方法2:几何平均法 (按行连乘求n次方根后归一化)
    W_geom = prod(A, 2) .^ (1/n);         
    W_geom = W_geom / sum(W_geom);        
    
    % 方法3:特征值法 (取最大特征值对应的特征向量进行归一化)
    W_eigen = V(:, c) / sum(V(:, c));     
    
    % 输出展示
    disp('1. 算术平均法权重:'); disp(W_arith');
    disp('2. 几何平均法权重:'); disp(W_geom');
    disp('3. 特征值法权重:');   disp(W_eigen');
    
else
    disp('-> 警告:CR >= 0.10,该判断矩阵A未通过一致性检验,需要重新调整矩阵元素!');
end

参考资料