简体   繁体   中英

Using Python Pulp for binary optimization for multi-day player selection

I am struggling with an integer optimization question using pulp. I am creating a fantasy sports team - where I need to select 11 players on each game day. [assume only 2 game days for simplicity]. The other constraint is that I cannot make more than 3 changes over the 2 days. In other words, 8 players need to be the same between the 2 days. The players I buy need to be within a budget of 100 credits.

I have 2 decision variables: ie the selected team for each of the 2 days.

    prob = LpProblem("Fantasy_Cricket", LpMaximize)
    player_names = list(squad.Player)
    player_gd1 = LpVariable.dicts("playerChosen1", player_names, 0, 1, cat='Integer')
    player_gd2 = LpVariable.dicts("playerChosen2", player_names, 0, 1, cat='Integer')

FYI: player_names refers to a list of all available players. The objective function is to maximize the predicted score over the 2 days (gd1 and gd2 refer to gameday 1 and game day 2). This is a function of the player selected * his 'Value' and whether his team is playing on a given day.

    prob += lpSum([player_gd1[p]*squad[squad.Player==p]['Value'].sum()*squad[squad.Player==p]['gd1'].sum() + player_gd2[p]*squad[squad.Player==p]['Value'].sum()*squad[squad.Player==p]['gd2'].sum() for p in player_names])

Constraints set are as follows:

    prob += lpSum([player_gd1[p]*squad[squad.Player==p]['Points'].sum() for p in player_names]) <=100
    prob += lpSum([player_gd2[p]*squad[squad.Player==p]['Points'].sum() for p in player_names]) <=100
    
    prob += lpSum([player_gd1[p] for p in player_names]) == 11
    prob += lpSum([player_gd2[p] for p in player_names]) == 11
    
    prob += lpSum([((player_gd1[p] + player_gd2[p]) ==2) for p in player_names]) >=8

The first 4 constraints are working fine. It is the 5th one that results in an 'infeasible' solution. Basically, I am enforcing a rule that at least 8 players are common across the 2 days.

prob.solve()
print("Status:", LpStatus[prob.status]) 

Status: Infeasible

I am new to Python and PuLP. Can anyone help? What am I missing?

Reiterating here that the first 4 constraints are working fine. It is the introduction of the 5th (which is a constraint on multi-day selection) that causes issues.

Thanks in advance.

Your last constraint:

prob += lpSum([((player_gd1[p] + player_gd2[p]) ==2) for p in player_names]) >=8

Is not a valid constraint in PuLP. I can see what you are trying to achieve, creating an intermediary binary variable ((player_gd1[p] + player_gd2[p]) ==2) which is then summed across the players. If you want to do it this way you would have to explicitly declare this binary variable and find a way of forcing it to take a true value if (and only if) that condition is satisfied.

For example you could create a new set of variables:

player_swapped = LpVariable.dicts("player_swapped", player_names, 0, 1, cat='Integer')

And then have a set of constaints as:

for p in player_names:
    player_swapped[p] >= player_gd1[p] - player_gd2[p]
    player_swapped[p] >= player_gd2[p] - player_gd1[p]

You can then set a constraint on how many players can be swapped between the games.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM