R中的模拟/优化包,用于调整权重以实现组的最大分配

时间:2018-06-13 17:26:02

标签: r optimization simulation mathematical-optimization simulator

我希望识别R中的模拟包以识别完美的权重,这样我就可以将数据点分配到最大存储桶中。

基本上,我想以这样的方式调整我的体重以实现我的目标。

以下是示例。

  Score1,Score2,Score3,Final,Group
0.87,0.73,0.41,0.63,"60-100"
0.82,0.73,0.85,0.796,"70-80"
0.82,0.37,0.85,0.652,"60-65"
0.58,0.95,0.42,0.664,"60-65"
1,1,0.9,0.96,"90-100"

Weight1,Weight2,Weight3
0.2,0.4,0.4

Final Score= Score1*Weight1+ Score2*Weight2+Score3*Weight3

我的权重之和为1. W1 + W2 + W3 = 1

我想调整我的重量,以便我的大部分情况都在“90-100”桶中。我知道不会有完美的组合,但想要抓住最大的案例。我目前正在尝试使用Pivot手动执行相同的excel,但想知道R中是否有任何包,这有助于我实现我的目标。

小组分配“70-80”“80-90”是我在excel中所做的,使用if else条件。

R Pivot结果:

"60-100",1
"60-65",2
"70-80",1
"90-100",1

如果有人可以帮我这样做,我将不胜感激。

谢谢,

2 个答案:

答案 0 :(得分:1)

这是一种尝试使用嵌套优化方法将所有最终得分尽可能接近0.9的方法。

这是您的原始数据:

# Original data
df <- read.table(text = "Score1, Score2, Score3 
0.87,0.73,0.41 
0.82,0.73,0.85 
0.82,0.37,0.85 
0.58,0.95,0.42 
1,1,0.9", header = TRUE, sep = ",")

这是第一个重量的成本函数。

# Outer cost function
cost_outer <- function(w1){
  # Run nested optimisation
  res <- optimise(cost_nested, lower = 0, upper = 1 - w1, w1 = w1)

  # Spit second weight into a global variable
  res_outer <<- res$minimum

  # Return the cost function value
  res$objective
}

这是第二个重量的成本函数。

# Nested cost function
cost_nested <- function(w2, w1){
  # Calculate final weight
  w <- c(w1, w2, 1 - w2 -w1)

  # Distance from desired interval
  res <- 0.9 - rowSums(w*df) 

  # Zero if negative distance, square distance otherwise
  res <- sum(ifelse(res < 0, 0, res^2))
}

接下来,我运行优化。

# Repackage weights
weight <- c(optimise(cost_outer, lower = 0, upper = 1)$minimum, res_outer)
weight <- c(weight, 1 - sum(weight)) 

最后,我展示了结果。

# Final scores
cbind(df, Final = rowSums(weight * df))


#   Score1 Score2 Score3     Final
# 1   0.87   0.73   0.41 0.7615286
# 2   0.82   0.73   0.85 0.8229626
# 3   0.82   0.37   0.85 0.8267400
# 4   0.58   0.95   0.42 0.8666164
# 5   1.00   1.00   0.90 0.9225343

但请注意,此代码会将最终得分尽可能接近到该时间间隔,这与在该时间间隔内获得最多得分不同。这可以通过以下方式切换嵌套成本函数来实现:

# Nested cost function
cost_nested <- function(w2, w1){
  # Calculate final weight
  w <- c(w1, w2, 1 - w2 -w1)

  # Number of instances in desired interval
  res <- sum(rowSums(w*df) < 0.9)
}

答案 1 :(得分:1)

这可以表示为混合整数编程(MIP)问题。数学模型看起来像:

enter image description here

二进制变量δ i 表示最终权重F i 是否在区间[0.9,1]内。 M是“大”值(如果您的所有数据都在0和1之间,我们可以选择M=1)。 a i,j 是您的数据。

目标函数和所有约束都是线性的,因此我们可以使用标准的MIP求解器来解决这个问题。 R的MIP求解器随时可用。

示例组中的PS重叠。这对我来说没有多大意义。我想如果我们有“90-100”,我们也不应该有“60-100”。

PS2。如果所有数据都在0和1之间,我们可以稍微简化夹层方程:我们可以放弃正确的部分。

对于小示例数据集,我得到:

----     56 PARAMETER a  

            j1          j2          j3

i1       0.870       0.730       0.410
i2       0.820       0.730       0.850
i3       0.820       0.370       0.850
i4       0.580       0.950       0.420
i5       1.000       1.000       0.900


----     56 VARIABLE w.L  weights

j1 0.135,    j2 0.865


----     56 VARIABLE f.L  final scores

i1 0.749,    i2 0.742,    i3 0.431,    i4 0.900,    i5 1.000


----     56 VARIABLE delta.L  selected

i4 1.000,    i5 1.000


----     56 VARIABLE z.L                   =        2.000  objective

(不打印零)