如何在 R 中为 ompr 线性规划约束添加约束,以便每个人只能担任 1 个角色?
How do I add a constraint to ompr linear programming constraint in R so that each person can only be put in 1 role?
我正在尝试向 R 中的混合整数规划模型添加约束,以便每个人只分配给一个角色。
我有一个如下所示的数据框:
ID Name Role PreferenceScore
----- ------- --------- ------------------
1 Abby Chef 10
1 Abby Waiter 8
1 Abby Greeter 9
2 Bob Chef 7
2 Bob Waiter 8
2 Bob Greeter 3
3 Carly Chef 5
3 Carly Waiter 8
3 Carly Greeter 4
... ... ... ...
20 David Chef 2
20 David Waiter 3
20 David Greeter 8
我正在尝试使用 MIP 模型根据每个人的偏好(数字越大越好)为每个人分配一个角色。每个角色最多8人,一共20人
这是我目前的情况:
library(dplyr)
library(ompr)
library(ompr.roi)
library(ROI)
library(ROI.plugin.glpk)
teamData <- read.csv("filename")
teamData$wait <- if_else(teamData$jobType == "Waiter", 1, 0)
teamData$chef <- if_else(teamData$jobType == "Chef", 1, 0)
teamData$greet <- if_else(teamData$jobType == "Greeter", 1, 0)
p <- nrow(teamData)
v <- as.numeric(teamData$PreferenceScore)
maxTeamSize <- 8
role <- teamData$Role
chef_job <- teamData$chef
waiter_job <- teamData$wait
greeter_job <- teamData$greet
name <- teamData$Name
# Build the model
model <- MIPModel() %>%
add_variable(x[i], i=1:p, type = "binary") %>%
set_objective(sum_expr(x[i] * v[i], i=1:p)) %>%
add_constraint(sum_expr(chef_job[i], i=1:p) <= 8) %>%
add_constraint(sum_expr(waiter_job[i], i=1:p) <= 8) %>%
add_constraint(sum_expr(greeter_job[i], i=1:p) <= 8) # %>%
# add_constraint(sum_expr(count(name[i])) == 1)
solved <- solve_model(model, with_ROI("glpk"))
result <- solved %>%
get_solution(x[i]) %>%
select(i) %>%
rowwise() %>%
mutate(Pref = v[i], Role = role[i], teamData$Name[i]) %>%
ungroup
result
我现在的主要问题是我不知道如何添加约束,以便每个人在解决方案中只能扮演一个角色(即每个人只能是厨师、服务员或迎宾员)
任何指点将不胜感激。
这是一个典型的分配问题,您要将人员 p
分配给工作 j
。因此,您需要 更新您的公式 以获得双索引决策变量 x[p, j]
。然后事情会开始变得更有意义...... :).
然后您可以对所有工作求和,以确保每个人的任务不超过一项(在伪代码中...我的 R 语法很糟糕):
sum (x[p, j] for j in Jobs) <=1 for p in Persons
并且如果每个职位最多有 spots[j]
人填补,则可以确保没有职位过满:
sum (x[p, j] for p in People) <= spots[j] for j in Jobs
并且您的 objective 函数将通过乘以 preference[p, j]
类似地落到位
我正在尝试向 R 中的混合整数规划模型添加约束,以便每个人只分配给一个角色。
我有一个如下所示的数据框:
ID Name Role PreferenceScore
----- ------- --------- ------------------
1 Abby Chef 10
1 Abby Waiter 8
1 Abby Greeter 9
2 Bob Chef 7
2 Bob Waiter 8
2 Bob Greeter 3
3 Carly Chef 5
3 Carly Waiter 8
3 Carly Greeter 4
... ... ... ...
20 David Chef 2
20 David Waiter 3
20 David Greeter 8
我正在尝试使用 MIP 模型根据每个人的偏好(数字越大越好)为每个人分配一个角色。每个角色最多8人,一共20人
这是我目前的情况:
library(dplyr)
library(ompr)
library(ompr.roi)
library(ROI)
library(ROI.plugin.glpk)
teamData <- read.csv("filename")
teamData$wait <- if_else(teamData$jobType == "Waiter", 1, 0)
teamData$chef <- if_else(teamData$jobType == "Chef", 1, 0)
teamData$greet <- if_else(teamData$jobType == "Greeter", 1, 0)
p <- nrow(teamData)
v <- as.numeric(teamData$PreferenceScore)
maxTeamSize <- 8
role <- teamData$Role
chef_job <- teamData$chef
waiter_job <- teamData$wait
greeter_job <- teamData$greet
name <- teamData$Name
# Build the model
model <- MIPModel() %>%
add_variable(x[i], i=1:p, type = "binary") %>%
set_objective(sum_expr(x[i] * v[i], i=1:p)) %>%
add_constraint(sum_expr(chef_job[i], i=1:p) <= 8) %>%
add_constraint(sum_expr(waiter_job[i], i=1:p) <= 8) %>%
add_constraint(sum_expr(greeter_job[i], i=1:p) <= 8) # %>%
# add_constraint(sum_expr(count(name[i])) == 1)
solved <- solve_model(model, with_ROI("glpk"))
result <- solved %>%
get_solution(x[i]) %>%
select(i) %>%
rowwise() %>%
mutate(Pref = v[i], Role = role[i], teamData$Name[i]) %>%
ungroup
result
我现在的主要问题是我不知道如何添加约束,以便每个人在解决方案中只能扮演一个角色(即每个人只能是厨师、服务员或迎宾员)
任何指点将不胜感激。
这是一个典型的分配问题,您要将人员 p
分配给工作 j
。因此,您需要 更新您的公式 以获得双索引决策变量 x[p, j]
。然后事情会开始变得更有意义...... :).
然后您可以对所有工作求和,以确保每个人的任务不超过一项(在伪代码中...我的 R 语法很糟糕):
sum (x[p, j] for j in Jobs) <=1 for p in Persons
并且如果每个职位最多有 spots[j]
人填补,则可以确保没有职位过满:
sum (x[p, j] for p in People) <= spots[j] for j in Jobs
并且您的 objective 函数将通过乘以 preference[p, j]