0

I try to make minimize cost model by PuLP many times and still have the error. I would like to make decision for 2 variables below. produce = How many unit will produce for each product ? order = How many qty. will order more for each material item ?

from pulp import *

product = ['S1', 'S2', 'S3', 'S4']
material = ['A', 'B', 'C', 'D', 'E', 'F', 'I', 'G', 'H', 'J', 'K', 'L', 'M']
margin = {'S1': 25.68, 'S2': 25.68,
          'S3': 25.68, 'S4': 25.68}
capacity = 300
inv_bf = 42753.63
product_cost = {'S1': 4.28, 'S2': 4.28,
                'S3': 4.28, 'S4': 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},
         'S3': {'H': 0.26,
                'K': 0.014,
                'B': 12.24,
                'C': 12.24,
                'I': 0.624,
                'G': 12.18,
                'J': 24.24,
                'M': 0.005},
         'S4': {'H': 0.26,
                'K': 0.014,
                'B': 12.24,
                'C': 12.24,
                'I': 0.624,
                'G': 12.18,
                'J': 24.24,
                'M': 0.005}}

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
produce = LpVariable.dicts("produce", product, lowBound=0, cat='Integer')
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)

# 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)

# Capacity limited
for i in product:
    model += lpSum(produce[i]) <= capacity

# Profit
for i in product:
    model += lpSum(produce[i]*margin[i]) >= Total_ProCost + Total_MatCost

# Reduce inv cost
for i in product:
    model += lpSum(inv[m]+order[m] - produce[i]*usage[i][m] for m in material for i in product if m in usage[i].keys()) <= inv_bf

model.solve()

#Output

for v in model.variables():
    print(v.name,'=',v.varValue)

produce = [v.varValue for v in model.variables()]

I found the result show 0 to order all material and produce 4 products. That is impossible and strange . because Actually we need to use material in dict usage to produce for each product. Example is we can produce S1 when we have material enough for all items . It means that need to use A,D,E,F,G,H,J,K and L.

order_A = 0.0
order_B = 0.0
order_C = 0.0
order_D = 0.0
order_E = 0.0
order_F = 0.0
order_G = 0.0
order_H = 0.0
order_I = 0.0
order_J = 0.0
order_K = 0.0
order_L = 0.0
order_M = 0.0
produce_S1 = 97.11436
produce_S2 = 97.11436
produce_S3 = 97.11436
produce_S4 = 291.34308
Total cost =  2493.887783819344

Please advise the way to fix my constraints or other ways to do. Thanks in advance.

Kudadas
  • 3
  • 2

1 Answers1

0

You've got several problems here...

  • First, it is likely "producing" from the inventory you have, without need to order more

  • in several constraints, you are making redundant constraints when your for i in product and then sum over the same set inside the constraint

  • if you are making a minimization model, what will motivate the model to produce anything at all? Where is the demand?

  • you probably need to look again at order and inv. As you are doing it now, there is no sense of where the order or inventory is used, so you could be using the same inventory to build 5 different things...

AirSquid
  • 10,214
  • 2
  • 7
  • 31
  • The objective of my model is using current inventory (excess at factory) to produce more product with ordering little quantity for some material what might have inventory as 0 or small inventory to reduce the excess inventory cost (inv_bf) and in total still need to minimize total cost (production cost + ordering material cost + excess cost after allocated). Could you please suggest the way to correct it or the easier formulation ? – Kudadas Oct 13 '21 at 15:01
  • Why don't you start with a couple of *much* simpler models and get something working. I'd suggest (1) forget about cost and see how many **total items** you can produce from stock on hand (no ordering, no cost/profits). (2) Maximize the **profit** for production from materials on hand. If you can get those working, which will take a bit of work, you'll be in better shape to build this. – AirSquid Oct 13 '21 at 16:34
  • Got it for your suggestion and will try to do as your comment. But I still have the problem and question that how to calculate usage of all compents for each product with produce quantity. It seems like the way I formulate not calculate for all. Please suggest for this problem. – Kudadas Oct 13 '21 at 17:27
  • You will need to flip around your quantity constraint and make it *for each material* instead of product. And then sum across all products and make it <= amount of material `m` – AirSquid Oct 13 '21 at 19:15
  • So I revise as this. Is It correct ?for m in material: 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) – Kudadas Oct 14 '21 at 14:53
  • you should remove the summation of the material set for the RHS of the inequality so that you have ?for m in material: model += lpSum(produce[i]*usage[i][m]for m in material for i in product if m in usage[i].keys()) \ <= inv[m] + order[m] Always check if you have uncontrolled, or in this case, doubled controlled sets. with this change your 'reduce inventory' constraint makes the model infeasible since the sum of the inventory is 35986.6 which is less than 42753.63, you should reconsider this constraint and what you want to do with it, for a feasible model you can remove this constraint – Billal Naseem Oct 15 '21 at 10:31