Интеграция столбцов в функции - PullRequest
1 голос
/ 11 марта 2019

У меня есть код, который возвращает количество грузовиков, необходимое для упаковки заданных предметов, на основе веса и объема предметов.Эта цель этой функции состоит в том, чтобы минимизировать стоимость транспортировки

Код:

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")

Этот код возвращает вывод следующим образом:

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

Вместо полученияиндекс элементов Можно ли заменить «Элемент 0» на «Элемент (productId)», где ProductID - это серия в кадре данных «data».Я рад предоставить данные и файлы CSV грузовиков или ссылку на Colab.

1 Ответ

1 голос
/ 11 марта 2019

Вместо "Item " + str(i) + " is packed in vehicle " + str(j) и при условии, что порядок ProductID совпадает с порядком set_trucks, вы можете сделать

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))

Поскольку вы используете Python 3, вы можете сделать это быстрее, используя форматирование строк, например

print(f"Item {s[i]} is packed in vehicle {j}")
...