1、问题描述
在长为L、高为W的矩形托盘上,相互不重叠地摆放长为a、高为b的矩形零件,要求零件不超出托盘的矩形范围,且零件可以横放或纵放,但零件边界必须与托盘边界平行。问如何摆放能够使得摆放的零件最多。
2、问题分析
解决PLP问题主要包括两个变量:
,矩形零件是否横向放置在(k, j)点,见下图式(1)。
,矩形零件是否纵向放置在(k, j)点,见下图式(2)。
目标为最大化纵向放置与横向放置的零件数量之和,见下图式(3)。
约束为矩形零件不能有重叠,且在当前点最多只能放置一个零件,见下图式(4)。
具体变量定义及标引数学模型如下所示, 其中L、W为托盘的长、宽,a、b为矩形零件的长、宽。
3、COPT代码编写求解
from coptpy import *
# 初始参数
L = 19
W = 13
a = 5
b = 4
# =========================
# 模型求解
# =========================
model = Envr().createModel("Placement_1") # 创建COPT环境及模型
# 添加变量
h = model.addVars(L-a+1, W-b+1, vtype=COPT.BINARY, nameprefix="h_") # 零件是否横放在某点
v = model.addVars(L-b+1, W-a+1, vtype=COPT.BINARY, nameprefix="v_") # 零件是否纵放在某点
# 添加约束
for r in range(L):
for s in range(W):
model.addConstr(quicksum(h[k, j] for k in range(max(0, r-a), min(r-1, L-a)+1) for j in range(max(0, s-b), min(s-1, W-b)+1)) +
quicksum(v[k, j] for k in range(max(0, r-b), min(r-1, L-b)+1) for j in range(max(0, s-a), min(s-1, W-a)+1)) <= 1)
# 设置目标函数
obj = quicksum(h[k, j] for k in range(L-a+1) for j in range(W-b+1)) + quicksum(v[k, j] for k in range(L-b+1) for j in range(W-a+1))
model.setObjective(obj, sense=COPT.MAXIMIZE)
# 模型求解
model.setParam(COPT.Param.TimeLimit, 30.0) # 设置求解时间限制
status = model.solve()
h_result = [] # 横放块
v_result = [] # 纵放块
if model.status == COPT.OPTIMAL:
print('\nObjective value:{}'.format(model.objval))
allvars = model.getVars()
for i in range(L-a+1):
for j in range(W-b+1):
if h[i,j].value == 1:
h_result.append([i,j])
for i in range(L-b+1):
for j in range(W-a+1):
if v[i,j].value == 1:
v_result.append([i,j])
else:
print("No solution!")
对求解结果进行绘图验证:
4、Leapms求解
max sum{k=1,...,L-a+1;j=1,...,W-b+1}h[k][j]+sum{k=1,...,L-b+1;j=1,...,W-a+1}v[k][j]
subject to
sum{k=max(1,r-a+1),...,min(r,L-a+1);j=max(1,s-b+1),...,min(s,W-b+1)}h[k][j]+ -->
sum{k=max(1,r-b+1),...,min(r,L-b+1);j=max(1,s-a+1),...,min(s,W-a+1)}v[k][j]<=1 | -->
r=1,...,L;s=1,...,W
where
L,W,a,b are numbers
h[k][j] is a variable of binary | k=1,...,L-a+1;j=1,...,W-b+1
v[k][j] is a variable of binary | k=1,...,L-b+1;j=1,...,W-a+1
data
L=19
W=13
a=5
b=4
对求解结果进行绘图验证: