Thursday, 31 August 2017

Product Supply chain network design with uncertain demand

Logistics is the activity involving movement of a valuable transaction (product or empty!) from one location to another location. Need for such movement might arise from different factors depending upon the context. Movement can be used for various reasons such as meeting demand in distribution, movement of tenants, water for irrigation and drinking purposes among numerous other activities. There is a link that drives logistics and can be generically stated as movement of physical goods from point of supply to point of demand. Logistical activities involve movement of product and require resources that are capable of performing loading, transportation and unloading between consecutive supply and demand points, not necessarily in the same order always (empty movements). However, combination of successive supply and demand points forms a large chain of network commonly known as supply chain network from perspective of suppliers.
Supply chain management is the management of overall network for meeting customer demand of system for maximization of surplus. Supply chain surplus is the difference of revenue and costs of performing logistical, storage and production operations at various stages of the network. The management of supply chain can happen either at local or global level. Local supply chain management primarily deals with improving surplus of individual or subset of members while global supply chain management deals with improving overall network surplus. We put forth that logistical movement might comprise of loaded or empty movement in the network. The empty movement occurs when transport fleet returns back to supply location with vacant pallets. However, generally the fleets are managed by independent transportation providers and such empty movements are not part of network. The first and foremost factor is defining the system boundary for supply chain network. Such network would comprise of nodes and arcs in mathematical sense for analysis and decision making.
The article attempts to analyze product based supply chain comprising of bill of material (BOM) hierarchy in supply chain design for improving the supply chain surplus. Supply chain network comprises of regional cluster connected via ground transportation. Here, we have excluded other modes of transportation such as airfreight and sea freight to have a reasonable system boundary for decision making. To incorporate real world problems associated with inconsistent but predictive customer requirement the demand is stochastic.     

The problem deals with maximization of supply chain revenue and service level with novel fourfold dimensions focusing on BOM, uncertain demand and the movement of stock transfer order (STO) within the same echelon. Real life complexity is incorporated in the model with uncertain demand.


#Import pulp and pandas packages


from pulp import*
import pandas as pd

#Raw Input Data


# Input Data

scenarios = [1,2,3]
probs = [0.1,0.6,0.3]

nodes = ['S1','S2','M1','M2','D1','D2','R1','R2']
S = [['S1','RM1'],['S2','RM2']]
M = [['M1','P1'],['M1','P2'],['M2','P2']]
D = [['D1','P1'],['D1','P2'],['D2','P2']]
R = [['R1','P1'],['R1','P2'],['R2','P2']]
T = [1,2,3,4,5]
RM = ['RM1','RM2']
P = ['P1','P2']
BOM = [['P1','RM1',8],['P1','RM2',5],['P2','RM2',4]]
SL = [['R1', 'P1', 1, 0.95],
 ['R1', 'P1', 2, 0.95],
 ['R1', 'P1', 3, 0.95],
 ['R1', 'P1', 4, 0.95],
 ['R1', 'P1', 5, 0.95],
 ['R1', 'P2', 1, 0.90],
 ['R1', 'P2', 2, 0.90],
 ['R1', 'P2', 3, 0.90],
 ['R1', 'P2', 4, 0.90],
 ['R1', 'P2', 5, 0.90],
 ['R2', 'P2', 1, 0.85],
 ['R2', 'P2', 2, 0.85],
 ['R2', 'P2', 3, 0.85],
 ['R2', 'P2', 4, 0.85],
 ['R2', 'P2', 5, 0.85]]

# Selling Price

price = [['R1', 'P1', 1, 21000],
 ['R1', 'P1', 2, 21000],
 ['R1', 'P1', 3, 11000],
 ['R1', 'P1', 4, 22000],
 ['R1', 'P1', 5, 26000],
 ['R1', 'P2', 1, 19000],
 ['R1', 'P2', 2, 10000],
 ['R1', 'P2', 3, 11000],
 ['R1', 'P2', 4, 24000],
 ['R1', 'P2', 5, 13000],
 ['R2', 'P2', 1, 12000],
 ['R2', 'P2', 2, 28000],
 ['R2', 'P2', 3, 24000],
 ['R2', 'P2', 4, 14000],
 ['R2', 'P2', 5, 19000]]


# Transportation Cost

trans = [['S1', 'S2', 550],
 ['S1', 'M1', 610],
 ['S1', 'M2', 280],
 ['S1', 'D1', 520],
 ['S1', 'D2', 640],
 ['S1', 'R1', 80],
 ['S1', 'R2', 360],
 ['S2', 'S1', 210],
 ['S2', 'M1', 70],
 ['S2', 'M2', 540],
 ['S2', 'D1', 760],
 ['S2', 'D2', 100],
 ['S2', 'R1', 500],
 ['S2', 'R2', 530],
 ['M1', 'S1', 610],
 ['M1', 'S2', 660],
 ['M1', 'M2', 60],
 ['M1', 'D1', 360],
 ['M1', 'D2', 520],
 ['M1', 'R1', 510],
 ['M1', 'R2', 430],
 ['M2', 'S1', 580],
 ['M2', 'S2', 670],
 ['M2', 'M1', 380],
 ['M2', 'D1', 200],
 ['M2', 'D2', 740],
 ['M2', 'R1', 520],
 ['M2', 'R2', 60],
 ['D1', 'S1', 530],
 ['D1', 'S2', 120],
 ['D1', 'M1', 370],
 ['D1', 'M2', 490],
 ['D1', 'D2', 290],
 ['D1', 'R1', 430],
 ['D1', 'R2', 660],
 ['D2', 'S1', 200],
 ['D2', 'S2', 50],
 ['D2', 'M1', 130],
 ['D2', 'M2', 620],
 ['D2', 'D1', 260],
 ['D2', 'R1', 350],
 ['D2', 'R2', 140],
 ['R1', 'S1', 460],
 ['R1', 'S2', 590],
 ['R1', 'M1', 670],
 ['R1', 'M2', 770],
 ['R1', 'D1', 370],
 ['R1', 'D2', 280],
 ['R1', 'R2', 210],
 ['R2', 'S1', 480],
 ['R2', 'S2', 240],
 ['R2', 'M1', 400],
 ['R2', 'M2', 480],
 ['R2', 'D1', 380],
 ['R2', 'D2', 510],
 ['R2', 'R1', 730]]

# Raw material inventory holding cost at manufacturer

hcr = [['M1', 'RM1', 1, 20],
 ['M1', 'RM1', 2, 20],
 ['M1', 'RM1', 3, 20],
 ['M1', 'RM1', 4, 20],
 ['M1', 'RM1', 5, 20],
 ['M1', 'RM2', 1, 10],
 ['M1', 'RM2', 2, 10],
 ['M1', 'RM2', 3, 10],
 ['M1', 'RM2', 4, 10],
 ['M1', 'RM2', 5, 10],
 ['M2', 'RM2', 1, 10],
 ['M2', 'RM2', 2, 10],
 ['M2', 'RM2', 3, 10],
 ['M2', 'RM2', 4, 10],
 ['M2', 'RM2', 5, 10]]

# Product inventory holding cost at manufacturer

hcp = [['M1', 'P1', 1, 70],
 ['M1', 'P1', 2, 70],
 ['M1', 'P1', 3, 70],
 ['M1', 'P1', 4, 70],
 ['M1', 'P1', 5, 70],
 ['M1', 'P2', 1, 50],
 ['M1', 'P2', 2, 50],
 ['M1', 'P2', 3, 50],
 ['M1', 'P2', 4, 50],
 ['M1', 'P2', 5, 50],
 ['M2', 'P2', 1, 50],
 ['M2', 'P2', 2, 50],
 ['M2', 'P2', 3, 50],
 ['M2', 'P2', 4, 50],
 ['M2', 'P2', 5, 50]]   

# Product inventory holding cost at distributor

hcd = [['D1', 'P1', 1, 80],
 ['D1', 'P1', 2, 80],
 ['D1', 'P1', 3, 80],
 ['D1', 'P1', 4, 80],
 ['D1', 'P1', 5, 80],
 ['D1', 'P2', 1, 60],
 ['D1', 'P2', 2, 60],
 ['D1', 'P2', 3, 60],
 ['D1', 'P2', 4, 60],
 ['D1', 'P2', 5, 60],
 ['D2', 'P2', 1, 60],
 ['D2', 'P2', 2, 60],
 ['D2', 'P2', 3, 60],
 ['D2', 'P2', 4, 60],
 ['D2', 'P2', 5, 60]]

# Supplier Capacity

scap = [['S1', 'RM1', 20000], ['S2', 'RM2', 20000]]

# Manufacturer production capacity
    
mprcap = [['M1', 'P1', 3000], ['M1', 'P2', 7000], ['M2', 'P2', 4000]]

# Manufacturer product storage capacity

mscp = [['M1', 'P1', 1800], ['M1', 'P2', 1800], ['M2', 'P2', 1800]]

# Manufacturer raw material storage capacity

mscr = [['M1', 'RM1', 800], ['M1', 'RM2', 750], ['M2', 'RM2', 900]]

# Distributor product storage capacity

mscd = [['D1', 'P1', 2500], ['D1', 'P2', 2000], ['D2', 'P2', 2000]]

# Demand 

dem = [['R1','P1',400, 0.1,600, 0.6,800, 0.3],['R1','P2',300, 0.1,400, 0.6,500, 0.3],['R2','P2',200, 0.1,300, 0.6,400, 0.3]]

# Production Cost

prodcost = [['M1','P1',600],['M1','P2',480],['M2','P2',680]]

# Initial raw material inventory at manufacturer 

iimr = [['M1','RM1',40],['M1','RM2',100],['M2','RM2',80]]

# Initial product inventory at manufacturer

iimp = [['M1','P1',25],['M1','P2',50],['M2','P2',60]]

# Initial product inventory at distributor

iid = [['D1','P1',180],['D1','P2',350],['D2','P2',80]]

#Pre-processing of data


# Enumeration of Supplier to Manufacturer Flow List
smarc1 = []
for i,j in enumerate(S):
    for k,l in enumerate(M):
        for m,n in enumerate(BOM):
            if n[0] == l[1] and n[1] == j[1]:
                for t in T:
                    for s in scenarios:
                        smarc1.append([j[0],l[0],j[1],t,s])
                    
smarc = []
[smarc.append(item) for item in smarc1 if item not in smarc]

# Enumeration of Manufacturer to Distributor Flow List
mdarc1 = []
for i,j in enumerate(M):
    for k,l in enumerate(D):
        if j[1] == l[1]:
            for t in T:
                for s in scenarios:
                    mdarc1.append([j[0],l[0],j[1],t,s])
                
mdarc = []
[mdarc.append(item) for item in mdarc1 if item not in mdarc]

# Enumeration of Distributor to Retailer Flow List
drarc1 = []
for i,j in enumerate(D):
    for k,l in enumerate(R):
        if j[1] == l[1]:
            for t in T:
                for s in scenarios:
                    drarc1.append([j[0],l[0],j[1],t,s])
                
drarc = []
[drarc.append(item) for item in drarc1 if item not in drarc]

# Enumeration of Manufacturer Raw Material Stock Transfer Flow List
stmrarc1 = []
for i,j in enumerate(M):
    for k,l in enumerate(M):
        for m,n in enumerate(BOM):
            if j[0] != l[0] and n[0] == l[1] and n[0] == j[1]:
                for t in T:
                    for s in scenarios:
                        stmrarc1.append([j[0],l[0],n[1],t,s])
                    
stmrarc = []
[stmrarc.append(item) for item in stmrarc1 if item not in stmrarc]

# Enumeration of Manufacturer Product Stock Transfer Flow List
stmparc1 = []
for i,j in enumerate(M):
    for k,l in enumerate(M):
        if j[0] != l[0] and j[1] == l[1]:
            for t in T:
                for s in scenarios:
                    stmparc1.append([j[0],l[0],j[1],t,s])
                    
stmparc = []
[stmparc.append(item) for item in stmparc1 if item not in stmparc]

# Enumeration of Distributor Product Stock Transfer Flow List
stdarc1 = []
for i,j in enumerate(D):
    for k,l in enumerate(D):
        if j[0] != l[0] and j[1] == l[1]:
            for t in T:
                for s in scenarios:
                    stdarc1.append([j[0],l[0],j[1],t,s])
                    
stdarc = []
[stdarc.append(item) for item in stdarc1 if item not in stdarc]

# Enumeration of Raw Material Inventory at Manufacturer
imr1 = []
for i,j in enumerate(M):
    for k,l in enumerate(BOM):
        if j[1] == l[0]:
            for t in T:
                for s in scenarios:
                    imr1.append([j[0],l[1],t,s])
                
imr = []
[imr.append(item) for item in imr1 if item not in imr]

# Enumeration of Product Inventory at Manufacturer
imp1 = []
for i,j in enumerate(M):
    for t in T:
        for s in scenarios:
            imp1.append([j[0],j[1],t,s])
                
imp = []
[imp.append(item) for item in imp1 if item not in imp]

# Enumeration of Product Inventory at Distributor
ind1 = []
for i,j in enumerate(D):
    for t in T:
        for s in scenarios:
            ind1.append([j[0],j[1],t,s])
                
ind = []
[ind.append(item) for item in ind1 if item not in ind]

# Enumeration of supplier, raw material and time list

srt1 = []
for i,j in enumerate(S):
    for t in T:
        for s in scenarios:
            srt1.append([j[0],j[1],t,s])
        
srt = []
[srt.append(item) for item in srt1 if item not in srt]

# Enumeration of manufacturer, raw material, product and time list

mrpt1 = []
for i,j in enumerate(M):
    for k,l in enumerate(BOM):
        if j[1] == l[0]:
            for t in T:
                for s in scenarios:
                    mrpt1.append([j[0],l[1],j[1],t,s])
        
mrpt = []
[mrpt.append(item) for item in mrpt1 if item not in mrpt]

# Enumeration of retailer, product and time list

rpt1 = []
for i,j in enumerate(R):
        for t in T:
            for s in scenarios:
                rpt1.append([j[0],j[1],t,s])
        
rpt = []
[rpt.append(item) for item in rpt1 if item not in rpt]


# Converting the data list to dataframe

SL = pd.DataFrame(SL,columns=['Retailer','Product','Time','SL'])
SL = SL.set_index(['Retailer','Product','Time'])

price = pd.DataFrame(price,columns=['Retailer','Product','Time','Price'])
price = price.set_index(['Retailer','Product','Time'])

trans = pd.DataFrame(trans,columns=['From','To','TransCost'])
trans = trans.set_index(['From','To'])

hcr = pd.DataFrame(hcr,columns=['Manufacturer','RawMaterial','Time','InvCost'])
hcr = hcr.set_index(['Manufacturer','RawMaterial','Time'])

hcp = pd.DataFrame(hcp,columns=['Manufacturer','Product','Time','InvCost'])
hcp = hcp.set_index(['Manufacturer','Product','Time'])

hcd = pd.DataFrame(hcd,columns=['Distributor','Product','Time','InvCost'])
hcd = hcd.set_index(['Distributor','Product','Time'])

qty = pd.DataFrame(BOM,columns=['Product','RawMaterial','Quantity'])
qty = qty.set_index(['Product','RawMaterial'])

scap = pd.DataFrame(scap,columns=['Supplier','RawMaterial','Capacity'])
scap = scap.set_index(['Supplier','RawMaterial'])

mprcap = pd.DataFrame(mprcap,columns=['Manufacturer','Product','ProdCap'])
mprcap = mprcap.set_index(['Manufacturer','Product'])

mscp = pd.DataFrame(mscp,columns=['Manufacturer','Product','ProdStorCap'])
mscp = mscp.set_index(['Manufacturer','Product'])

mscr = pd.DataFrame(mscr,columns=['Manufacturer','RawMaterial','ProdRawCap'])
mscr = mscr.set_index(['Manufacturer','RawMaterial'])

mscd = pd.DataFrame(mscd,columns=['Distributor','Product','ProdStorCap'])
mscd = mscd.set_index(['Distributor','Product'])

dem = pd.DataFrame(dem,columns=['Retailer','Product','LowDemand','LowProb','MedDemand','MedProb','HighDemand','HighProb'])
dem = dem.set_index(['Retailer','Product'])

prodcost = pd.DataFrame(prodcost,columns=['Manufacturer','Product','ProdCost'])
prodcost = prodcost.set_index(['Manufacturer','Product'])

iimr = pd.DataFrame(iimr,columns=['Manufacturer','RawMaterial','Inventory'])
iimr = iimr.set_index(['Manufacturer','RawMaterial'])

iimp = pd.DataFrame(iimp,columns=['Manufacturer','Product','Inventory'])
iimp = iimp.set_index(['Manufacturer','Product'])

iid = pd.DataFrame(iid,columns=['Distributor','Product','Inventory'])
iid = iid.set_index(['Distributor','Product'])

#Product Supply Chain Network Design


x = LpVariable.dicts("Supp_to_Mfg_Flow_variable", ((i,j,r,t,s) for i,j,r,t,s in smarc),lowBound=0,cat='Integer')
y = LpVariable.dicts("Mfg_to_Distr_Flow_variable", ((j,k,p,t,s) for j,k,p,t,s in mdarc),lowBound=0,cat='Integer')
z = LpVariable.dicts("Distr_to_Retlr_Flow_variable", ((k,l,p,t,s) for k,l,p,t,s in drarc),lowBound=0,cat='Integer')

stmr = LpVariable.dicts("Stock_Transfer_Mfg_Rawm_Flow_variable", ((i,j,r,t,s) for i,j,r,t,s in stmrarc),lowBound=0,cat='Integer')
stmp = LpVariable.dicts("Stock_Transfer_Mfg_Prod_Flow_variable", ((i,j,p,t,s) for i,j,p,t,s in stmparc),lowBound=0,cat='Integer')
std = LpVariable.dicts("Stock_Transfer_Distr_Flow_variable", ((j,k,p,t,s) for j,k,p,t,s in stdarc),lowBound=0,cat='Integer')

imfgr = LpVariable.dicts("Inv_Mfg_Rawm_variable", ((j,r,t,s) for j,r,t,s in imr),lowBound=0,cat='Integer')
imfgp = LpVariable.dicts("Inv_Mfg_Prod_variable", ((j,p,t,s) for j,p,t,s in imp),lowBound=0,cat='Integer')
indr = LpVariable.dicts("Inv_Distr_Prod_variable", ((k,p,t,s) for k,p,t,s in ind),lowBound=0,cat='Integer')

rq = LpVariable.dicts("RawMtrl_Used_Mfg_variable", ((j,r,p,t,s) for j,r,p,t,s in mrpt),lowBound=0,cat='Integer')
pq = LpVariable.dicts("Product_Produced_Mfg_variable", ((j,p,t,s) for j,p,t,s in imp),lowBound=0,cat='Integer')

dsl = LpVariable.dicts("Demand_Slack_variable", ((l,p,t,s) for l,p,t,s in rpt),lowBound=0,cat='Integer')

model = LpProblem("Product Supply Chain Network Design",LpMaximize)

# Objective Function
model += lpSum([probs[int(s-1)] * price.loc[(l,p,t),'Price'] * z[k,l,p,t,s] for k,l,p,t,s in drarc]) - lpSum([probs[int(s-1)] * trans.loc[(i,j),'TransCost'] * x[i,j,r,t,s] for i,j,r,t,s in smarc]
                                                                                      + [probs[int(s-1)] * trans.loc[(j,k),'TransCost'] * y[j,k,p,t,s] for j,k,p,t,s in mdarc]
                                                                                      + [probs[int(s-1)] * trans.loc[(k,l),'TransCost'] * z[k,l,p,t,s] for k,l,p,t,s in drarc]
                                                                                      + [probs[int(s-1)] * trans.loc[(i,j),'TransCost'] * stmr[i,j,r,t,s] for i,j,r,t,s in stmrarc]
                                                                                      + [probs[int(s-1)] * trans.loc[(i,j),'TransCost'] * stmp[i,j,p,t,s] for i,j,p,t,s in stmparc]
                                                                                      + [probs[int(s-1)] * trans.loc[(j,k),'TransCost'] * std[j,k,p,t,s] for j,k,p,t,s in stdarc]
                                                                                      + [probs[int(s-1)] * hcr.loc[(j,r,t),'InvCost'] * imfgr[j,r,t,s] for j,r,t,s in imr]
                                                                                      + [probs[int(s-1)] * hcp.loc[(j,p,t),'InvCost'] * imfgp[j,p,t,s] for j,p,t,s in imp]
                                                                                      + [probs[int(s-1)] * hcd.loc[(k,p,t),'InvCost'] * indr[k,p,t,s] for k,p,t,s in ind]
                                                                                      + [probs[int(s-1)] * prodcost.loc[(j,p),'ProdCost'] * pq[j,p,t,s] for j,p,t,s in imp])


# supplier capacity constraint
for i,r,t,s in srt:
    model += lpSum([x[a,j,b,c,d] for a,j,b,c,d in x if a == i and b == r and c == t and d == s]) <= scap.loc[(i,r),'Capacity']

# BOM conversion constraint
for j,r,p,t,s in mrpt:
    model += rq[j,r,p,t,s] == qty.loc[(p,r),'Quantity'] * pq[j,p,t,s]
    
# manufacturer raw material balance constraint 
for j,r,t,s in imr:
    if t == 1:
        model += lpSum([stmr[i,a,b,c,d] for i,a,b,c,d in stmr if a == j and b == r and c == t and d == s] + [x[i,a,b,c,d] for i,a,b,c,d in x if a == j and b == r and c == t and d == s]) + iimr.loc[(j,r),'Inventory'] == imfgr[j,r,t,s] + lpSum([stmr[a,i,b,c,d] for a,i,b,c,d in stmr if a == j and b == r and c == t and d == s] + [rq[a,b,p,c,d] for a,b,p,c,d in rq if a == j and b == r and c == t and d == s]) 

for j,r,t,s in imr:
    if t > 1:
        model += lpSum([stmr[i,a,b,c,d] for i,a,b,c,d in stmr if a == j and b == r and c == t and d == s] + [x[i,a,b,c,d] for i,a,b,c,d in x if a == j and b == r and c == t and d == s]) + imfgr[j,r,int(t-1),s] == imfgr[j,r,t,s] + lpSum([stmr[a,i,b,c,d] for a,i,b,c,d in stmr if a == j and b == r and c == t and d == s] + [rq[a,b,p,c,d] for a,b,p,c,d in rq if a == j and b == r and c == t and d == s]) 

# manufacturer product balance constraint 
for j,p,t,s in imp:
    if t == 1:
        model += lpSum([stmp[i,a,b,c,d] for i,a,b,c,d in stmp if a == j and b == p and c == t and d == s]) + pq[j,p,t,s] + iimp.loc[(j,p),'Inventory'] == imfgp[j,p,t,s] + lpSum([stmp[a,i,b,c,d] for a,i,b,c,d in stmp if a == j and b == p and c == t and d == s] + [y[a,k,b,c,d] for a,k,b,c,d in y if a == j and b == p and c == t and d == s])

for j,p,t,s in imp:
    if t > 1:
        model += lpSum([stmp[i,a,b,c,d] for i,a,b,c,d in stmp if a == j and b == p and c == t and d == s]) + pq[j,p,t,s] + imfgp[j,p,int(t-1),s] == imfgp[j,p,t,s] + lpSum([stmp[a,i,b,c,d] for a,i,b,c,d in stmp if a == j and b == p and c == t and d == s] + [y[a,k,b,c,d] for a,k,b,c,d in y if a == j and b == p and c == t and d == s])

# manufacturer production capacity constraint
for j,p,t,s in imp:
    model += pq[j,p,t,s] <= mprcap.loc[(j,p),'ProdCap']
    
# manufacturer product storage capacity constraint
for j,p,t,s in imp:
    model += imfgp[j,p,t,s] <= mscp.loc[(j,p),'ProdStorCap']
    
# manufacturer raw material storage capacity constraint
for j,r,t,s in imr:
    model += imfgr[j,r,t,s] <= mscr.loc[(j,r),'ProdRawCap']
    
# distributor product balance constraint 
for k,p,t,s in ind:
    if t == 1:
        model += lpSum([std[i,a,b,c,d] for i,a,b,c,d in std if a == k and b == p and c == t and d == s]) + lpSum([y[j,a,b,c,d] for j,a,b,c,d in y if a == k and b == p and c == t and d == s]) + iid.loc[(k,p),'Inventory'] == indr[k,p,t,s] + lpSum([std[a,i,b,c,d] for a,i,b,c,d in std if a == k and b == p and c == t and d == s] + [z[a,l,b,c,d] for a,l,b,c,d in z if a == k and b == p and c == t and d == s])

for k,p,t,s in ind:
    if t > 1:
        model += lpSum([std[i,a,b,c,d] for i,a,b,c,d in std if a == k and b == p and c == t and d == s]) + lpSum([y[j,a,b,c,d] for j,a,b,c,d in y if a == k and b == p and c == t and d == s]) + indr[k,p,int(t-1),s] == indr[k,p,t,s] + lpSum([std[a,i,b,c,d] for a,i,b,c,d in std if a == k and b == p and c == t and d == s] + [z[a,l,b,c,d] for a,l,b,c,d in z if a == k and b == p and c == t and d == s])

# distributor product storage capacity constraint
for k,p,t,s in ind:
    model += indr[k,p,t,s] <= mscd.loc[(k,p),'ProdStorCap']
    
# demand balance constraint
for l,p,t,s in rpt:
    if s == 1:
        model += lpSum([z[k,a,b,c,d] for k,a,b,c,d in z if a == l and b == p and c == t and d == s]) + dsl[l,p,t,s] == dem.loc[(l,p),'LowDemand']  

for l,p,t,s in rpt:
    if s == 2:
        model += lpSum([z[k,a,b,c,d] for k,a,b,c,d in z if a == l and b == p and c == t and d == s]) + dsl[l,p,t,s] == dem.loc[(l,p),'MedDemand']  

for l,p,t,s in rpt:
    if s == 3:
        model += lpSum([z[k,a,b,c,d] for k,a,b,c,d in z if a == l and b == p and c == t and d == s]) + dsl[l,p,t,s] == dem.loc[(l,p),'HighDemand'] 

        
# demand service level constraint
for l,p,t,s in rpt:
    if s == 1:
        model += lpSum([z[k,a,b,c,d] for k,a,b,c,d in z if a == l and b == p and c == t and d == s]) >= dem.loc[(l,p),'LowDemand'] * SL.loc[(l,p,t),'SL'] 
        

for l,p,t,s in rpt:
    if s == 2:
        model += lpSum([z[k,a,b,c,d] for k,a,b,c,d in z if a == l and b == p and c == t and d == s]) >= dem.loc[(l,p),'MedDemand'] * SL.loc[(l,p,t),'SL']    
        

for l,p,t,s in rpt:
    if s == 3:
        model += lpSum([z[k,a,b,c,d] for k,a,b,c,d in z if a == l and b == p and c == t and d == s]) >= dem.loc[(l,p),'HighDemand'] * SL.loc[(l,p,t),'SL']    

#Solve the integer linear programming problem and get the solution


model.writeLP("ProductSCND.lp")
model.solve()
LpStatus[model.status]

# Print our objective function value (Total Revenue)
print (value(model.objective))

for i,j,r,t,s in x:
    if x[(i,j,r,t,s)].varValue > 0:
        v = (x[(i,j,r,t,s)].varValue)
        print ("Supplier %s to Manufacturer %s of raw material %s in period %s for scenario %s with quantity %s is moved!" % (i,j,r,t,s,v))

for j,k,p,t,s in y:
    if y[(j,k,p,t,s)].varValue > 0:
        v = (y[(j,k,p,t,s)].varValue)
        print ("Manufacturer %s to Distributor %s of end product %s in period %s for scenario %s with quantity %s is moved!" % (j,k,p,t,s,v))

for k,l,p,t,s in z:
    if z[(k,l,p,t,s)].varValue > 0:
        v = (z[(k,l,p,t,s)].varValue)
        print ("Distributor %s to Retailer %s of end product %s in period %s for scenario %s with quantity %s is moved!" % (k,l,p,t,s,v))

for j,r,p,t,s in rq:
    if rq[(j,r,p,t,s)].varValue > 0:
        v = (rq[(j,r,p,t,s)].varValue)
        print ("Manufacturer %s use Raw material %s to produce end product %s in period %s for scenario %s with quantity %s for production!" % (j,r,p,t,s,v))

for j,p,t,s in pq:
    if pq[(j,p,t,s)].varValue > 0:
        v = (pq[(j,p,t,s)].varValue)
        print ("Manufacturer %s produces end product %s in period %s for scenario %s with quantity %s" % (j,p,t,s,v))

for l,p,t,s in dsl:
    if dsl[(l,p,t,s)].varValue > 0:
        v = (dsl[(l,p,t,s)].varValue)
        print ("Demand of retailer %s for end product %s in period %s for scenario %s is not met %s quantity!" % (l,p,t,s,v))

for j,r,t,s in imfgr:
    if imfgr[(j,r,t,s)].varValue > 0:
        v = (imfgr[(j,r,t,s)].varValue)
        print ("Inventory at manufacturer %s for raw material %s in period %s for scenario %s is stored with %s quantity!" % (j,r,t,s,v))

for j,p,t,s in imfgp:
    if imfgp[(j,p,t,s)].varValue > 0:
        v = (imfgp[(j,p,t,s)].varValue)
        print ("Inventory at manufacturer %s for end product %s in period %s for scenario %s is stored with %s quantity!" % (j,p,t,s,v))

for k,p,t,s in indr:
    if indr[(k,p,t,s)].varValue > 0:
        v = (indr[(k,p,t,s)].varValue)
        print ("Inventory at distributor %s for end product %s in period %s for scenario %s is stored with %s quantity!" % (k,p,t,s,v))

for i,j,r,t,s in stmr:
    if stmr[(i,j,r,t,s)].varValue > 0:
        v = (stmr[(i,j,r,t,s)].varValue)
        print ("Stock Transfer from manufacturer %s to manufacturer %s of raw material %s in period %s for scenario %s with quantity %s is moved!" % (i,j,r,t,s,v))

for i,j,p,t,s in stmp:
    if stmp[(i,j,p,t,s)].varValue > 0:
        v = (stmp[(i,j,p,t,s)].varValue)
        print ("Stock Transfer from manufacturer %s to manufacturer %s of end product %s in period %s for scenario %s with quantity %s is moved!" % (i,j,p,t,s,v))

for j,k,p,t,s in std:
    if std[(j,k,p,t,s)].varValue > 0:
        v = (std[(j,k,p,t,s)].varValue)
        print ("Stock Transfer from distributor %s to distributor %s of end product %s in period %s for scenario %s with quantity %s is moved!" % (j,k,p,t,s,v))

No comments:

Post a Comment