繁体   English   中英

如何更改脚本以使其成本最小化,同时计算所选的体积和重量是可行的?

[英]How can I change my script so it minimizes the cost, and at the same time calculates the volume and weight chosen is viable?

我使用纸浆创建了一个函数,该函数可容纳一系列物品和卡车。 每个项目都有一个容量,每辆卡车都有一个容量和一个成本。 我使用纸浆求解器来计算所需的最少卡车数量,同时又保持了最低成本。 限制因素是容量,而优化因素是装箱成本。 但是现在,我想添加另一个约束量。 能做到吗? 您能建议一种使用求解器本身的方法吗? 我试图在不使用求解器的情况下完成该部分,但这完全没有帮助。 非常感谢。

我尝试创建一个函数,以便在收到消息“卡车不足”时将最小的卡车替换为第二大的卡车。

更新:@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-

以下代码的版本假定总载重量和每辆卡车的总载重量限制。 注意:这不能保证可以组合在卡车内的物品(体积为8m x 1m x 1m的物品的体积为8立方米,但是不能容纳在内部空间为2m x 2m x 2m = 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM