R lpSolve设置约束(梦幻足球相关)

R lpSolve setting constraints (fantasy football related)

我正在尝试解决线性优化问题。 我有 100 名球员,每个球员都有得分和价格。我的目标是 select 11 名玩家并在不超出预算的情况下最大限度地提高得分(本例中为 83)。 下面的代码解决了这个任务。

library(data.table)
library(lpSolve)
set.seed(1)
# simulating data
data <- data.table(id = 1:100,
                   price = round(rnorm(100, 9, 2), 1),
                   score = round(rnorm(100, 150, 25)))
# objective which should be maximized
obj <- data$score

constraints <- matrix(
  c(data$price, 
    rep(1, 100)),
  byrow = TRUE, nrow = 2
)

constr_dir <- c("<=", "==")

rhs <- c(83, 11)

result <- lp("max", obj, constraints, constr_dir, rhs, all.bin = TRUE)

# joining result for easier observing
data$result <- result$solution
data[result != 0,]

问题来了。在我的团队中应该有一个得分会加倍的队长。如何修改我的代码以添加此条件? (请注意 lp 函数中的 all.bin 参数,也许这应该在最终解决方案中更改)。 所以这是当前结果:

    id price score coeff
 1:  6   7.4   194     1
 2: 10   8.4   192     1
 3: 13   7.8   186     1
 4: 14   4.6   134     1
 5: 24   5.0   146     1
 6: 35   6.2   158     1
 7: 60   8.7   197     1
 8: 66   9.4   205     1
 9: 71  10.0   208     1
10: 78   9.0   202     1
11: 97   6.4   186     1

我要实现的是10个系数应该等于1,一个等于2(结果可能与下面的不同,这是一个例子):

    id price score coeff
 1:  6   7.4   194     1
 2: 10   8.4   192     1
 3: 13   7.8   186     1
 4: 14   4.6   134     1
 5: 24   5.0   146     1
 6: 35   6.2   158     1
 7: 60   8.7   197     1
 8: 66   9.4   205     1
 9: 71  10.0   208     2
10: 78   9.0   202     1
11: 97   6.4   186     1

您可以 运行 100 个增广线性问题。在第 i 个问题中,你将第 i 个玩家的分数乘以 2。最后你选择得分最高的解决方案:

constraints <- matrix(c(data$price, rep(1, 100)), byrow = TRUE, nrow = 2)
constr_dir <- c("<=", "==")
rhs <- c(83, 11)

res <- vector("list", nrow(data))
for(i in seq_len(nrow(data))){
  
  cat("iter:", i, "\n")

  obj <- data$score
  obj[[i]] <- obj[[i]] * 2
  
  res[[i]] <- lp("max", obj, constraints, constr_dir, rhs, all.bin = TRUE)
}

captain_index <- which.max(unlist(lapply(res, function(x) x$objval)))
data[res[[captain_index]]$solution == 1,]

被选中的队长有索引captian_index