Как я могу изменить свой сценарий, чтобы он минимизировал стоимость и в то же время вычислял объем и выбранный вес? - PullRequest
0 голосов
/ 15 февраля 2019

Я создал функцию с использованием целлюлозы, которая принимает множество предметов и грузовиков.У каждого предмета есть вместимость, а у каждого грузовика - вместимость и стоимость.Я использовал средство расчета целлюлозы, чтобы рассчитать минимальное количество требуемых грузовиков, сохранив при этом минимальную стоимость.Ограничивающим фактором является пропускная способность, а оптимизирующим фактором является стоимость бункера.Но теперь я хочу добавить еще один ограничивающий фактор объема.Это можно сделать?Можете ли вы предложить способ сделать это с помощью самого решателя ??Я пытаюсь выполнить эту часть без использования решателя, но это совсем не помогает.Большое спасибо.

Я пытался создать функцию, которая заменяет минимальный грузовик на следующий по величине грузовик всякий раз, когда я получаю сообщение «Грузовиков недостаточно»

ОБНОВЛЕНИЕ: @kabdulla помог мнеполучить ответ, но также указал, что у него есть большой недостаток, что он учитывает только весь объем предметов, а не геометрию предметов, чтобы поместиться внутри;предмет 2 X 2 X 2 должен легко помещаться в грузовик, но 8 X 1 X 1 имеет другую геометрию и имеет другие ограничения.Вот мой обновленный код (все благодаря @kabdulla) с деталями и информацией о грузовике.

from pulp import *
import numpy as np

# Item details
item_name = ["Mudguard1","Mudguard2","Mudguard3","Mudguard4",]
item_id = ["1001474185","1001474401","1001474182","1001474154"]
item_length = [14,22,16,16]
item_breadth = [12,24,14,12]
item_height = [9,26,12,17]
item_quantity = [14,8,10,1]
item_vol = [12.25,63.55,15.55,1.88]
item_mass= [160,528,83,5]
n_items = len(item_id)
set_items = range(n_items)

# Details of trucks
item_name = ["Tata-407-9.5","Tata-407-13","Tata-407-17","Tata-407-16",]
item_id = ["1","2","3","4"]
truck_length = [14,22,16,16]
truck_breadth = [12,24,14,12]
truck_height = [9,26,12,17]
truck_quantity = [14,8,10,1]
truck_vol = [12.25,63.55,15.55,1.88]
truck_mass= [160,528,83,5]
truck_cost = [7,1.5,18,100]


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 allocation 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("x_soln"); print(x_soln)
print("y_soln"); print(y_soln)

print("Trucks used: " + str(sum(([y_soln[i] for i in set_trucks]))))

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

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:  126.5
x_soln
[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]]
y_soln
[1. 1. 1. 1.]
Trucks used: 4.0
Item 0 is packed in vehicle 0
Item 1 is packed in vehicle 1
Item 2 is packed in vehicle 2
Item 3 is packed in vehicle 3
The volume of used trucks is 93.22999999999999
Trucks are sufficient

Вот ссылка на colab для игры.https://colab.research.google.com/drive/1uKuS2F4Xd1Lbps8yAwivLbhzZrD_Hv0-

1 Ответ

0 голосов
/ 17 февраля 2019

В приведенной ниже версии кода предполагается, что для каждого грузового автомобиля существует общая грузоподъемность и ограничение общего грузоподъемности.Примечание: это не гарантирует комбинацию предметов, которые помещаются в грузовики (предмет размером 8 х 1 м х 1 м имеет объем 8 кубических метров, но не помещается в грузовик, внутреннее пространство которого составляет 2 х 2 м х 2 м = 8 куб.метров, например, но использование ограничения громкости ниже этого не нарушит ограничение).

from pulp import *
import numpy as np

# Item masses, volumes
item_mass = [16, 10, 5]
item_vol = [25, 12, 1]
n_items = len(item_vol)
set_items = range(n_items)

# Mass & volume capacities of trucks
truck_mass = [7, 15, 15, 15, 18, 38, 64, 100]
truck_vol = [25, 50, 50, 50, 100, 125, 250, 500]

# Cost of using each truck
truck_cost = [7, 1.5, 1.5, 1.5, 18, 380, 640, 1000]

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("x_soln"); print(x_soln)
print("y_soln"); print(y_soln)

print("Trucks used: " + str(sum(([y_soln[i] for i in set_trucks]))))

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

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: ', 19.5)
x_soln
[[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]
 [0. 1. 1.]
 [1. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]
y_soln
[0. 0. 0. 1. 1. 0. 0. 0.]
Trucks used: 2.0
Item 0 is packed in vehicle 4
Item 1 is packed in vehicle 3
Item 2 is packed in vehicle 3
Volume of used trucks is 150.0
Trucks are sufficient
...