I am trying to solve the supplier diversification problem by minimizing the costs. I basically have a list of pricing for an item from different suppliers. The suppliers are willing to give me some discounts if I order in large quantities. I am trying to solve this problem in Python using CPLEX.
However, I do not know how to write the objective function of this problem. So, for example, I have these pricings
price_list=[{(0, 5): 5, (5, 10): 4},
{(0, 5): 6, (5, 10): 5, (10, 15): 4, (15, 20): 3},
{(0, 2): 3, (2, 3): 2},
{(0, 2): 4, (2, 3): 3, (3, 4): 2}]
whereby if I order from the first supplier 3 items, the unit price of these items is 5. But if I buy 7 items, the unit price becomes 4.
My demand is large enough that I need to buy from different suppliers to meet it.
I am very new to this, can anyone please help?
I did try to write a function that checks to which pricing range the demanded quantity belongs. I wanted the code to be something like this:
def get_cost(ordered_quantity,supplier_index):
for i in price_list[supplier_index]: #loop through the price range of the given supplier
if ordered_quantity>=i[0] and ordered_quantity<=i[1]: # check if the demand quantity is within this range
return price_list[supplier_index][i]*ordered_quantity # computer and return cost of demand
But this can;t work because the demand quantity is a variable in my model and I can't figure out how to get its value to compute the objective function when the model is executing.
You should use piecewise linear function. See example https://github.com/AlexFleischerParis/zoodocplex/blob/master/zoopiecewise.py
from docplex.mp.model import Model
mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
#after 4 buses, additional buses of a given size are cheaper
f=mdl.piecewise(0, [(0, 0),(4,4)], 0.8)
mdl.minimize(f(nbbus40)*500 + f(nbbus30)*400)
mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
And with your values
price_list=[{(0, 5): 5, (5, 10): 4},
{(0, 5): 6, (5, 10): 5, (10, 15): 4, (15, 20): 3},
{(0, 2): 3, (2, 3): 2},
{(0, 2): 4, (2, 3): 3, (3, 4): 2}]
def get_cost(ordered_quantity,supplier_index):
for i in price_list[supplier_index]: #loop through the price range of the given supplier
if ordered_quantity>=i[0] and ordered_quantity<=i[1]: # check if the demand quantity is within this range
return price_list[supplier_index][i]*ordered_quantity # computer and return cost of demand
q=4
from docplex.mp.model import Model
mdl = Model(name='test')
q1 = mdl.integer_var(name='q1')
cost1 = mdl.integer_var(name='cost')
costfunction1=mdl.piecewise(0, [(0, 0),(4,20),(5,20),(10,40)], 1000000)
mdl.add(cost1==costfunction1(q1))
mdl.add(q1==q)
mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
print("cost=",get_cost(q,0))
which gives
q1 = 4.0
cost = 20.0
cost= 20