1. 程式人生 > >層次分析法---python實現

層次分析法---python實現

層次分析法(The analytic hierarchy process)簡稱AHP

在20世紀70年代中期由美國運籌學家托馬斯·塞蒂(T.L.saaty)正式提出。它是一種定性和定量相結合的、系統化、層次化的分析方法。由於它在處理複雜的決策問題上的實用性和有效性,很快在世界範圍得到重視。它的應用已遍及經濟計劃和管理、能源政策和分配、行為科學、軍事指揮、運輸、農業、教育、人才、醫療和環境等領域。

比較常用的場合是進行決策,層次分析法是一種比較常見的多目標決策方法。其實我看來,層次分析法就是一種按照層次結構計算加權和的方法,主要是權重的選取,這裡人為因素太大,比較容易受到詬病。

具體的理論,可以參考wiki

,附上網址:https://wiki.mbalib.com/wiki/%E5%B1%82%E6%AC%A1%E5%88%86%E6%9E%90%E6%B3%95

層次分析法的多級遞階層次模型分為三類:完全相關性結構、完全獨立性結構、混合型結構。

前兩種分別對應於下圖的圖1,2(來自網路,侵刪):

                                 

                                                                                 圖1 . 完全相關性

                                         

                                                                                 圖2. 完全獨立性

混合型就是具備兩種的特點。其實也不需要管這個了,就是按照自己的需要搭建好層次結構就可以了,有了結構下面開始擼程式碼。

示例:

此次我們實現的是這樣的層次結構,如圖3,同時我們假設成對比較矩陣已經按照尺度表定義好(尺度表即表示相對權重,在wiki中可以找到),實際應用中可以根據需求求解成對比較矩陣。

                                   

                                                                             圖3. 示例的層次結構圖

python3 程式碼。

# -*- coding: utf-8 -*-
"""
Created on Tue Nov 13 15:37:12 2018

@author: user
"""

"""
AHP demo: 第一層:A, 第二層:B1 B2 B3, 第三層:C1 C2 C3, 完全相關性結構。
"""

import numpy as np

"""
1. 成對比較矩陣 
"""
def comparision(W0):  # W為每個資訊值的權重
    n=len(W0)
    F=np.zeros([n,n])
    for i in range(n):
        for j in range(n):
            if i==j:
                F[i,j]=1
            else:
                F[i,j]=W0[i]/W0[j]
    return F
                
"""
2. 單層排序,相對重要度
"""
def ReImpo(F):
    n=np.shape(F)[0]
    W=np.zeros([1,n])
    for i in range(n):
        t=1
        for j in range(n):
            t=F[i,j]*t
        W[0,i]=t**(1/n)
    W=W/sum(W[0,:])  # 歸一化 W=[0.874,2.467,0.464]
    return W.T

"""
3. 一致性檢驗
"""
def isConsist(F):
    n=np.shape(F)[0]
    a,b=np.linalg.eig(F)
    maxlam=a[0].real
    CI=(maxlam-n)/(n-1)
    if CI<0.1:
        return bool(1)
    else:
        return bool(0)
"""
4. 計算綜合重要性
"""
def ComImpo(W12,W231,W232,W233):  # 綜合重要性
    #F12=comparision(W12)  # 實際應用中可以根據特徵的權重求解成對比較矩陣。
    #F231=comparision(W231)
    #F232=comparision(W232)
    #F233=comparision(W233)
    F12=np.array([[1,1/3,2],[3,1,5],[1/2,1/5,1]])  # 此處直接假設出成對比較矩陣
    F231=np.array([[1,1/3,1/5],[3,1,1/3],[5,3,1]])
    F232=np.array([[1,2,7],[1/2,1,5],[1/7,1/5,1]])
    F233=np.array([[1,1/3,1/7],[3,1,1/5],[7,5,1]])
    
    if isConsist(F12) and isConsist(F231) and isConsist(F232) and isConsist(F233):
        W12=ReImpo(F12)
        W231=ReImpo(F231)
        W232=ReImpo(F232)
        W233=ReImpo(F233)
        W23=np.hstack([W231,W232,W233])
    else:
        print("成對比較矩陣不一致,請調整權重後重試!")
        return 0
    n=len(W12)
    C=np.zeros([1,n])
    for i in range(n):
        t=W23[i,:]
        C[0,i]=sum((W12.T*t)[0])
    return C

def main():
    print("這裡是AHP的演示程式:")
    w=np.ones([3])  # W 為成對比較矩陣
    C=ComImpo(w,w,w,w)
    print('最佳方案為第',np.argmax(C)+1,'個方案.','綜合推薦指數為',max(C[0,:]))



if __name__ == '__main__':
    main()
    # print(__name__)