Reputation: 2495
I have a code which return the number of trucks required to pack the given items based on the Weight and Volume of the items. This objective of this function is to minimize the cost of transportation
Code:
from pulp import *
import numpy as np
# Item masses, volumes
item_mass = data["Weight"].tolist()
item_vol = data["Volume"].tolist()
n_items = len(item_vol)
set_items = range(n_items)
# Mass & volume capacities of trucks
truck_mass = truck["Weight"].tolist()
truck_vol = truck["Volume"].tolist()
# Cost of using each truck
truck_cost = truck["Price"].tolist()
n_trucks = len(truck_cost)
set_trucks = range(n_trucks)
y = pulp.LpVariable.dicts('truckUsed', set_trucks,
lowBound=0, upBound=1, cat=LpInteger)
x = pulp.LpVariable.dicts('itemInTruck', (set_items, set_trucks),
lowBound=0, upBound=1, cat=LpInteger)
# Model formulation
prob = LpProblem("Truck allocatoin problem", LpMinimize)
# Objective
prob += lpSum([truck_cost[i] * y[i] for i in set_trucks])
# Constraints
for j in set_items:
# Every item must be taken in one truck
prob += lpSum([x[j][i] for i in set_trucks]) == 1
for i in set_trucks:
# Respect the mass constraint of trucks
prob += lpSum([item_mass[j] * x[j][i] for j in set_items]) <= truck_mass[i]*y[i]
# Respect the volume constraint of trucks
prob += lpSum([item_vol[j] * x[j][i] for j in set_items]) <= truck_vol[i]*y[i]
# Ensure y variables have to be set to make use of x variables:
for j in set_items:
for i in set_trucks:
x[j][i] <= y[i]
prob.solve()
x_soln = np.array([[x[i][j].varValue for i in set_items] for j in set_trucks])
y_soln = np.array([y[i].varValue for i in set_trucks])
print (("Status:"), LpStatus[prob.status])
print ("Total Cost is: ", value(prob.objective))
print("Trucks used: " + str(sum(([y_soln[i] for i in set_trucks]))))
a = []
b = []
for i in set_items:
for j in set_trucks:
if x[i][j].value() == 1:
print("Item " + str(i) + " is packed in vehicle "+ str(j))
a.append(str(j))
b.append(str(i))
totalitemvol = sum(item_vol)
totaltruckvol = sum([y[i].value() * truck_vol[i] for i in set_trucks])
print("Volume of used trucks is " + str(totaltruckvol))
if(totaltruckvol >= totalitemvol):
print("Trucks are sufficient")
else:
print("Items cannot fit")
This code return the output as follows:
Status: Optimal
Total Cost is: 400000.0
Trucks used: 3.0
Item 0 is packed in vehicle 7
Item 1 is packed in vehicle 7
Item 2 is packed in vehicle 6
Item 3 is packed in vehicle 7
Item 4 is packed in vehicle 16
Item 5 is packed in vehicle 7
Item 6 is packed in vehicle 16
Item 7 is packed in vehicle 7
Item 8 is packed in vehicle 16
Item 9 is packed in vehicle 6
Item 10 is packed in vehicle 16
Volume of used trucks is 3436.0
Trucks are sufficient
Instead of getting the index of items Can I replace "Item 0" with "Item (productId)" where ProductID is a series in the "data" Dataframe. I am happy to give the data and trucks csv files or the colab link.
Upvotes: 1
Views: 43
Reputation: 2337
Instead of "Item " + str(i) + " is packed in vehicle " + str(j)
and assuming that the order of the ProductID is the same as the order of set_trucks
, you could do
s = pd.Series(['item0', 'item1', 'item2'])
for i in set_items:
for j in set_trucks:
print("Item " + str(s[i]) + " is packed in vehicle " + str(j))
Since you're using Python 3, you can do it faster by using string formatting such as
print(f"Item {s[i]} is packed in vehicle {j}")
Upvotes: 1