Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
DataScienceUWL
GitHub Repository: DataScienceUWL/DS775
Path: blob/main/Lessons/Lesson 03 - LP 3/Self_Assess_Solns_03.ipynb
871 views
Kernel: Python 3 (system-wide)

Self-Assessment Solutions for Lesson 3

Self-Assessment: Unbalanced Transportation Problem

# Solution 1 with a dummy customer from pyomo.environ import * import pandas as pd ### PROBLEM DATA # Load Data factories = ['factory1', 'factory2'] customers = ['cust1', 'cust2', 'cust3','dummy'] usc = [[600, 800, 700, 0], [400, 900, 600, 0]] sup = [400, 500] dem = [300, 200, 300, 100] # dummy customer gets 100 for balance # Parse into Dictionaries supply = dict(zip(factories, sup)) demand = dict(zip(customers, dem)) unit_ship_cost = { f:{ c:usc[i][j] for j,c in enumerate(customers)} for i,f in enumerate(factories)} ### MODEL CONSTRUCTION ### # Declaration model = ConcreteModel() # Decision Variables model.transp = Var(factories, customers, domain=NonNegativeReals) # Objective model.total_cost = Objective(expr=sum(unit_ship_cost[f][c] * model.transp[f, c] for f in factories for c in customers), sense=minimize) # Constraints model.supply_ct = ConstraintList() for f in factories: model.supply_ct.add( sum(model.transp[f, c] for c in customers) == supply[f]) model.demand_ct = ConstraintList() for c in customers: model.demand_ct.add( sum(model.transp[f, c] for f in factories) == demand[c]) ### SOLUTION ### solver = SolverFactory('glpk') solver.solve(model) ### OUTPUT ### print(f"Minimum Total Cost = ${model.total_cost():,.2f}") # dataframes are displayed nicely in Jupyter dvars = pd.DataFrame([[model.transp[f, c]() for c in customers] for f in factories], index=factories, columns=customers) print("Number to ship from each factory to each customer:") dvars
Minimum Total Cost = $470,000.00 Number to ship from each factory to each customer:
# Solution 2 with no dummy center, adjust the supply constraint instead from pyomo.environ import * import pandas as pd ### PROBLEM DATA # Load Data factories = ['factory1', 'factory2'] customers = ['cust1', 'cust2', 'cust3'] usc = [[600, 800, 700], [400, 900, 600]] sup = [400, 500] dem = [300, 200, 300] # Parse into Dictionaries supply = dict(zip(factories, sup)) demand = dict(zip(customers, dem)) unit_ship_cost = { f:{ c:usc[i][j] for j,c in enumerate(customers)} for i,f in enumerate(factories)} ### MODEL CONSTRUCTION ### # Declaration model = ConcreteModel() # Decision Variables model.transp = Var(factories, customers, domain=NonNegativeReals) # Objective model.total_cost = Objective(expr=sum(unit_ship_cost[f][c] * model.transp[f, c] for f in factories for c in customers), sense=minimize) # Constraints model.supply_ct = ConstraintList() for f in factories: model.supply_ct.add( sum(model.transp[f, c] for c in customers) <= supply[f]) model.demand_ct = ConstraintList() for c in customers: model.demand_ct.add( sum(model.transp[f, c] for f in factories) == demand[c]) ### SOLUTION ### solver = SolverFactory('glpk') solver.solve(model) ### OUTPUT ### print(f"Minimum Total Cost = ${model.total_cost():,.2f}") # dataframes are displayed nicely in Jupyter dvars = pd.DataFrame([[model.transp[f, c]() for c in customers] for f in factories], index=factories, columns=customers) print("Number to ship from each factory to each customer:") dvars
Minimum Total Cost = $470,000.00 Number to ship from each factory to each customer:

Self-Assessment: Big M Method

Consider the example above where three of the routes are rendered infeasible as shown in the table below:

Start with the code above that is labeled "basic transportation code". Set the costs along the infeasible routes to be M=10000M = 10000 and solve the linear program. Does your solution have zero amounts along the infeasible routes? The minimum cost should now be higher than before. Why does that make sense?

# self-assessment big M method solution from pyomo.environ import* ### PROBLEM DATA ### # load data canneries = ['can1', 'can2','can3'] warehouses = ['ware1','ware2','ware3','ware4'] supply = [75, 125, 100] demand = [80, 65, 70, 85] bigM = 10000 unit_ship_cost = [[464, bigM, 654, 867], [bigM, 416, 690, 791], [995, 682, bigM, 685] ] # parse dictionaries supply_dict = dict( zip( canneries, supply) ) demand_dict = dict( zip( warehouses, demand)) unit_ship_cost_dict = { c: {w: unit_ship_cost[i][j] for j,w in enumerate(warehouses) } for i,c in enumerate(canneries)} ### MODEL CONSTRUCTION ### # declaration model = ConcreteModel() # decision variables model.transp = Var(canneries, warehouses, domain=NonNegativeReals) # objective model.total_cost = Objective(expr=sum(unit_ship_cost_dict[c][w] * model.transp[c, w] for c in canneries for w in warehouses), sense=minimize) # constraints model.supply_ct = ConstraintList() for c in canneries: model.supply_ct.add( sum(model.transp[c, w] for w in warehouses) == supply_dict[c]) model.demand_ct = ConstraintList() for w in warehouses: model.demand_ct.add( sum(model.transp[c, w] for c in canneries) == demand_dict[w]) ### SOLUTION ### solver = SolverFactory('glpk') solver.solve(model) ### OUTPUT ### print(f"Minimum Total Cost = ${model.total_cost():,.2f}") # put amounts in dataframe for nicer display import pandas as pd dvars = pd.DataFrame([[model.transp[c, w]() for w in warehouses] for c in canneries], index=canneries, columns=warehouses) print("Number of truckloads to ship from each cannery to each warehouse:") dvars
Minimum Total Cost = $176,000.00 Number of truckloads to ship from each cannery to each warehouse:

Self-Assessment: Unbalanced assignment problem without dummies

Solve the prototypical assignment problem above without introducing any dummy machines or locations. You'll need to slightly adjust one or more constraints.

from pyomo.environ import* import pandas as pd ### PROBLEM DATA ### # load data machines = ['mac1', 'mac2', 'mac3'] supply = [1 for m in machines] # gives [1,1,1] locations = ['loc1', 'loc2', 'loc3', 'loc4'] demand = [1 for l in locations] # gives [1,1,1,1] bigM = 1000 cost = [[13,16,12,11],[15,bigM,13,20],[5,7,10,6]] # parse into dictionaries supply_dict = dict( zip( machines, supply) ) demand_dict = dict( zip( locations, demand)) cost_dict = {m: {l: cost[i][j] for j,l in enumerate(locations)} for i,m in enumerate(machines)} ### MODEL CONSTRUCTION ### # declaration model = ConcreteModel() # decision variables model.assign = Var(machines, locations, domain=NonNegativeReals) # objective model.total_cost = Objective(expr=sum(cost_dict[m][l] * model.assign[m, l] for m in machines for l in locations), sense=minimize) # constraints model.supply_ct = ConstraintList() for m in machines: model.supply_ct.add( sum(model.assign[m, l] for l in locations) == supply_dict[m]) model.demand_ct = ConstraintList() for l in locations: model.demand_ct.add( sum(model.assign[m, l ] for m in machines) <= demand_dict[l]) # note we are using <= for larger set ### SOLUTION ### solver = SolverFactory('glpk') solver.solve(model) ### OUTPUT ### print(f"Minimum Cost per hour = ${model.total_cost():,.2f}") # put amounts in dataframe for nicer display dvars = pd.DataFrame([[model.assign[m, l]() for l in locations] for m in machines], index = machines, columns=locations) print("Machine assignments to locations:") dvars
Minimum Cost per hour = $29.00 Machine assignments to locations: