Rahul Sharma
Rahul Sharma

Reputation: 2495

Column integration in a function

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

Answers (1)

m13op22
m13op22

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

Related Questions