徐泽水《不确定多属性决策方法与应用》78页
## 3.1 基于理想点的多属性决策方法---徐泽水《不确定多属性决策方法与应用》78页 --3.1.2 实例分析
library(data.table)
library(dplyr)
A = c(0.37,1800,2,19,90,
0.58,2800,5,28,105,
0.52,3500,5,32,130,
0.43,1900,3,27,98)
A= matrix(A,nrow = 4,ncol = 5,byrow = T) %>% data.table()
A # 原始决策矩阵
#> V1 V2 V3 V4 V5
#> 1: 0.37 1800 2 19 90
#> 2: 0.58 2800 5 28 105
#> 3: 0.52 3500 5 32 130
#> 4: 0.43 1900 3 27 98
####################################################### ##############################
################## 正理想点偏差 ----- 且 决策者不能提供任何权重信息 ###############
####################################################### ##############################
#### 第一步把原始决策矩阵A 利用适当的方法进行规范化为R,R为归一化后的矩阵
### norm_matrix()函数,根据书中收益型属性(按公式1.2)与成本型属性(按公式1.4)分别进行归一化
norm_matrix = function(A,shouyi=NULL,chengben=NULL){
if(is.matrix(A))A = data.table(A)
stopifnot(!is.null(shouyi) | !is.null(chengben))
m = ncol(A)
if(is.null(chengben)) chengben =setdiff(1L:m,shouyi)
if(is.null(shouyi)) shouyi = setdiff(1:m,chengben)
stopifnot(length(intersect(shouyi,chengben))==0,setequal(union(shouyi,chengben),1:m))
if( length(chengben) == 0 ){
# 对决策矩阵进行重命名
names(A)=paste0('V',1:m)
shouyi = paste0("V",shouyi)
R = A
# 归一化
R[,':='(c(shouyi),lapply(.SD, function(x)x/max(x))),.SDcols =shouyi] # 收益型属性归一化 (书中1.2式)
}else if( length(shouyi) == 0 ){
#对决策矩阵进行重命名
names(A)=paste0('V',1:m)
chengben = paste0("V",chengben)
R = A
# 归一化
R[,':='(c(chengben),lapply(.SD,function(x)min(x)/x)),.SDcols = chengben]# 成本型属性归一化 (书中1.3式)
}else{
#对决策矩阵进行重命名
names(A)=paste0('V',1:m)
shouyi = paste0("V",shouyi)
chengben = paste0("V",chengben)
R = A
# 归一化
R[,':='(c(shouyi),lapply(.SD, function(x)x/max(x))),.SDcols =shouyi] # 收益型属性归一化 (书中1.2式)
R[,':='(c(chengben),lapply(.SD,function(x)min(x)/x)),.SDcols = chengben]# 成本型属性归一化 (书中1.3式)
}
R = as.data.frame(R)
return(R)
}
R = norm_matrix(A,shouyi = c(1:5))
R
#> V1 V2 V3 V4 V5
#> 1 0.6379310 0.5142857 0.4 0.59375 0.6923077
#> 2 1.0000000 0.8000000 1.0 0.87500 0.8076923
#> 3 0.8965517 1.0000000 1.0 1.00000 1.0000000
#> 4 0.7413793 0.5428571 0.6 0.84375 0.7538462
#### 第二步 最小化方案与正理想点之间的偏差,得出属性权重向量
M_position = function(R){ # 输入归一化后的决策矩阵。
m = ncol(R)
n = nrow(R)
# ## 程序 1
temp = apply(R, 2, FUN = function(x)1/(n-sum(x)) )
w = temp/sum(temp)
return(w)
# ## 程序 2
# w = rep(0,m)
# s = 0
# for(j in 1:m){
# s = s + 1/(n - sum(R[,j]))
# }
# for(j in 1:m){
# w[j] = (1/(n - sum(R[,j])))/s
# }
# return(w)
}
w = M_position(R)
w
#> V1 V2 V3 V4 V5
#> 0.2282300 0.1446113 0.1652700 0.2403928 0.2214959
#### 第三步 计算出的权重向量,带入目标函数,并对目标函数值升序排序,排序结果,即为方案的优劣结果
f_obj = apply(R, 1, function(x){ sum( (1-x)*w*w ) })
round(f_obj,4) # 按升序排列,则最优结果为: x3 > x2 > x4 > x1
#> [1] 0.0840 0.0208 0.0054 0.0551
####################################################### ##############################
################## 负(或正)理想点偏差 ----- 且 决策者提供权重信息 ##########
###################### (本质求解线性规划问题) 书中77页M3.3 和 M-3.6###############################
####################################################### ##############################
######## 方法一: 正理想点偏差
# 第一步: 归一化决策矩阵
# 第二步: 得出属性权重向量
# M_position_tigong_w 输入决策矩阵(为规范化后的决策矩阵),以及提供权重信息,以向量形式给出
# 该函数输入结果为: 得出属性权重向量
M_position_tigong_w = function(R,lower_c,upper_c){
library(Rglpk)
n = nrow(R)
m = ncol(R)
obj = n - c(apply(R, 2, sum)) # 设置目标函数
mat = matrix(rep(1,m),nrow = 1) # 约束条件,权和向量为1
dir = c("==")
rhs = c(1)
types = c("C")
bounds <- list(lower = list(ind = 1L:m, val = lower_c),
upper = list(ind = 1L:m, val = upper_c))
return(Rglpk_solve_LP(obj, mat, dir, rhs, bounds, types)$solution)
}
w = M_position_tigong_w(R,lower_c = c(0.15,0.13,0.15,0.20,0.20),
upper_c = c(0.25,0.15,0.20,0.25,0.23))
w
#> [1] 0.25 0.13 0.15 0.25 0.22
round(w,2)
#> [1] 0.25 0.13 0.15 0.25 0.22
#### 第三步: 把计算出的权重向量,带入目标函数,并对目标函数值升序排序,排序结果,即为方案的优劣结果
apply(R, 1, function(x) sum( (1-x)*w ) )
#> [1] 0.41291491 0.09955769 0.02586207 0.27730009
apply(R, 1, function(x) sum( (1-x)*w ) ) %>% rank %>% order()# 按升序排列,则最优结果为: x3 > x2 > x4 > x1
#> [1] 3 2 4 1
######## 方法二: 负理想点偏差
# 第一步: 归一化决策矩阵
# 第二步: 得出属性权重向量
# M_negative_w 输入决策矩阵(为规范化后的决策矩阵),以及提供权重信息,以向量形式给出
# 该函数输入结果为: 得出属性权重向量
M_negative_w = function(R,lower_c,upper_c){
library(Rglpk)
n = nrow(R)
m = ncol(R)
obj = c(apply(R, 2, sum)) # 设置目标函数
mat = matrix(rep(1,m),nrow = 1) # 约束条件,权和向量为1
dir = c("==")
rhs = c(1)
types = c("C")
bounds <- list(lower = list(ind = 1L:m, val = lower_c),
upper = list(ind = 1L:m, val = upper_c))
return(Rglpk_solve_LP(obj, mat, dir, rhs, bounds, types,max =TRUE )$solution)
}
w = M_position_tigong_w(R,lower_c = c(0.15,0.13,0.15,0.20,0.20),
upper_c = c(0.25,0.15,0.20,0.25,0.23))
w
#> [1] 0.25 0.13 0.15 0.25 0.22
round(w,2)
#> [1] 0.25 0.13 0.15 0.25 0.22
#### 第三步: 把计算出的权重向量,带入目标函数,并对目标函数值升序排序,排序结果,即为方案的优劣结果
apply(R, 1, function(x) sum( (1-x)*w ) )
#> [1] 0.41291491 0.09955769 0.02586207 0.27730009
apply(R, 1, function(x) sum( (1-x)*w ) ) %>% rank %>% order()# 按升序排列,则最优结果为: x3 > x2 > x4 > x1
#> [1] 3 2 4 1