AHP层次分析法python实现

层次分析法原理介绍可参考以下文章:

  1. https://blog.csdn.net/weixin_53972936/article/details/122775543

2.https://blog.csdn.net/knighthood2001/article/details/127519604

  1. https://blog.csdn.net/weixin_43095238/article/details/108055579

这篇文章主要讨论层析分析法所需要用代码实现的过程

一、对权重矩阵一致性检验

(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)一致性指标需要用到两个公式:

计算CI首先需要计算权重矩阵的最大特征值,进而计算CI.然后,根据权重矩阵的阶n查找对应的平均随机一致性指标 RI.

求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

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值