层次分析法是什么
决策是指在很多方案里选一个,比如在北京理工大学和哈尔滨工业大学里选一个;在苏杭、北戴河。桂林里选一个地方去旅游。
一种”朴素“的决策思想是打分。
打分一般要考虑多个指标,每个指标,可能会有不同权重。比如认为选旅游景点,景色,价格,消费,饮食都是要考虑的指标,但是可能打分着对不同指标看重程度不同。
**层次分析法(AHP)**是一种决策方法,他将主观的”不同指标的重要程度“进行了量化,再定量比较,这是他的最大特点。
基本操作步骤
1.建立层次结构模型
以旅游问题为例。
我们要研究的问题是”选择旅游地“,属于目标层。
我们依据的指标有”景色“,”花费“,”居住“,”饮食“,”交通“,属于准则层。
我们的备选方案有”苏杭“,”北戴河“,”桂林“,属于决策层。
明白这个结构后,接下来要解决的问题就是确定准则层各指标的权重,各方案的打分,各方案的总分,最后给出决策。
2.构造判断矩阵
依据上表,对准则层的指标(C1,C2…Cn)两两比较。
基于比较结果构造矩阵
- cij表示与Cj相比Ci的重要程度)
- cii=1,即主对角线上元素为1
- cij>0且cij*cji=1(正互反矩阵)
3.一致性检验
可能出现上图的矛盾情况。
因为指标两两比较的主观性,一般的判断矩阵很难做到完全“逻辑上”合理。这就是说这个判断矩阵“不一致”。
如果不一致的程度太大,就认为这个判断矩阵无意义。以下是定量描述一致程度的方法。
(注:该方法的严谨数学证明此处省略,但可以知道以下定理成立)
定理1:n阶一致阵的唯一非零特征根为n
A是一致矩阵,当
定理2:n阶正互反阵A的最大特征根λ≥n,当且仅当λ=n时A为一致阵
定义一致性指标CI:
其中
为判断矩阵的最大特征根,n为准则层得指标个数。
查表得对应得平均一致性指标RI
定义一致性比率CR
一般,当一致性比率CR<0.1时,认为A的不一致程度在容许范围内,有满意的一致性,通过一致性检验。
(如果未通过一致性检验,可以自己往一致矩阵上面靠,改改数据)
4.将判断矩阵归一化处理
假如判断矩阵通过了一致性检验,接下来就要做归一化处理得到权重。
三种做法:
- 用每一列求一个权重,再求个算术平均
- 用每一列求一个权重,再求个几何平均
- 对最大特征值对应的特征向量归一化作为权重向量
5.用2到4的方法对每个准则层的对应方案层再分别打分
6.计算每个方案的最终得分
层次分析法评价
缺点:
- 决策层数据不能太多
- 决策层对应数据不是定性比较给出而是定量给出时不太适宜该做法
- 结果较为粗糙主观,泛化性差
优点:
**系统性:**将对象视作系统,按照分解、比较、判断、综合的思维方式进行决策。成为继机理分析、统计分析之后发展起来的系统分析的重要工具;
**实用性:**一定性与定量相结合,能处理许多用传统的最优化技术无法着手的实际问题,应用范围很广,同时,这种方法使得决策者与决策分析者能够相互沟通,决策者甚至可以直接应用它,这就增加了决策的有效性;
**简洁性:**计算简便,结果明确,具有中等文化程度的人即可以了解层次分析法的基本原理并掌握该法的基本步骤,容易被决策者了解和掌握。便于决策者直接了解和掌握。
(优点这一段来源:知乎/作者:子木/链接:https://zhuanlan.zhihu.com/p/266405027)
代码(python实现)
from copy import copy
import numpy as np
# 测试数据
# 5
# 0.90
# 0.5,4,3,3,7,5,5,0.5,0.33333,1
#数据录入
def input_data(n):
M=np.empty((n,n),float)
k=0
num=input("请输入上三角阵: ").split(',')
for i in range(len(num)):
num[i]=float(num[i])
for i in range(n):
M[i][i]=1
for j in range(i+1,n):
M[i][j]=num[k]
k+=1
M[j][i]=1/M[i][j]
return M
#一致性检验
CR=lambda lambda_max,RI,n: (lambda_max-n)/((n-1)*RI)
n=int(input("请输入判断矩阵的阶数: "))
IR=float(input("请输入IR: "))
M=input_data(n)
lambdas=np.linalg.eig(M)[0]
k=[]
for i in range(len(lambdas)):
if lambdas[i].imag==0:
k.append(lambdas[i])
for i in range(len(k)):
k[i]=k[i].real
lambda_max=max(k)
CR_value=CR(lambda_max,IR,n)
if CR_value<0.1:
print(f"CR={CR_value},通过一致性检验")
else:
print(f"CR={CR_value},未通过一致性检验")
#归一化处理
#算术平均
M1=copy(M)
M1=M1.T
for i in range(n):
M1[i]/=sum(M1[i])
suanshu=sum(M1)/n
print(f"算术平均后的权重: {suanshu}")
#几何平均
jihe=[]
for i in range(n):
t=1
for j in M[i]:
t*=j
t=pow(t,1/n)
jihe.append(t)
jihe/=sum(jihe)
print(f"几何平均后的权重: {jihe}")
#特征向量
for i in range(len(lambdas)):
if lambda_max==lambdas[i].real:
index=i;exit
T=np.linalg.eig(M)[1].T[index]
T/=sum(T)
tezhengxl=[]
for i in range(len(T)):
tezhengxl.append(T[i].real)
print(f"特征向量求出的的权重: {tezhengxl}")
本文为清风老师数学建模课程的学习笔记