> 文章列表 > 最优最差多准则决策方法(BWMCDM)Python实现

最优最差多准则决策方法(BWMCDM)Python实现

最优最差多准则决策方法(BWMCDM)Python实现

文章目录

  • I.理论基础
    • 1.离散MCDM问题描述
    • 2.BWM
    • 3.一致性计算
    • 4.参考
  • II.Python源码
  • III.测试

I.理论基础

1.离散MCDM问题描述

\\quad离散MCDM问题表达如下:
c1c2⋯cnA=a1a2⋮am(p11p12⋯p1np21p22⋯p2n⋮⋮⋱⋮pm1pm2⋯pmn)(1)\\begin{array}{l} \\begin{array}{llll} \\qquad&&c_{1} & \\ c_{2} & \\ \\cdots & \\ c_{n} \\end{array} \\\\ A = \\begin{array}{c} a_{1} \\\\ a_{2} \\\\ \\vdots \\\\ a_{m} \\end{array}\\left(\\begin{array}{cccc} p_{11} & p_{12} & \\cdots & p_{1 n} \\\\ p_{21} & p_{22} & \\cdots & p_{2 n} \\\\ \\vdots & \\vdots & \\ddots & \\vdots \\\\ p_{m 1} & p_{m 2} & \\cdots & p_{m n} \\end{array}\\right) \\\\ \\end{array} \\tag{1} c1 c2  cnA=a1a2amp11p21pm1p12p22pm2p1np2npmn(1)

其中,{a1,a2,…,am}\\left\\{a_1,a_2,\\ldots,a_m\\right\\}{a1,a2,,am}为一组可行替代方案,{c1,c2,…,cn}\\left\\{c_1,c_2,\\ldots,c_n\\right\\}{c1,c2,,cn}为一组决策准则pijp_{ij}pij为替代方案iii在准则jjj上的得分。

\\quad目标是选择最佳(例如,最持久、最重要)的替代方案,即选择具有最高总体价值的替代方案。

\\quad若为每个准则分配权重wj,(wj≥0,∑wj=1),j=1,2,…,nw_j,\\left(w_j \\geq 0, \\sum w_j=1\\right),j=1,2,\\ldots,nwj,(wj0,wj=1),j=1,2,,n,则可行方案iii的加权价值函数为:
Vi=∑j=1nwjpij(2)V_i = \\sum_{j=1}^n w_j p_{ij} \\tag{2} Vi=j=1nwjpij(2)

2.BWM

\\quad假设有n个评价准则,并使用1/91/91/9999对这些准则进行成对比较,从而得分判断矩阵AAA
A=(a11a12…a1na21a22…a2n⋮⋮⋱⋮an1an2…ann)(3)A = \\left(\\begin {array}{c} a_{11} & a_{12} & \\ldots & a_{1n} \\\\ a_{21} & a_{22} & \\ldots & a_{2n} \\\\ \\vdots & \\vdots & \\ddots & \\vdots \\\\ a_{n1} & a_{n2} & \\ldots & a_{nn} \\\\ \\end{array}\\right) \\tag{3} A=a11a21an1a12a22an2a1na2nann(3)

其中,aija_{ij}aij表示准则iii相对于准则jjj的相对偏好,aij=1a_{ij}=1aij=1表示两者同等重要,aij≥1a_{ij}\\ge 1aij1表示准则iii比准则jjj更加重要,aij=9a_{ij}=9aij=9表示绝对重要。满足aji=1aij,aii=1a_{ji}=\\frac{1}{a_{ij}},a_{ii}=1aji=aij1,aii=1

为了获得完整的判断矩阵AAA需要进行n(n−1)/2n\\left(n-1\\right)/2n(n1)/2次成对比较。若满足以下条件,则认为判断矩阵AAA是完全一致的:
aik×akj=aij,∀i,j(4)a_{ik}\\times a_{kj} = a_{ij}, \\forall i,j \\tag{4} aik×akj=aij,i,j(4)

将成对比较分为两类:(1)参考比较(Reference Comparisons)和(2)二次比较(Secondary Comparisons)

定义1 如果iii是最佳要素和/或jjj最差要素,则aija_{ij}aij表示一个参考比较。

定义2 如果iiijjj都不是最佳或最差要素,且aij≥1a_{ij}\\geq 1aij1,则aija_{ij}aij为一个二次比较。

实施步骤
S1.确定决策准则集

\\quad采用准则C={c1,c2,…,cn}C=\\{c_1,c_2,\\ldots,c_n\\}C={c1,c2,,cn}作为决策准则

S2.确定最佳(如,最重要)和最差(如,最不重要)准则

\\quad由决策者从整体上确定最佳和最差的准则

S3.使用1-9得分确定最佳准则相对所有准则的偏好值(Best-to-Others向量)
AB=(aB1,aB2,…,aBn)A_B = \\left(a_{B1},a_{B2},\\ldots,a_{Bn}\\right) AB=(aB1,aB2,,aBn)
其中,aBja_{Bj}aBj表示最佳准则BBB相对于准则jjj的偏好,显然,aBB=1a_{BB}=1aBB=1

S4.使用1-9得分确定最差准则相对所有准则的偏好值
AW=(a1W,a2W,…,anW)A_W = \\left(a_{1W},a_{2W},\\ldots,a_{nW}\\right) AW=(a1W,a2W,,anW)
其中,ajWa_{jW}ajW表示准则jjj相对于最佳准则WWW的偏好,显然,aWW=1a_{WW}=1aWW=1

S5.找到最优权重(w1∗,w2∗,…,wn∗)\\left(w_{1}^*,w_{2}^*,\\ldots,w_{n}^*\\right)(w1,w2,,wn)

对于每一对wB/wjw_B/w_jwB/wjwj/wWw_j/w_Wwj/wW,有wB/wj=aBjw_B/w_j = a_{Bj}wB/wj=aBjwj/wW=ajWw_j/w_W = a_{jW}wj/wW=ajW。为了对所有jjj都满足以上条件,需要找到一个对所有jjj的最大绝对差∣wBwj−aBj∣\\left|\\frac{w_B}{w_j}-a_{Bj}\\right|wjwBaBj∣wjwW−ajW∣\\left|\\frac{w_j}{w_W}-a_{jW}\\right|wWwjajW最小。考虑到权重的非负性和和约束,有:
min⁡max⁡j{∣wBwj−aBj∣,∣wjwW−ajW∣}s.t.∑jwj=1wj≥0,∀j(5)\\begin{array}{l} \\min \\max_{j}\\left\\{\\left|\\frac{w_B}{w_j}-a_{Bj}\\right|,\\left|\\frac{w_j}{w_W}-a_{jW}\\right|\\right\\} \\\\ s.t. \\\\ \\sum_{j} w_j = 1 \\\\ w_j \\geq 0, \\forall j \\\\ \\end{array} \\tag{5} minmaxj{wjwBaBj,wWwjajW}s.t.jwj=1wj0,j(5)

可将上述问题(5)转化为以下问题:
min⁡ξs.t.∣wBwj−aBj∣≤ξ,∀j∣wjwW−ajW∣≤ξ,∀j∑jwj=1wj≥0,∀j(6)\\begin{array}{l} \\min \\xi \\\\ s.t. \\\\ \\left|\\frac{w_B}{w_j}-a_{Bj}\\right| \\leq \\xi, \\forall j \\\\ \\left|\\frac{w_j}{w_W}-a_{jW}\\right| \\leq \\xi, \\forall j \\\\ \\sum_{j} w_{j} = 1 \\\\ w_j \\geq 0, \\forall j \\\\ \\end{array} \\tag{6} minξs.t.wjwBaBjξ,jwWwjajWξ,jjwj=1wj0,j(6)

求解问题(6),即可得到最优权重(w1∗,w2∗,…,wn∗)\\left(w_{1}^*,w_{2}^*,\\ldots,w_{n}^*\\right)(w1,w2,,wn)ξ∗\\xi^*ξ

3.一致性计算

\\quadaBj×ajW=aBWa_{Bj} \\times a_{jW} = a_{BW}aBj×ajW=aBW对所有j都满足,则该比较是一致的。

\\quad不一致:
(aBj−ξ)×(ajW−ξ)=(aBW+ξ)(7)\\left(a_{Bj}-\\xi\\right) \\times \\left(a_{jW}-\\xi\\right) = \\left(a_{BW}+\\xi\\right) \\tag{7} (aBjξ)×(ajWξ)=(aBW+ξ)(7)

为了得到最小一致性aBj=ajW=aBWa_{Bj}=a_{jW}=a_{BW}aBj=ajW=aBW,有:
(aBj−ξ)×(ajW−ξ)=(aBW+ξ)⇒ξ2−(1+2aBW)ξ+(aBW2−aBW)=0(8)\\left(a_{Bj}-\\xi\\right) \\times \\left(a_{jW}-\\xi\\right) = \\left(a_{BW}+\\xi\\right) \\Rightarrow \\xi^2 - \\left(1+2a_{BW}\\right)\\xi + \\left({a_{BW}}^2 - a_{BW}\\right)=0 \\\\ \\tag{8} (aBjξ)×(ajWξ)=(aBW+ξ)ξ2(1+2aBW)ξ+(aBW2aBW)=0(8)

为了求解aBW∈{1,2,…,9}a_{BW}\\in\\left\\{1,2,\\ldots,9\\right\\}aBW{1,2,,9},可以寻找最大可能ξ\\xiξmax⁡ξ\\max \\ximaxξ)。使用这些最大值作为一致性指标,然后使用ξ∗\\xi^*ξ和对应的一致性指标计算一致率:
CR=ξ∗CICR = \\frac{\\xi^*}{CI} CR=CIξ

4.参考

  1. Rezaei, J. Best-worst multi-criteria decision-making method. Omega, 2015, 53, 49-57.

II.Python源码

import numpy as np
import math
import random
import os## 灰狼优化求解算法# Function
def target_function():return# Function: Initialize Variables
def initial_position(pack_size = 5, min_values = [-5,-5], max_values = [5,5], target_function = target_function):position = np.zeros((pack_size, len(min_values)+1))for i in range(0, pack_size):for j in range(0, len(min_values)):position[i,j] = random.uniform(min_values[j], max_values[j])position[i,-1] = target_function(position[i,0:position.shape[1]-1])return position# Function: Initialize Alpha
def alpha_position(dimension = 2, target_function = target_function):alpha = np.zeros((1, dimension + 1))for j in range(0, dimension):alpha[0,j] = 0.0alpha[0,-1] = target_function(alpha[0,0:alpha.shape[1]-1])return alpha# Function: Initialize Beta
def beta_position(dimension = 2, target_function = target_function):beta = np.zeros((1, dimension + 1))for j in range(0, dimension):beta[0,j] = 0.0beta[0,-1] = target_function(beta[0,0:beta.shape[1]-1])return beta# Function: Initialize Delta
def delta_position(dimension = 2, target_function = target_function):delta =  np.zeros((1, dimension + 1))for j in range(0, dimension):delta[0,j] = 0.0delta[0,-1] = target_function(delta[0,0:delta.shape[1]-1])return delta# Function: Updtade Pack by Fitness
def update_pack(position, alpha, beta, delta):updated_position = np.copy(position)for i in range(0, position.shape[0]):if (updated_position[i,-1] < alpha[0,-1]):alpha[0,:] = np.copy(updated_position[i,:])if (updated_position[i,-1] > alpha[0,-1] and updated_position[i,-1] < beta[0,-1]):beta[0,:] = np.copy(updated_position[i,:])if (updated_position[i,-1] > alpha[0,-1] and updated_position[i,-1] > beta[0,-1]  and updated_position[i,-1] < delta[0,-1]):delta[0,:] = np.copy(updated_position[i,:])return alpha, beta, delta# Function: Updtade Position
def update_position(position, alpha, beta, delta, a_linear_component = 2, min_values = [-5,-5], max_values = [5,5], target_function = target_function):updated_position = np.copy(position)for i in range(0, updated_position.shape[0]):for j in range (0, len(min_values)):   r1_alpha              = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1)r2_alpha              = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1)a_alpha               = 2*a_linear_component*r1_alpha - a_linear_componentc_alpha               = 2*r2_alpha      distance_alpha        = abs(c_alpha*alpha[0,j] - position[i,j]) x1                    = alpha[0,j] - a_alpha*distance_alpha   r1_beta               = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1)r2_beta               = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1)a_beta                = 2*a_linear_component*r1_beta - a_linear_componentc_beta                = 2*r2_beta            distance_beta         = abs(c_beta*beta[0,j] - position[i,j]) x2                    = beta[0,j] - a_beta*distance_beta                          r1_delta              = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1)r2_delta              = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1)a_delta               = 2*a_linear_component*r1_delta - a_linear_componentc_delta               = 2*r2_delta            distance_delta        = abs(c_delta*delta[0,j] - position[i,j]) x3                    = delta[0,j] - a_delta*distance_delta                                 updated_position[i,j] = np.clip(((x1 + x2 + x3)/3),min_values[j],max_values[j])     updated_position[i,-1] = target_function(updated_position[i,0:updated_position.shape[1]-1])return updated_position# GWO Function
def grey_wolf_optimizer(pack_size = 5, min_values = [-5,-5], max_values = [5,5], iterations = 50, target_function = target_function, verbose = True):    count    = 0alpha    = alpha_position(dimension = len(min_values), target_function = target_function)beta     = beta_position(dimension  = len(min_values), target_function = target_function)delta    = delta_position(dimension = len(min_values), target_function = target_function)position = initial_position(pack_size = pack_size, min_values = min_values, max_values = max_values, target_function = target_function)while (count <= iterations): if (verbose == True):    print('Iteration = ', count, ' f(x) = ', alpha[0][-1])      a_linear_component = 2 - count*(2/iterations)alpha, beta, delta = update_pack(position, alpha, beta, delta)position           = update_position(position, alpha, beta, delta, a_linear_component = a_linear_component, min_values = min_values, max_values = max_values, target_function = target_function)    count              = count + 1          return alpha# BWM
def BWM(dataset, mic, lic, size = 50, iterations = 150):X         = np.copy(dataset)/1.0best      = np.where(mic == 1)[0][0] #获得最优指标值为1的索引worst     = np.where(lic == 1)[0][0] #获得最差准则只为1的索引# 建立Best-to-Others向量pairs_b   = [(best, i)  for i in range(0, mic.shape[0])]# 建立Others-to-Worst向量pairs_w   = [(i, worst) for i in range(0, mic.shape[0]) if (i, worst) not in pairs_b]# 建立优化目标函数def target_function(variables):eps       = [float('+inf')]for pair in pairs_b: #与最佳准则比较i, j = pairdiff = abs(variables[i] - variables[j]*mic[j]) #计算|a_Bj-w_b/w_j|if ( i != j):eps.append(diff)for pair in pairs_w: #与最差准则比较i, j = pairdiff = abs(variables[i] - variables[j]*lic[j])if ( i != j):eps.append(diff)if ( np.sum(variables) == 0):eps = float('+inf')else:eps = max(eps[1:])return eps# 采用灰狼优化算法寻找最优权重weights = grey_wolf_optimizer(pack_size = size, min_values = [0.01]*X.shape[1], max_values = [1]*X.shape[1], iterations = iterations, target_function = target_function)# 权重归一化weights = weights[0][:-1]/sum(weights[0][:-1])return weights

III.测试

# 数据集
dataset = np.array([# g1   g2   g3   g4[250,  16,  12,  5],[200,  16,  8 ,  3],   [300,  32,  16,  4],[275,  32,  8 ,  4],[225,  16,  16,  2]])
# 最优准则
mic = np.array([1, 3, 4, 7])
# 最差准则
lic = np.array([7, 5, 5, 1])
# 采用BWM计算最优权重
weights =  BWM(dataset, mic, lic, size = 50, iterations = 150)
# 输出各个指标的最优权重
for i in range(0, weights.shape[0]):print('w(g'+str(i+1)+'): ', round(weights[i], 3))

输出结果:

Iteration =  0  f(x) =  inf
Iteration =  1  f(x) =  0.8225123652041643
Iteration =  2  f(x) =  0.26978730095302067
Iteration =  3  f(x) =  0.11575769796201554
Iteration =  4  f(x) =  0.11575769796201554
Iteration =  5  f(x) =  0.07244990479832858
Iteration =  6  f(x) =  0.07244990479832858
Iteration =  7  f(x) =  0.07244990479832858
Iteration =  8  f(x) =  0.07244990479832858
Iteration =  9  f(x) =  0.07244990479832858
Iteration =  10  f(x) =  0.07244990479832858
Iteration =  11  f(x) =  0.07244990479832858
Iteration =  12  f(x) =  0.0627512470203439
Iteration =  13  f(x) =  0.0627512470203439
Iteration =  14  f(x) =  0.0627512470203439
Iteration =  15  f(x) =  0.0627512470203439
Iteration =  16  f(x) =  0.0627512470203439
Iteration =  17  f(x) =  0.0627512470203439
Iteration =  18  f(x) =  0.0627512470203439
Iteration =  19  f(x) =  0.0627512470203439
Iteration =  20  f(x) =  0.0613258458509815
Iteration =  21  f(x) =  0.0416184489289983
Iteration =  22  f(x) =  0.0416184489289983
Iteration =  23  f(x) =  0.0416184489289983
Iteration =  24  f(x) =  0.04043851330583073
Iteration =  25  f(x) =  0.04043851330583073
Iteration =  26  f(x) =  0.03839692794308719
Iteration =  27  f(x) =  0.03839692794308719
Iteration =  28  f(x) =  0.03839692794308719
Iteration =  29  f(x) =  0.03839692794308719
Iteration =  30  f(x) =  0.03839692794308719
Iteration =  31  f(x) =  0.03839692794308719
Iteration =  32  f(x) =  0.03362197238350268
Iteration =  33  f(x) =  0.03362197238350268
Iteration =  34  f(x) =  0.027563216968690428
Iteration =  35  f(x) =  0.027563216968690428
Iteration =  36  f(x) =  0.027563216968690428
Iteration =  37  f(x) =  0.027563216968690428
Iteration =  38  f(x) =  0.027563216968690428
Iteration =  39  f(x) =  0.027563216968690428
Iteration =  40  f(x) =  0.02521773272774567
Iteration =  41  f(x) =  0.02521773272774567
Iteration =  42  f(x) =  0.02521773272774567
Iteration =  43  f(x) =  0.02521773272774567
Iteration =  44  f(x) =  0.02521773272774567
Iteration =  45  f(x) =  0.02521773272774567
Iteration =  46  f(x) =  0.02521773272774567
Iteration =  47  f(x) =  0.02521773272774567
Iteration =  48  f(x) =  0.02521773272774567
Iteration =  49  f(x) =  0.021877679478816078
Iteration =  50  f(x) =  0.021877679478816078
Iteration =  51  f(x) =  0.021877679478816078
Iteration =  52  f(x) =  0.017349379506246702
Iteration =  53  f(x) =  0.017349379506246702
Iteration =  54  f(x) =  0.017349379506246702
Iteration =  55  f(x) =  0.017349379506246702
Iteration =  56  f(x) =  0.016814330101299044
Iteration =  57  f(x) =  0.016814330101299044
Iteration =  58  f(x) =  0.016814330101299044
Iteration =  59  f(x) =  0.016814330101299044
Iteration =  60  f(x) =  0.016814330101299044
Iteration =  61  f(x) =  0.016814330101299044
Iteration =  62  f(x) =  0.01664986899457347
Iteration =  63  f(x) =  0.012419697076621149
Iteration =  64  f(x) =  0.012419697076621149
Iteration =  65  f(x) =  0.012419697076621149
Iteration =  66  f(x) =  0.012419697076621149
Iteration =  67  f(x) =  0.012419697076621149
Iteration =  68  f(x) =  0.012419697076621149
Iteration =  69  f(x) =  0.012419697076621149
Iteration =  70  f(x) =  0.01200555185181644
Iteration =  71  f(x) =  0.011952061481401982
Iteration =  72  f(x) =  0.011952061481401982
Iteration =  73  f(x) =  0.011952061481401982
Iteration =  74  f(x) =  0.008761657912284386
Iteration =  75  f(x) =  0.008761657912284386
Iteration =  76  f(x) =  0.008761657912284386
Iteration =  77  f(x) =  0.008761657912284386
Iteration =  78  f(x) =  0.008761657912284386
Iteration =  79  f(x) =  0.008419538595294263
Iteration =  80  f(x) =  0.008419538595294263
Iteration =  81  f(x) =  0.008419538595294263
Iteration =  82  f(x) =  0.008419538595294263
Iteration =  83  f(x) =  0.008419538595294263
Iteration =  84  f(x) =  0.008419538595294263
Iteration =  85  f(x) =  0.008419538595294263
Iteration =  86  f(x) =  0.008419538595294263
Iteration =  87  f(x) =  0.008419538595294263
Iteration =  88  f(x) =  0.008419538595294263
Iteration =  89  f(x) =  0.008419538595294263
Iteration =  90  f(x) =  0.008419538595294263
Iteration =  91  f(x) =  0.008419538595294263
Iteration =  92  f(x) =  0.008419538595294263
Iteration =  93  f(x) =  0.008419538595294263
Iteration =  94  f(x) =  0.008419538595294263
Iteration =  95  f(x) =  0.008419538595294263
Iteration =  96  f(x) =  0.008419538595294263
Iteration =  97  f(x) =  0.008419538595294263
Iteration =  98  f(x) =  0.008419538595294263
Iteration =  99  f(x) =  0.008419538595294263
Iteration =  100  f(x) =  0.008419538595294263
Iteration =  101  f(x) =  0.008419538595294263
Iteration =  102  f(x) =  0.008419538595294263
Iteration =  103  f(x) =  0.008419538595294263
Iteration =  104  f(x) =  0.008419538595294263
Iteration =  105  f(x) =  0.008419538595294263
Iteration =  106  f(x) =  0.008175882927208215
Iteration =  107  f(x) =  0.008175882927208215
Iteration =  108  f(x) =  0.008175882927208215
Iteration =  109  f(x) =  0.008175882927208215
Iteration =  110  f(x) =  0.008175882927208215
Iteration =  111  f(x) =  0.008175882927208215
Iteration =  112  f(x) =  0.008175882927208215
Iteration =  113  f(x) =  0.008175882927208215
Iteration =  114  f(x) =  0.008175882927208215
Iteration =  115  f(x) =  0.008175882927208215
Iteration =  116  f(x) =  0.008175882927208215
Iteration =  117  f(x) =  0.008175882927208215
Iteration =  118  f(x) =  0.008175882927208215
Iteration =  119  f(x) =  0.008175882927208215
Iteration =  120  f(x) =  0.008175882927208215
Iteration =  121  f(x) =  0.008175882927208215
Iteration =  122  f(x) =  0.008175882927208215
Iteration =  123  f(x) =  0.008175882927208215
Iteration =  124  f(x) =  0.008175882927208215
Iteration =  125  f(x) =  0.00809499667967843
Iteration =  126  f(x) =  0.00809499667967843
Iteration =  127  f(x) =  0.00809499667967843
Iteration =  128  f(x) =  0.00809499667967843
Iteration =  129  f(x) =  0.00809499667967843
Iteration =  130  f(x) =  0.00809499667967843
Iteration =  131  f(x) =  0.00809499667967843
Iteration =  132  f(x) =  0.00808352974904726
Iteration =  133  f(x) =  0.00808352974904726
Iteration =  134  f(x) =  0.00808352974904726
Iteration =  135  f(x) =  0.00808352974904726
Iteration =  136  f(x) =  0.00808352974904726
Iteration =  137  f(x) =  0.00808352974904726
Iteration =  138  f(x) =  0.00808352974904726
Iteration =  139  f(x) =  0.00808352974904726
Iteration =  140  f(x) =  0.00808352974904726
Iteration =  141  f(x) =  0.00808352974904726
Iteration =  142  f(x) =  0.00808352974904726
Iteration =  143  f(x) =  0.00808352974904726
Iteration =  144  f(x) =  0.008060349193135287
Iteration =  145  f(x) =  0.008060349193135287
Iteration =  146  f(x) =  0.008060349193135287
Iteration =  147  f(x) =  0.008060349193135287
Iteration =  148  f(x) =  0.008019470478954472
Iteration =  149  f(x) =  0.008019470478954472
Iteration =  150  f(x) =  0.008004493940747618
w(g1):  0.578
w(g2):  0.168
w(g3):  0.162
w(g4):  0.093

篮球游戏