麗水網(wǎng)站建設哪家好網(wǎng)址導航哪個好
數(shù)學建模筆記——TOPSIS[優(yōu)劣解距離法]
- TOPSIS(優(yōu)劣解距離)法
- 1. 基本概念
- 2. 模型原理
- 3. 基本步驟
- 4. 典型例題
- 4.1 矩陣正向化
- 4.2 正向矩陣標準化
- 4.3 計算得分并歸一化
- 4.4 python代碼實現(xiàn)
TOPSIS(優(yōu)劣解距離)法
1. 基本概念
C. L.Hwang和 K.Yoon于1981年首次提出 TOPSIS(Technique for Order Preference by Similarity to an Ideal Solution),可翻譯為逼近理想解排序法,國內常簡稱為優(yōu)劣解距離法。
TOPSIS法是一種常用的綜合評價方法,能充分利用原始數(shù)據(jù)的信息,其結果能精確地反映各評價方案之間的差距。
TOPSIS法引入了兩個基本概念:
- 理想解:設想的最優(yōu)的解(方案),它的各個屬性值都達到各備選方案中的最好的值;
- 負理想解:設想的最劣的解(方案),它的各個屬性值都達到各備選方案中的最壞的值。方案排序的規(guī)則是把各備選方案與理想解和負理想解做比較,若其中有一個方案最接近理想解,而同時又遠離負理想解,則該方案是備選方案中最好的方案。TOPSIS通過最接近理想解且最遠離負理想解來確定最優(yōu)選擇。

2. 模型原理
TOPSIS法是一種理想目標相似性的順序選優(yōu)技術,在多目標決策分析中是一種非常有效的方法。它通過歸一化后(去量綱化)的數(shù)據(jù)規(guī)范化矩陣,找出多個目標中最優(yōu)目標和最劣目標(分別用理歸想一解化和反理想解表示),分別計算各評價目標與理想解和反理想解的距離,獲得各目標與理想解的貼近度,按理想解貼近度的大小排序,以此作為評價目標優(yōu)劣的依據(jù)。貼近度取值在0~1之間,該值愈接近1,表示相應的評價目標越接近最優(yōu)水平;反之,該值愈接近0,表示評價目標越接近最劣水平。
3. 基本步驟
-
將原始矩陣正向化
將原始矩陣正向化,就是要將所有的指標類型統(tǒng)一轉化為極大型指標
-
將正向化矩陣標準化
標準化的方法有很多種,其主要目的就是去除量綱的影響,保證不同評價指標在同一數(shù)量級,且數(shù)據(jù)大小排序不
-
計算得分并歸一化
S i = D i ? D i + + D i ? S_{i}=\frac{D_{i}^{-}}{D_{i}^{+}+D_{i}^{-}} Si?=Di+?+Di??Di???,其中 S i S_{i} Si?為得分, D i + {D_{i}^{+}} Di+?為評價對象與最大值的距離, D i ? D_{i}^{-} Di??
為評價對象與最小值的距離。
4. 典型例題
明星Kun想找一個對象,但喜歡他的人太多,不知道怎么選,經(jīng)過層層考察,留下三個候選人。他認為身高165是最好的,體重在90-100斤是最好的。
候選人 顏值 牌氣(爭吵次數(shù)) 身高 體重 A 9 10 175 120 B 8 7 164 80 C 6 3 157 90
4.1 矩陣正向化
常見的指標類型:
指標名稱 | 指標特點 | 例子 |
---|---|---|
極大型 (效益型) 指標 | 越大(多)越好 | 成績、 GDP增速、 企業(yè)利潤 |
極小型 (成本型) 指標 | 越小(少)越好 | 費用、 壞品率、污染程度 |
中間型指標 | 越接近某個值越好 | 水質量評估時的PH值 |
區(qū)間型指標 | 落在某個區(qū)間最好 | 體溫、 水中植物性營養(yǎng)物量 |
在 TOPSIS 方法中,就是要將所有指標進行統(tǒng)一正向化,即統(tǒng)一轉化為極大型指標。 那么就需要極小型、中間型以及區(qū)間型的指標進行轉化為極大型指標。
指標名稱 | 公式 |
---|---|
極大型(效益型)指標 | / |
極小型(成本型)指標 | x ~ = m a x ? x \tilde{x} = max-x x~=max?x, x ~ \tilde{x} x~為指標值, m a x max max為指標最大值, x x x為指標值 |
中間型指標 | { x i } \{x_i\} {xi?} 是一組中間型序列,最優(yōu)值是 x b e s t x_{best} xbest?,$M = max{ |
區(qū)間型指標 | x i {x_i} xi?是一組區(qū)間型序列,最佳區(qū)間為 [ a , b ] [a,b] [a,b],正向化公式如下 M = m a x { a ? m i n { x i } , m a x { x i } ? b } , x ~ i = { 1 ? a ? x i M , x i < a 1 , a ≤ x i ≤ b 1 ? x i ? b M , x i > b M=max\{a-min\{x_i\}, max\{x_i\}-b\}, \widetilde{x}_i=\begin{cases}1-\frac{a-x_i}{M}, x_i<a\\1, a\leq x_i\leq b\\1-\frac{x_i-b}{M}, x_i>b\end{cases} M=max{a?min{xi?},max{xi?}?b},x i?=? ? ??1?Ma?xi??,xi?<a1,a≤xi?≤b1?Mxi??b?,xi?>b? |
-
顏值為極大型指標
-
脾氣為極小型指標
候選人 顏值 m a x max max m a x ? x max-x max?x A 10 10 0 B 7 10 3 C 3 10 7 -
身高為中間型指標
候選人 身高 x b e s t x_{best} xbest? | x i ? x b e s t x_i-x_{best} xi??xbest?| x ^ i \hat{x}_i x^i? A 175 165 10 1 B 164 165 1 1/10 C 157 165 8 8/10 -
體重為區(qū)間型指標
候選人 體重 M M M x ^ i \hat{x}_i x^i? A 120 20 0 B 80 20 1/2 C 90 20 1
正向化后的矩陣為
候選人 | 顏值 | 牌氣(爭吵次數(shù)) | 身高 | 體重 |
---|---|---|---|---|
A | 9 | 0 | 0 | 0 |
B | 8 | 3 | 0.9 | 0.5 |
C | 6 | 7 | 0.2 | 1 |
4.2 正向矩陣標準化
標準化的目的是消除不同指標量綱的影響
假設有n個要評價的對象,m個評價指標(已經(jīng)正向化了)構成的正向化矩陣如下:
X = [ x 11 x 12 ? x 1 m x 21 x 22 ? x 2 m ? ? ? ? x n 1 x n 2 ? x n m ] X=\begin{bmatrix}x_{11}&x_{12}&\cdots&x_{1m}\\x_{21}&x_{22}&\cdots&x_{2m}\\\vdots&\vdots&\ddots&\vdots\\x_{n1}&x_{n2}&\cdots&x_{nm}\end{bmatrix} X= ?x11?x21??xn1??x12?x22??xn2???????x1m?x2m??xnm?? ?
那么對其標準化后的矩陣記為Z,Z的每一個元素:
z i j = x i j ∑ i = 1 n x i j 2 z_{ij}=\frac{x_{ij}}{\sqrt{\sum_{i=1}^nx_{ij}^2}} zij?=∑i=1n?xij2??xij??
即(每一個元素/根號下所在列元素的平方和)得到標準化矩陣Z:
Z = [ z 11 z 12 ? z 1 m z 21 z 22 ? z 2 m ? ? ? ? z n 1 z n 2 ? z n m ] Z=\begin{bmatrix}z_{11}&z_{12}&\cdots&z_{1m}\\z_{21}&z_{22}&\cdots&z_{2m}\\\vdots&\vdots&\ddots&\vdots\\z_{n1}&z_{n2}&\cdots&z_{nm}\end{bmatrix} Z= ?z11?z21??zn1??z12?z22??zn2???????z1m?z2m??znm?? ?
標準化后,還需要給不同指標加上權重,采用的權重確定方法有層次分析法、熵權法、Delphi法、對數(shù)最小二乘法。這里認為各個指標權重相同。
對上述矩陣進行標準化,得
候選人 | 顏值 | 牌氣(爭吵次數(shù)) | 身高 | 體重 |
---|---|---|---|---|
A | 0.669 | 0 | 0 | 0 |
B | 0.595 | 0.394 | 0.976 | 0.447 |
C | 0.446 | 0.919 | 0.217 | 0.894 |
4.3 計算得分并歸一化
定義最大值:
Z + = ( m a x { z 11 , z 21 , ? , z n 1 } , m a x { z 12 , z 22 , ? , z n 2 } , ? , m a x { z 1 m , z 2 m , ? , z n m } ) Z^+=(max\{z_{11},z_{21},\cdots,z_{n1}\},max\{z_{12},z_{22},\cdots,z_{n2}\},\cdots,max\{z_{1m},z_{2m},\cdots,z_{nm}\}) Z+=(max{z11?,z21?,?,zn1?},max{z12?,z22?,?,zn2?},?,max{z1m?,z2m?,?,znm?})
定義最小值:
Z ? = ( m i n { z 11 , z 21 , ? , z n 1 } , m i n { z 12 , z 22 , ? , z n 2 } , ? , m i n { z 1 m , z 2 m , ? , z n m } ) Z^-=(min\{z_{11},z_{21},\cdots,z_{n1}\},min\{z_{12},z_{22},\cdots,z_{n2}\},\cdots,min\{z_{1m},z_{2m},\cdots,z_{nm}\}) Z?=(min{z11?,z21?,?,zn1?},min{z12?,z22?,?,zn2?},?,min{z1m?,z2m?,?,znm?})
定義第i (i=1,2,…,n) 個評價對象與最大值的距離:
D i + = ∑ j = 1 m ( Z j + ? z i j ) 2 D_i^+=\sqrt{\sum_{j=1}^m(Z_j^+-z_{ij})^2} Di+?=j=1∑m?(Zj+??zij?)2?
定義第i (i=1,2,…,n) 個評價對象與最小值的距離:
D i ? = ∑ j = 1 m ( Z j ? ? z i j ) 2 D_i^-=\sqrt{\sum_{j=1}^m(Z_j^--z_{ij})^2} Di??=j=1∑m?(Zj???zij?)2?
那么,我們可以計算得出第 i( i=1,2,…,n) 個評價對象未歸一化的得分:
S i = D i ? D i + + D i ? S_i=\frac{D_i^-}{D_i^++D_i^-} Si?=Di+?+Di??Di???
很明顯 0≤Si≤1,且 Si 越大 Di+ 越小,即越接近最大值。
我們可以將得分歸一化并換成百分制:
S i ~ = S i ∑ i = 1 n S i × 100 \widetilde{S_{\mathrm{i}}}=\frac{S_{\mathrm{i}}}{\sum_{i=1}^{n}S_{\mathrm{i}}}\times100 Si? ?=∑i=1n?Si?Si??×100
4.4 python代碼實現(xiàn)
import numpy as np# 從用戶輸入?yún)⒃u數(shù)目和指標數(shù)目
print("請輸入?yún)⒃u數(shù)目:")
n = int(input())
print("請輸入指標數(shù)目:")
m = int(input())# 接受用戶輸入的類型矩陣
print("請輸入類型矩陣:1. 極大型 2. 極小型 3. 中間型 4.區(qū)間型")
kind = input().split(" ")# 接受用戶輸入的矩陣并轉化為向量
print("請輸入矩陣:")
A = np.zeros(shape=(n, m))
for i in range(n):A[i] = input().split(" ")A[i] = list(map(float, A[i]))
print("輸入矩陣為:\n{}".format(A))# 極小型指標轉化為極大型指標的函數(shù)def minTomax(maxx, x):x = list(x)ans = [[(maxx-e) for e in x]]return np.array(ans)# 中間型指標轉化為極大型指標的函數(shù)def midTomax(bestx, x):x = list(x)h = [abs(e-bestx) for e in x]M = max(h)if M == 0:M = 1 # 防止最大差值為0的情況ans = [[1-(e/M) for e in h]]return np.array(ans)# 區(qū)間型指標轉化為極大型指標的函數(shù)def regTomax(lowx, highx, x):x = list(x)M = max(lowx-min(x), max(x)-highx)if M == 0:M = 1 # 防止最大差值為0的情況ans = []for i in range(len(x)):if x[i] < lowx:ans.append(1-(lowx-x[i])/M)elif x[i] > highx:ans.append(1-(x[i]-highx)/M)else:ans.append(1)return np.array([ans])# 同一指標類型,將所有指標轉化為極大型指標
X = np.zeros(shape=(n, 1))
for i in range(m):if kind[i] == "1":v = np.array(A[:, i])elif kind[i] == "2":maxA = max(A[:, i])v = minTomax(maxA, A[:, i])elif kind[i] == "3":print("類型三,請輸入最優(yōu)值:")bestA = eval(input())v = midTomax(bestA, A[:, i])elif kind[i] == "4":print("類型四,請輸入?yún)^(qū)間[a,b]值a:")lowA = eval(input())print("類型四,請輸入?yún)^(qū)間[a,b]值b:")highA = eval(input())v = regTomax(lowA, highA, A[:, i])if i == 0:X = v.reshape(-1, 1) # 如果是第一個指標,直接賦值else:X = np.hstack((X, v.reshape(-1, 1))) # 如果不是第一個指標,橫向拼接
print("統(tǒng)一指標后矩陣為:\n{}".format(X))# 對統(tǒng)一指標后的矩陣進行標準化處理
X = X.astype(float) # 將X轉化為浮點型
for i in range(m):X[:, i] = X[:, i]/np.sqrt(sum(X[:, i]**2)) # 對每一列進行歸一化處理,即除以該列的歐幾里得范數(shù)
print("標準化后矩陣為:\n{}".format(X))# 最大值和最小值距離的計算
x_max = np.max(X, axis=0) # 計算每一列的最大值
x_min = np.min(X, axis=0) # 計算每一列的最小值
# 計算每一個參評對象與最優(yōu)情況的距離d+
d_z = np.sqrt(np.sum(np.square(X-np.tile(x_max, (n, 1))), axis=1))
# 計算每一個參評對象與最差情況的距離d-
d_f = np.sqrt(np.sum(np.square(X-np.tile(x_min, (n, 1))), axis=1))
print("每個指標的最大值為:{}".format(x_max))
print("每個指標的最小值為:{}".format(x_min))# 計算每一個參評對象的綜合得分
s = d_f/(d_f+d_z) # 根據(jù)d+和d-計算每一個參評對象的得分,其中s接近1表示越好,接近0表示越差
Score = 100*s/sum(s) # 將得分轉換為百分制
for i in range(n):print(f"第{i+1}個參評對象的得分為:{Score[i]}")
輸入:
請輸入?yún)⒃u數(shù)目:
3
請輸入指標數(shù)目:
4
請輸入類型矩陣:1. 極大型 2. 極小型 3. 中間型 4.區(qū)間型
1 2 3 4
請輸入矩陣:
9 10 175 120
8 7 164 80
6 3 157 90
輸入矩陣為:
[[ 9. 10. 175. 120.][ 8. 7. 164. 80.][ 6. 3. 157. 90.]]
類型三,請輸入最優(yōu)值:
165
類型四,請輸入?yún)^(qū)間[a,b]值a:
90
類型四,請輸入?yún)^(qū)間[a,b]值b:
100
輸出:
統(tǒng)一指標后矩陣為:
[[9. 0. 0. 0. ][8. 3. 0.9 0.5][6. 7. 0.2 1. ]]
標準化后矩陣為:
[[0.66896473 0. 0. 0. ][0.59463532 0.3939193 0.97618706 0.4472136 ][0.44597649 0.91914503 0.21693046 0.89442719]]
每個指標的最大值為:[0.66896473 0.91914503 0.97618706 0.89442719]
每個指標的最小值為:[0.44597649 0. 0. 0. ]
第1個參評對象的得分為:8.886366735657832
第2個參評對象的得分為:45.653341055701134
第3個參評對象的得分為:45.46029220864103