Search code examples
pythonlinear-programmingcplexpulp

Print variable defined as dicts in PuLP


I am new to using PuLP in python and I would like to know how I can select a specific variable from my model to print and export to Excel.

I have been guided by some examples where they define the variables with indexes such as LpVariable.dicts, but when I open it in the console, the values for solving the problem do not appear. Only 0:LpVariable appears; 1:LpVariable...

This is how i defined it. x_var = LpVariable.dicts('x', (set_M, set_N), 0, 1, cat="Binary")

I tried variable.value and variable.varvalue but neither works.


Solution

  • You are going to be a lot happier if you go the 1 extra step of making the x-product sets (or lists) separately and handing them over to that construction. When you hand over the tuple of (set_M, set_N), pulp's indexing is a bit weird. Just make a separate index set for the cross product (where needed) using either a comprehension or one of the itertools methods.

    Also, you don't need to put the bounds in for Binary. It is implied.

    This leads to much easier indexing when you want to access the variables in the model:

    from pulp import *
    
    M = {1, 2, 3, 4}
    N = {'A', 'B', 'C', 'D'}
    
    # some example x-products.  Itertools could also be used, but comprehensions are a snap:
    MN = {(m, n) for m in M for n in N}
    MN_lite = {(m, n) for m in M for n in N if m < 3}
    
    
    prob = LpProblem('sample', LpMinimize)
    
    # VARS
    x = LpVariable.dicts('x', indices=MN, cat="Binary")
    y = LpVariable.dicts('y', indices=MN_lite, cat="Integer")
    z = LpVariable.dicts('z', indices=N)
    
    # sample print / access...  No value yet
    print(x[2, 'C'].varValue)  # <---- this is how you want to access them!
    
    
    # some silly constraints...
    
    for n in N:
        prob += lpSum(x[m, n] for m in M) >= 2  # must pick 2 for each n in N
    
    for n in N:
        prob += z[n] >= 4.2
    
    # objective:  Minimize picks
    
    prob += lpSum(x[m, n] for (m, n) in MN) + lpSum(z[n] for n in N)
    
    prob.solve()
    
    for m, n in sorted(MN):       # sorting, if desired
        print(f'for index {m}, {n} set: {x[m, n].varValue : 0.0f}')
    
    for n in N:
        print(n, z[n].varValue)   # simple
    

    Output (minus the solve data, which you should always check):

    for index 1, A set:  1
    for index 1, B set:  1
    for index 1, C set:  1
    for index 1, D set:  1
    for index 2, A set:  1
    for index 2, B set:  1
    for index 2, C set:  1
    for index 2, D set:  1
    for index 3, A set:  0
    for index 3, B set:  0
    for index 3, C set:  0
    for index 3, D set:  0
    for index 4, A set:  0
    for index 4, B set:  0
    for index 4, C set:  0
    for index 4, D set:  0
    C 4.2
    B 4.2
    A 4.2
    D 4.2