pythoncastinglinear-programmingpulpcoin-or-cbc

PuLP: casting LpVariable or LpAffineExpression to integer


In my optimization problem, I have a conditional that the amount of items (LpInteger) in a particular group may not exceed a percentage of the total amount of items. To do that, I wrote the following code:

total = lpSum([num[i].varValue for i in ind])
for d in length:
    # get list of items that satisfy the conditional
    items_length_d = list(compress(items,[work[i]==work_group[d] for i in items])) 
    # use that list to calculate the amount of items in the group (an item can occur multiple times) 
    amount[d] = lpSum([num[dl] for dl in items_length_d])
    max_d[d] = total*perc_max[d] + 1 
    min_d[d] = total*perc_min[d] - 1 
    prob += max_d[d] >= amount[d]
    prob += min_d[d] <= amount[d] 

The problem with this approach is that my maximum and minimum become floats (LpContinuous). This in turn makes the solution infeasible.

How can I make sure that each max_d and min_d values are integers? Preferably, I would also like to round up max_d, while truncating min_d.

Edit

I solved the problem of an infeasible solution by changing total = lpSum([num[i].varValue for i in ind]) to total = lpSum([num[i] for i in ind]). However, the minimum and maximum values are still floats. If someone knows how to convert these to ints, an answer would still be very appreciated.


Solution

  • You appear to misunderstand how constructing and solving an Linear Programming problem works.

    The entire problem should be set up, then solved and the solution values extracted.

    You can't get the LpVariable.varValue for a variable while setting up the problem.

    So for a fractional constraint if we define an the group as i /in G and then define the total as i /in T

    we get where f is the required fraction

    if rearrange this equation.

    so in your code

    prob += perc_max[d] * lpSum([num[i] for i in ind]) <= lpSum([num[dl] for dl in items_length_d])