如何在R中的ompr线性规划约束中添加约束,以便每个人只能担任1个角色?

问题描述

我正在尝试向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  

我正在尝试使用MIPmodel根据每个人的喜好将其分配给一个角色(越大越好)。每个角色最多可以有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",0)
teamData$greet <- if_else(teamData$jobType == "Greeter",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

我现在的主要问题是我无法弄清楚如何添加约束,这样每个人在解决方案中只能扮演一个角色(即每个人只能是厨师,服务员或问候者)>

任何指针将不胜感激。

解决方法

这是一个典型的 assignment 问题,其中您将人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

乘以preference[p,j]

后,您的目标函数也将落入适当位置

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...