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
我正在尝试解决线性优化问题。 我有 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