Search code examples
pythonpulp

Evaluating expressions in pulp


I have developed a LP problem and this works. However, when I print out total_transfers it just gives me an expression like "buy10__Aarons,_M + buy10__Adams,_C + buy10__Adrian + buy10__Ait_Nouri,_R + buy10__Ajer,_K +...." whereas I thought it should be a number. How can this be printed out as a number? I really want to put this into my objective function as a panalty value but unable to do this

# Define constriant for starting team i.e first week (week 4) 
for player in players:
    fpl_problem += lineup[0][player] == starting_team[player] + tran_in[0][player] - tran_out[0][player]
    fpl_problem += tran_in[0][player] + tran_out[0][player] <= 1    
    fpl_problem += cpt[0][player]  <= lineup[0][player] 
# Define constriants for teams for rest of the weeks (week 5 and 6. The code is generic and automatically scales for additional weeks)

for week in range(0,len(weeks)-1):
  for player in players:
    fpl_problem += lineup[week+1][player] == lineup[week][player] + tran_in[week+1][player] - tran_out[week+1][player]
    fpl_problem += tran_in[week+1][player] + tran_out[week+1][player] <= 1
    fpl_problem += cpt[week+1][player]  <= lineup[week+1][player] 
    
for week in range(0,len(weeks)):
  fpl_problem += sum(tran_in[week][player] for player in players) <=11          # trade in players should be <= 11 per week
  fpl_problem += sum(lineup[week][player] for player in players) == n_players   # Lineup size should be equal to maximum players per week
  fpl_problem += sum(cpt[week][player] for player in players) == 1              # There should be only 1 captain per week
  fpl_problem += sum([player_cost[player] * lineup[week][player] for player in players]) <= float(max_budget)     # Total cost constriant per week
  total_transfers = total_transfers + sum(tran_in[week][player] for player in players)
fpl_problem += total_transfers <= transfers_left

Solution

  • You are correct on all things stated. :). total_transfers is an expression. You do realize that you are building out this expression with your loop, right? You could also have done so outside of the loop by using a comprehension for the weeks... either way works.

    So you can:

    • print the expression (what you got.)
    • evaluate the expression (what you are trying to do)
    • Use the expression arbitrarily in either constraints or the OBJ. (what you are trying to do also.)

    Sometimes it isn't clear in pulp how to get at the methods and attributes without a little tinkering, but the missing thing to evaluate here is the value() method. See the example below and comment back if you are stuck.

    # pulp expression example
    
    from pulp import *
    
    prob = LpProblem('example', LpMinimize)
    
    x1 = LpVariable('x1')
    x2 = LpVariable('x2')
    
    z = x1 + x2
    
    print(f'z is a : {type(z)}')
    print(f'z evaluates to: {z}')  # <-- what you are seeing now
    print(f'the value of the expression z is: {z.value()}')
    
    # some goofy constraints...
    
    prob += x1 >= 1
    prob += x2 >= 3
    prob += z >= 6     # the expression z is legal in a constraint
    
    # the objective
    prob += z + x1     # the expression z is legal in the OBJ
    
    prob.solve()
    
    print(f'the value of z after solve is now: {z.value()}')
    
    for v in prob.variables():
        print(f'the value of {v.name} is: {v.value()}')
    

    Yields:

    z is a : <class 'pulp.pulp.LpAffineExpression'>
    z evaluates to: x1 + x2
    the value of the expression z is: None
    
    ... solve data ...
    
    the value of z after solve is now: 6.0
    the value of x1 is: 1.0
    the value of x2 is: 5.0