Search code examples
pythonlinear-programmingpulpminimization

PuLP : What am I wrong in Objective Function?


I created objective function and found the error in syntax of Excess below.

*Excess = (inv[m]+order[m]for m in material) - sum(produce[i]usage[i][m]for m in material for i in product)

The Excess cost = (Inventory + Quantity order) - Total quantity used

Constraint Material Quantity used I would like to fix that quantity of material is used for production will not exceed total inventory what we have plus total quantity that we order more.

So Material Quantity used <= Total Inventory + Total order

Can anyone suggest for my missing ?

product = ['S1', 'S2']

material = ['A', 'B', 'C', 'D', 'E', 'F', 'I', 'G', 'H', 'J', 'K', 'L', 'M']
inv_bf = 40000

product_cost = {'S1': 4.28, 'S2': 4.28,}

usage = {'S1': {'A': 12.24,
                'D': 12.24,
                'E': 0.014,
                'F': 0.095,
                'G': 12.24,
                'H': 0.589,
                'J': 24.24,
                'K': 0.005,
                'L': 0.0105},
         'S2': {'A': 12.24,
                'D': 12.24,
                'E': 0.014,
                'F': 0.095,
                'G': 12.24,
                'H': 0.589,
                'J': 24.24,
                'K': 0.005,
                'L': 0.0105}}

inv = {'A': 7645.8, 'B': 2470, 'C': 4526,
       'D': 6678, 'J': 4180.92, 'G': 6879,
       'E': 159.5, 'F': 717.4, 'I': 764.1,
       'H': 1302.69, 'K': 248.79, 'L': 235,
       'M': 179.4}

cost = {'A': 0.03, 'B': 0.03, 'C': 0.056,
        'D': 0.151, 'J': 0.024, 'G': 0.88,
        'E': 5.156, 'F': 13.04, 'I': 11.09,
        'H': 6.833, 'K': 11.261, 'L': 10.118,
        'M': 11.914}'''

# Define variables
# How many unit will produce ?
produce = LpVariable.dicts("produce", product, lowBound=0, cat='Integer')

# How many quantity of material to order more ?
order = LpVariable.dicts("order", material, lowBound=0, cat='Integer')

# Define and initialize model
model = LpProblem("total_cost", LpMinimize)

# Objective Function

Total_ProCost = lpSum(product_cost[i]*produce[i] for i in product)
Total_MatCost = lpSum(order[m]*cost[m] for m in material)
Excess = lpSum(inv[m]+order[m]for m in material) - \
         lpSum(produce[i]*usage[i][m]for m in material for i in product if m in usage[i].keys())

objective = Total_ProCost + Total_MatCost + lpSum(Excess*cost[m]for m in material)
model.setObjective(objective)

# Define Constraints

# Material Quantity used
for i in product:
    model += lpSum(produce[i]*usage[i][m]for m in material for i in product if m in usage[i].keys()) <= lpSum(inv[m] +\
              order[m] for m in material)

Solution

  • Where you are creating the expression for Excess cost you have a parenthetical without sum or more likely lpSum in front of it. So it is then a python generator without an expression in front of it, so that is causing your problem.

    Also, in your follow-on expression, you are multiplying Excess cost * cost[] which seems very odd. Either you have the math wrong or the variable names are goofy because cost squared is probably nonsensical.

    EDIT:

    Try this. I think this is what you want. You need lpSum in front of your summations in order to construct the math model. And in your Excess statement you were not checking if usage had the material in it, so that was generating key errors as you were summing over all materials, even though some are not in usage. I put a conditional into the correct summation...

    # Objective Function
    
    Total_ProCost = lpSum(product_cost[i]*produce[i] for i in product)
    Total_MatCost = lpSum(order[m]*cost[m] for m in material)
    Excess = lpSum(inv[m]+order[m]for m in material) - \
             lpSum(produce[i]*usage[i][m]for m in material for i in product if m in usage[i].keys())
    
    objective = Total_ProCost + Total_MatCost + lpSum(Excess*cost[m]for m in material)
    
    model.setObjective(objective)