R OMPR 包 - 限制选择的唯一可变组件的数量
R OMPR package - Limiting the number of unique variable components chosen
我正在使用 ompr
包来创建和解决整数规划问题。为了简单起见,我将以 NFL 橄榄球梦幻球员为例。
我想最大化 2 场比赛的得分,同时每场比赛每个位置只让 1 名球员上场。 (为简单起见,这里假设任何球员都可以打任何位置。)
我遇到问题的部分是 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))
您可以添加一组跨球员索引的二进制变量,以跟踪球员是否在任何游戏的任何位置上使用。然后您可以将这些变量的总和限制在您的限制 (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) %>%
我正在使用 ompr
包来创建和解决整数规划问题。为了简单起见,我将以 NFL 橄榄球梦幻球员为例。
我想最大化 2 场比赛的得分,同时每场比赛每个位置只让 1 名球员上场。 (为简单起见,这里假设任何球员都可以打任何位置。)
我遇到问题的部分是 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))
您可以添加一组跨球员索引的二进制变量,以跟踪球员是否在任何游戏的任何位置上使用。然后您可以将这些变量的总和限制在您的限制 (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) %>%