层次分析法原理介绍可参考以下文章:
2.https://blog.csdn.net/knighthood2001/article/details/127519604
这篇文章主要讨论层析分析法所需要用代码实现的过程
一、对权重矩阵一致性检验
(1)首先对权重矩阵进行判断,判断其是否为正互反对称矩阵
#输入矩阵
A = np.array([[1,2,6,3,5],
[1/2,1,4,2,3],
[1/6,1/4,1,1/3,1/2],
[1/3,1/2,3,1,2],
[1/5,1/3,2,1/2,1]])
'''判断正互反矩阵'''
def reciprocal_matrix_judge(a):
print(a)
n = len(a)
b = 0
for j in range(n):
for i in range(n):
if a[:, j][i] * a[j, :][i] == 1:
b += 1
if b == n*n:
print("该矩阵是正互反矩阵!\n")
return True
else:
print("该矩阵不是正互反矩阵!\n")
return False
reciprocal_matrix_judge(A)
(2)一致性指标需要用到两个公式:
![](https://i-blog.csdnimg.cn/blog_migrate/3388dbf6b3bea00acb2022c3ecaea517.png)
![](https://i-blog.csdnimg.cn/blog_migrate/24fb71105b48e76329033122349a6957.png)
计算CI首先需要计算权重矩阵的最大特征值,进而计算CI.然后,根据权重矩阵的阶n查找对应的平均随机一致性指标 RI.
![](https://i-blog.csdnimg.cn/blog_migrate/f09de0c771dbaf4da2b7d0b9bfa57f98.png)
求CR并进行一致性检验的完整代码如下:
import numpy as np
#输入矩阵
A = np.array([[1,2,6,3,5],
[1/2,1,4,2,3],
[1/6,1/4,1,1/3,1/2],
[1/3,1/2,3,1,2],
[1/5,1/3,2,1/2,1]])
#求解特征值即特征向量
lamda = np.linalg.eig(A)
for i in range(len(lamda[0])):
print('特征值:{0}\n对应的特征向量:\n{1}\n'.format(lamda[0][i], np.transpose([lamda[1][:,i]])))
index = np.argmax(lamda[0])
lamda_max = np.real(lamda[0][index])
vector = lamda[1][:,index]
vector_final = np.transpose((np.real(vector)))
print('最大特征值为:{0}\n对应的特征向量:\n{1}'.format(lamda_max, vector_final))
'''CI计算'''
def CI_calc(a,λ_max):
n = len(a)
print(λ_max)
CI = (λ_max-n)/(n-1)
print('CI:', CI)
return CI
'''CR计算'''
def CR_calc(a):
RI = np.array([0, 0, 0.52, 0.89, 1.12, 1.26, 1.36, 1.41,
1.46, 1.49, 1.52, 1.54, 1.56, 1.58, 1.59])
n = len(a)
CI = CI_calc(a,lamda_max)
CR = CI/RI[n-1]
print('CR:', CR)
if CR < 0.1:
print("一致性检验通过!\n")
return True
else:
print("一致性检验失败,请修改!")
return False
CR_calc(A)
二、求权重向量
算术平均法求权重
第一步:将判断矩阵按照列归一化(每一个元素除以其所在列的和)。
第二步:将归一化的列相加(按行求和)。
第三步:将相加后得到的向量中的每个元素除以 n 即可得到权重向量。
代码如下:
import numpy as np
from numpy import linalg
# np.set_printoptions(precision=4)
'''算术平均法权重'''
def arithmetic_mean(a):
n = len(a)
b = sum(a)
#print('b:', b)
# 归一化处理
normal_a = a/b
print("算术平均法权重-归一化处理:")
#print(normal_a)
average_weight = []
for i in range(n):
s = sum(normal_a[i])
print("第{}行求和 ".format(i+1), s)
# 平均权重
average_weight.append(s/n)
# print(average_weight)
print('算术平均法权重:')
print(np.array(average_weight))
return np.array(average_weight)
arithmetic_mean(A)
几何平均法求权重
第一步:将A的元素按照行相乘得到一个新的列向量。
第二步:将新的向量的每个分量开n次方。
第三步:对该列向量进行归一化即可得到权重向量。
代码如下:
'''几何平均法求权重'''
def geometric_mean(a):
n = len(a)
# 1表示按照行相乘,得到一个新的列向量
b = np.prod(a, 1)
#print(b)
c = pow(b, 1/n)
#print(c)
# 归一化处理
average_weight = c/sum(c)
print('几何平均法权重:')
print(average_weight)
return average_weight
geometric_mean(A)
特征值法求权重
第一步:求出矩阵A的最大特征值以及其对应的特征向量。
第一步:对求出的特征向量进行归一化即可得到我们的权重。
代码如下:
'''特征值法求权重'''
def eigenvalue(a):
w, v = np.linalg.eig(a)
# for i in range(len(w)):
# print('特征值', a[i], '特征向量', v[:, i])
index = np.argmax(w)
w_max = np.real(w[index])
vector = v[:, index]
vector_final = np.transpose(np.real(vector))
#print('最大特征值', w_max, '对应特征向量', vector_final)
normalized_weight = vector_final/sum(vector_final)
print('***归一化处理后:', normalized_weight)
return w_max, normalized_weight
eigenvalue(A)
对最大特征值取小数点四位可以替换成下面的代码
w_max = round(np.real(w[index]),4)
上述代码参考:https://blog.csdn.net/knighthood2001/article/details/127519604