AHP(層次分析法)
層次分析法(The analytic hierarchy process)簡稱AHP,在20世紀70年代中期由美國運籌學家托馬斯·塞蒂(TLsaaty)正式提出。它是一種定性和定量相結合的、系統化、層次化的分析方法。由於它在處理復雜的決策問題上的實用性和有效性,很快在世界范圍得到重視。它的應用已遍及經濟計划和管理、能源政策和分配、行為科學、軍事指揮、運輸、農業、教育、人才、醫療和環境等領域。
層次分析法的基本步驟
1、建立層次結構模型。在深入分析實際問題的基礎上,將有關的各個因素按照不同屬性自上而下地分解成若干層次,同一層的諸因素從屬於上一層的因素或對上層因素有影響,同時又支配下一層的因素或受到下層因素的作用。最上層為目標層,通常只有1個因素,最下層通常為方案或對象層,中間可以有一個或幾個層 次,通常為准則或指標層。當准則過多時(譬如多於9個)應進一步分解出子准則層。
2、構造成對比較陣。從層次結構模型的第2層開始,對於從屬於(或影響)上一層每個因素的同一層諸因素,用成對比較法和1—9比較尺度構造成對比較陣,直到最下層。
3、計算權向量並做一致性檢驗。對於每一個成對比較陣計算最大特征根及對應特征向量,利用一致性指標、隨機一致性指標和一致性比率做一致性檢驗。若檢驗通過,特征向量(歸一化后)即為權向量:若不通過,需重新構造成對比較陣。
4、計算組合權向量並做組合一致性檢驗。計算最下層對目標的組合權向量,並根據公式做組合一致性檢驗,若檢驗通過,則可按照組合權向量表示的結果進行決策,否則需要重新考慮模型或重新構造那些一致性比率較大的成對比較陣。
建立層次結構模型
例--選拔干部模型
對三個干部候選人y 1、y 2、y 3,按選拔干部的五個標准:品德、才能、資歷、年齡和群眾關系,構成如下層次分析模型:假設有三個干部候選人y 1、y 2、y 3,按選拔干部的五個標准:品德,才能,資歷,年齡和群眾關系,構成如下層次分析模型

構造成對比較矩陣
比較第i個元素與第j個元素相對上一層某個因素的重要性時,使用數量化的相對權重a i j來描述。設共有n個元素參與比較,則
稱為成對比較矩陣。
成對比較矩陣中a i j的取值可參考Satty的提議,按下述標度進行賦值。a i j在1-9及其倒數中間取值。
- a i j = 1,元素i與元素j對上一層次因素的重要性相同;
- a i j = 3,元素i比元素j略重要;
- a i j = 5,元素i比元素j重要;
- a i j = 7,元素i比元素j重要得多;
- a i j = 9,元素i比元素j的極其重要;
- a i j = 2 n,n=1,2,3,4,元素i與j的重要性介於 a i j = 2 n − 1與 a i j = 2 n + 1之間;
,n=1,2,...,9,當且僅當a j i = n。
成對比較矩陣的特點:
。(備注:當i=j時候,a i j = 1)
選拔干部考慮5個條件:品德x 1,才能x 2,資歷x 3,年齡x 4,群眾關系x 5。某決策人用成對比較法,得到成對比較陣如下:
a 14 = 5表示品德與年齡重要性之比為5,即決策人認為品德比年齡重要。
作一致性檢驗
從理論上分析得到:如果A是完全一致的成對比較矩陣,應該有

但實際上在構造成對比較矩陣時要求滿足上述眾多等式是不可能的。因此退而要求成對比較矩陣有一定的一致性,即可以允許成對比較矩陣存在一定程度的不一致性。
由分析可知,對完全一致的成對比較矩陣,其絕對值最大的特征值等於該矩陣的維數。對成對比較矩陣的一致性要求,轉化為要求: 的絕對值最大的特征值和該矩陣的維數相差不大。
檢驗成對比較矩陣A一致性的步驟如下:
- 計算衡量一個成對比較矩陣A (n>1 階方陣)不一致程度的指標CI:

RI是這樣得到的:對於固定的n,隨機構造成對比較陣A,其中a i j是從1,2,…,9,1/2,1/3,…,1/9中隨機抽取的.這樣的A是不一致的,取充分大的子樣得到A的最大特征值的平均值
| n | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| RI | 0 | 0 | 0.58 | 0.90 | 1.12 | 1.24 | 1.32 | 1.41 | 1.45 |
注解:
- 從有關資料查出檢驗成對比較矩陣A 一致性的標准RI:RI稱為平均隨機一致性指標,它只與矩陣階數n 有關(一般不超過9個)。
- 按下面公式計算成對比較陣A 的隨機一致性比率CR:
。
- 判斷方法如下: 當CR<0.1時,判定成對比較陣A 具有滿意的一致性,或其不一致程度是可以接受的;否則就調整成對比較矩陣A,直到達到滿意的一致性為止。
例子的矩陣

特征向量: 0.47439499 0.26228108 0.0544921 0.09853357 0.11029827 (相加等於1)
算法過程 先對數組進行列相加----- [2.04285714,3.91666667,17 ,10.5 ,10.33333333]
再用等到的結果除以原矩陣得到一個新的矩陣:

再對矩陣進行行相加等到-------[2.37197494 1.31140538 0.2724605 0.49266783 0.55149136]
在進行歸一化處理(上面的結果被階數除)得到上面的特征向量(結果發現品德的影響最大)

AW = 特征向量*原矩陣(一開始的),然后拿到每一行的和---- [2.42456102 1.34394248 0.27386595 0.50012206 0.55461416]
所以可得 (AW/階數*特征向量) 5.07293180152562
計算得到
,查得RI=1.12,

這說明A 不是一致陣,但A 具有滿意的一致性,A 的不一致程度是可接受的。
層次總排序及決策
現在來完整地解決例2的問題,要從三個候選人y 1 , y 2 , y 3中選一個總體上最適合上述五個條件的候選人。對此,對三個候選人y = y 1 , y 2 , y 3分別比較他們的品德( x 1 ),才能( x 2 ),資歷( x 3 ),年齡( x 4 ),群眾關系( x 5 )。
先成對比較三個候選人的品德,得成對比較陣

經計算,B 1的權向量
ω x 1 ( Y ) = (0.082,0.236,0.682) z

故B 1的不一致程度可接受。ω x 1 ( Y )可以直觀地視為各候選人在品德方面的得分。
類似地,分別比較三個候選人的才能,資歷,年齡,群眾關系得成對比較陣

B5=
可得 5個特征向量

然后在通過
第一個人:(0.08199023*0.47439499 (一開始的那個特征向量)+0.59488796*0.26228108 +0.42857143*0.0544921 +0.63274854*0.09853357 +0.34595035*0.11029827 ) = 總得分
后兩個人類似
最后得 第一個人得 0.31878206
第二個人得 0.23919592
第三個人得 0.44202202
所以3號是第一候選人
層次分析法的用途舉例
例如,某人准備選購一台電冰箱,他對市場上的6種不同類型的電冰箱進行了解后,在決定買那一款式時,往往不是直接拿電冰箱整體進行比較,因為存在許多不可比的因素,而是選取一些中間指標進行考察。例如電冰箱的容量、制冷級別、價格、型號、耗電量、外界信譽、售后服務等。然后再考慮各種型號冰箱在上述各中間標准下的優劣排序。借助這種排序,最終作出選購決策。在決策時,由於6種電冰箱對於每個中間標准的優劣排序一般是不一致的,因此,決策者首先要對這7個標准的重要度作一個估計,給出一種排序,然后把6種冰箱分別對每一個標准的排序權重找出來,最后把這些信息數據綜合,得到針對總目標即購買電冰箱的排序權重。有了這個權重向量,決策就很容易了。
運用AHP法進行決策時,需要經歷以下4個步驟:
1、建立系統的遞階層次結構;
2、構造兩兩比較判斷矩陣;(正互反矩陣)
3、針對某一個標准,計算各備選元素的權重;
4、計算當前一層元素關於總目標的排序權重。
5、進行一致性檢驗。
附錄 示例代碼(python)
#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np RI_dict = {1: 0, 2: 0, 3: 0.58, 4: 0.90, 5: 1.12, 6: 1.24, 7: 1.32, 8: 1.41, 9: 1.45} def get_w(array): row = array.shape[0] # 計算出階數 a_axis_0_sum = array.sum(axis=0) # print(a_axis_0_sum) b = array / a_axis_0_sum # 新的矩陣b # print(b) b_axis_0_sum = b.sum(axis=0) b_axis_1_sum = b.sum(axis=1) # 每一行的特征向量 # print(b_axis_1_sum) w = b_axis_1_sum / row # 歸一化處理(特征向量) nw = w * row AW = (w * array).sum(axis=1) # print(AW) max_max = sum(AW / (row * w)) # print(max_max) CI = (max_max - row) / (row - 1) CR = CI / RI_dict[row] if CR < 0.1: # print(round(CR, 3)) # print('滿足一致性') # print(np.max(w)) # print(sorted(w,reverse=True)) # print(max_max) # print('特征向量:%s' % w) return w else: print(round(CR, 3)) print('不滿足一致性,請進行修改') def main(array): if type(array) is np.ndarray: return get_w(array) else: print('請輸入numpy對象') if __name__ == '__main__': # 由於地方問題,矩陣我就寫成一行了 e = np.array([[1, 2, 7, 5, 5], [1 / 2, 1, 4, 3, 3], [1 / 7, 1 / 4, 1, 1 / 2, 1 / 3], [1 / 5, 1 / 3, 2, 1, 1], [1 / 5, 1 / 3, 3, 1, 1]]) a = np.array([[1, 1 / 3, 1 / 8], [3, 1, 1 / 3], [8, 3, 1]]) b = np.array([[1, 2, 5], [1 / 2, 1, 2], [1 / 5, 1 / 2, 1]]) c = np.array([[1, 1, 3], [1, 1, 3], [1 / 3, 1 / 3, 1]]) d = np.array([[1, 3, 4], [1 / 3, 1, 1], [1 / 4, 1, 1]]) f = np.array([[1, 4, 1 / 2], [1 / 4, 1, 1 / 4], [2, 4, 1]]) e = main(e) a = main(a) b = main(b) c = main(c) d = main(d) f = main(f) try: res = np.array([a, b, c, d, f]) ret = (np.transpose(res) * e).sum(axis=1) print(ret) except TypeError: print('數據有誤,可能不滿足一致性,請進行修改')
