Creating every possible team combination — combinatorial optimization

时光总嘲笑我的痴心妄想 提交于 2019-12-06 09:46:38

问题


Apologies if the title is not an accurate description of what I'm doing.

I am trying to construct every possible hypothetical team for a fantasy sports competition. This means combining all available players, each of whom has characteristics like the team they are on, their position, and their salary, which limits how many can be on a single team. The trouble I am having is finding a memory efficient way to combine them all.

I made an example dataset:

 player_pool <- data.frame(id = seq(1,30), salary = seq(1,30), team = rep(LETTERS[seq(from=1, to=5)],6), position = rep(LETTERS[seq(from=1, to=5)],6))

Out of these 30 players I would like to choose every team of 8, with at least 1 player from all 5 roles, no more than 3 players from the same team, and a combined salary of less than 50.

For example, this would be a valid team:

 id salary team position
 1   1      A   A
 2   2      B   B
 3   3      C   C
 4   4      D   D
 5   5      E   E
 6   6      A   A
 7   7      B   B
 8   8      C   C

No more than two players from each team, at least 1 of each position, and at 36 total salary, under the cap.

I have been trying to implement a formula which goes through all ~6MM combinations step by step using the package iterpc, looking up and calculating salary/team numbers at each step. This lets me fit everything into memory at each step, but is incredibly slow and inefficient -- it amounts to creating every possible team and applying the rules in succession.

Any alternate approaches would be great!


回答1:


Setup Adding up the seven lowest-paid players, you get 28. This means that no one with a salary above 22 can be on the team.

pool <- subset(player_pool,salary<=22)

Finding combos From here, I would take the obvious route instead of looking for efficiency:

  1. Identify all combos of rows

    rs <- combn(seq(nrow(pool)),8)
    
  2. Test conditions

    good_rs <- with(pool,apply(rs,2,function(x){
      sum(salary[x]) <= 50 &&
      length(unique(position[x])) == 5 &&
      max(lengths(split(x,team[x]))) <= 3
    }))
    

Results It runs fast enough (under a second), and I see 339 matching combos

length(which(good_rs))
# [1] 339


来源:https://stackoverflow.com/questions/31572497/creating-every-possible-team-combination-combinatorial-optimization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!