Warm tip: This article is reproduced from serverfault.com, please click

optimization-R OMPR软件包

(optimization - R OMPR package)

发布于 2020-12-17 18:11:10

我正在使用该ompr软件包来创建和解决整数编程问题。为简单起见,我将以NFL足球奇幻球员为例。

我想最大化两场比赛的得分,同时每场比赛每个位置只玩一位玩家。(为简单起见,这里假设任何玩家都可以担任任何位置。)

我遇到的问题是25个可能的玩家,我想将两场比赛中选择的玩家总数限制为15。i添加的ompr变量组成部分代表玩家指数,但我不确定如何添加限制i选择的总唯一性的约束

任何帮助将不胜感激!

n_players = 25
n_positions = 11
n_games = 2

# Points each player will score at each position per game
points_game1 = matrix(runif(25*11), nrow = 25, ncol = 11)
points_game2 = matrix(runif(25*11), nrow = 25, ncol = 11)
points_array <- array(c(points_game1, points_game2), dim = c(n_players, n_positions, 2))

mip <- ompr::MIPModel() %>% 
  
  # Initialize player/position set of binary options
  ompr::add_variable(x[i, j, k], i = 1:n_players, j = 1:n_positions, k = 1:n_games, type = 'binary') %>%
  
  # Every player/game can only be 0 or 1 across all positions
  ompr::add_constraint(sum_expr(x[i, j, k], j = 1:n_positions) <= 1, i = 1:n_players, k = 1:n_games) %>% 
  
  # Every position/game has to be exactly 1 across all players
  ompr::add_constraint(sum_expr(x[i, j, k], i = 1:n_players) == 1, j = 1:n_positions, k = 1:2) %>%
  
  # ****** Limit to 15 players total ??? ****
  
  # Objective is to maximize points
  ompr::set_objective(sum_expr(x[i, j, k] * points_array[i, j, k], i = 1:n_players, j = 1:n_positions, k = 1:n_players), 'max') %>% 

  # Solve model
  ompr::solve_model(with_ROI(solver = 'symphony', verbosity = -2))

Questioner
Sam
Viewed
0
cookesd 2020-12-18 03:01:59

你可以添加一组跨玩家索引的二进制变量,以跟踪是否在任何游戏的任何职位中使用了玩家。然后,你可以将这些变量的总和限制为极限(15)。这样一来,即使在两个游戏中都使用过一个玩家,你也只能计算一次。然后,你可以添加一个较大的M约束,如果在任何游戏的任何位置使用了玩家,则将新的二进制变量强制为1,但如果不使用该玩家,则将变量设为0。由于我们有两个游戏,并且每个游戏者中每个玩家最多只能位于1个位置,因此我们可以将所有玩家的大M设置为2

ompr::add_variable(is_used[i], i = 1:n_players, type = 'binary') %>%
ompr::add_constraint(sum_expr(is_used[i],i = 1:n_players) <= 15) %>%
# big M constraint ensuring that is_used is 1 if a player is used
ompr::add_constraint(2*is_used[i] >= sum_expr(x[i,j,k],j = 1:n_positions, k = 1:2), i = 1:n_players) %>%