【附代码】【MILP建模】3D装箱问题(3D-Bin Packing Problem)

文章目录

  • 相关教程
  • 相关文献
  • 问题描述
  • 建模思路——carton 方向
    • 平行轴建模方法(9变量6约束)
    • 平行轴建模方法(4变量8约束)
    • 枚举建模方法(6变量1约束)
  • 建模思路——carton 位置
    • 平行轴建模方法
    • 枚举建模方法
  • Bin长宽一定,求最小高度(Three-dimensional bin packing problem with variable bin height)
    • 完整建模
      • 指标集(Indices)
      • 常量(Parameters)
      • 决策变量(Decision variables)
      • 目标函数(Objective function)
      • 约束(constraints)
    • 完整建模(少变量版本)
      • 指标集(Indices)
      • 常量(Parameters)
      • 决策变量(Decision variables)
      • 目标函数(Objective function)
      • 约束(constraints)
    • 代码

作者:小猪快跑

基础数学&计算数学,从事优化领域7年+,主要研究方向:MIP求解器、整数规划、随机规划、智能优化算法

如有错误,欢迎指正。如有更好的算法,也欢迎交流!!!——@小猪快跑

相关教程

  • [x]

相关文献

  • [1] Wu Y , Li W , Goh M ,et al.Three-dimensional bin packing problem with variable bin height[J].European Journal of Operational Research, 2010, 202(2):347-355.DOI:10.1016/j.ejor.2009.05.040.

问题描述

三维装箱问题(3D Bin Packing Problem, 3D-BPP)是一个经典的组合优化问题。它涉及到在有限的三维空间内如何有效地放置不同尺寸的物品,以最大化容器的利用率或最小化所需的容器数量。具体来说,就是将一系列具有不同形状和大小的物品最优地填充到一个或多个容器中,使得容器的空间利用率最大,并且满足所有装载约束条件。

这个问题在物流、制造业、仓储管理等领域有着广泛的应用,例如集装箱装载、货车装载、仓库布局等。解决三维装箱问题通常需要采用高效的算法,因为这是一个NP难问题,意味着随着物品数量和种类的增加,找到精确解的计算复杂度会迅速增长。

常用的算法包括:

  1. 启发式算法:如First-Fit(首次适应算法)、Best-Fit(最佳适应算法)、Worst-Fit(最差适应算法)和First-Fit Decreasing(先降序排列再首次适应算法)。
  2. 元启发式算法:如遗传算法、模拟退火算法和禁忌搜索算法。
  3. 数学规划算法:如整数规划和约束规划。

假设:

  • carton :被装入bin中的小纸盒,每个都是规则的长方体,长宽高体积确定,放入bin中必须和坐标轴平行
  • bin: 包含carton的大纸盒,都是规则的长方体

建模思路——carton 方向

在这里插入图片描述

平行轴建模方法(9变量6约束)

对于任意一个 carton,最多有六种不同方向的装箱(如上图)。我们希望通过建模表示实际X、Y、Z轴 carton 的边长分别是多少。

  • ( l , w , h ) (l, w, h) (l,w,h) :carton的长、宽、高
  • ( X l , Y l , Z l ) (X_l,Y_l,Z_l) (Xl,Yl,Zl) :carton的长是否平行于X、Y、Z轴
  • ( X w , Y w , Z w ) (X_w,Y_w,Z_w) (Xw,Yw,Zw) :carton的宽是否平行于X、Y、Z轴
  • ( X h , Y h , Z h ) (X_h,Y_h,Z_h) (Xh,Yh,Zh) :carton的高是否平行于X、Y、Z轴

于是我们有

X轴Y轴Z轴 X l X_l Xl X w X_w Xw X h X_h Xh Y l Y_l Yl Y w Y_w Yw Y h Y_h Yh Z l Z_l Zl Z w Z_w Zw Z h Z_h Zh
lwh100010001
lhw100001010
wlh010100001
whl010001100
hlw001100010
hwl001010100

我们很容易就写出他们的约束:

{ X l + X w + X h = 1 Y l + Y w + Y h = 1 Z l + Z w + Z h = 1 \begin{cases} X_l + X_w + X_h = 1 \\ Y_l + Y_w + Y_h = 1 \\ Z_l + Z_w + Z_h = 1 \end{cases} Xl+Xw+Xh=1Yl+Yw+Yh=1Zl+Zw+Zh=1

{ X l + Y l + Z l = 1 X w + Y w + Z w = 1 X h + Y h + Z h = 1 \begin{cases} X_l + Y_l + Z_l = 1 \\ X_w + Y_w + Z_w = 1 \\ X_h + Y_h + Z_h = 1 \end{cases} Xl+Yl+Zl=1Xw+Yw+Zw=1Xh+Yh+Zh=1

这种建模一共有 9 个变量,6 个约束。

平行轴建模方法(4变量8约束)

如果在上述建模方法求解过程中变量太多成为瓶颈,那我们可以通过等价变换让变量少一些。至少需要 9 − 6 + 1 = 4 9 - 6 + 1 = 4 96+1=4 个变量。

不妨设 4 个变量为 X l , Y w , Z h , Z l X_l,Y_w,Z_h,Z_l Xl,Yw,Zh,Zl。我们给出一个很简单的推导过程:
{ X l + X w + X h = 1 Y l + Y w + Y h = 1 Z l + Z w + Z h = 1 X l + Y l + Z l = 1 X w + Y w + Z w = 1 X h + Y h + Z h = 1 ⇒ { X l + X w + X h = 1 Y l + Y w + Y h = 1 Z l + Z w + Z h = 1 X l + Y l + Z l = 1 X w + Y w + Z w = 1 X h + Y h + Z h = 1 ⇒ { X l + X w + X h = 1 Y l + Y w + Y h = 1 Z l + Z w + Z h = 1 X l + Y l + Z l = 1 X w + Y w + Z w = 1 X h + Y h + Z h = 1 ⇒ { X l + X w + X h = 1 Y l + Y w + Y h = 1 Z l + Z w + Z h = 1 X l + Y l + Z l = 1 X w + Y w + Z w = 1 X h + Y h + Z h = 1 \begin{cases} \textbf X_l + X_w + X_h = 1 \\ Y_l + \textbf Y_w + Y_h = 1 \\ \textbf Z_l + Z_w + \textbf Z_h = 1 \\ \textbf X_l + Y_l + \textbf Z_l = 1 \\ X_w + \textbf Y_w + Z_w = 1 \\ X_h + Y_h + \textbf Z_h = 1 \\ \end{cases} \Rightarrow \begin{cases} \textbf X_l + X_w + X_h = 1 \\ \textbf Y_l + \textbf Y_w + Y_h = 1 \\ \textbf Z_l + \textbf Z_w + \textbf Z_h = 1 \\ \textbf X_l + \textbf Y_l + \textbf Z_l = 1 \\ X_w + \textbf Y_w + \textbf Z_w = 1 \\ X_h + Y_h + \textbf Z_h = 1 \\ \end{cases} \Rightarrow \begin{cases} \textbf X_l + \textbf X_w + X_h = 1 \\ \textbf Y_l + \textbf Y_w + \textbf Y_h = 1 \\ \textbf Z_l + \textbf Z_w + \textbf Z_h = 1 \\ \textbf X_l + \textbf Y_l + \textbf Z_l = 1 \\ \textbf X_w + \textbf Y_w + \textbf Z_w = 1 \\ X_h + \textbf Y_h + \textbf Z_h = 1 \\ \end{cases} \Rightarrow \begin{cases} \textbf X_l + \textbf X_w + \textbf X_h = 1 \\ \textbf Y_l + \textbf Y_w + \textbf Y_h = 1 \\ \textbf Z_l + \textbf Z_w + \textbf Z_h = 1 \\ \textbf X_l + \textbf Y_l + \textbf Z_l = 1 \\ \textbf X_w + \textbf Y_w + \textbf Z_w = 1 \\ \textbf X_h + \textbf Y_h + \textbf Z_h = 1 \\ \end{cases} Xl+Xw+Xh=1Yl+Yw+Yh=1Zl+Zw+Zh=1Xl+Yl+Zl=1Xw+Yw+Zw=1Xh+Yh+Zh=1 Xl+Xw+Xh=1Yl+Yw+Yh=1Zl+Zw+Zh=1Xl+Yl+Zl=1Xw+Yw+Zw=1Xh+Yh+Zh=1 Xl+Xw+Xh=1Yl+Yw+Yh=1Zl+Zw+Zh=1Xl+Yl+Zl=1Xw+Yw+Zw=1Xh+Yh+Zh=1 Xl+Xw+Xh=1Yl+Yw+Yh=1Zl+Zw+Zh=1Xl+Yl+Zl=1Xw+Yw+Zw=1Xh+Yh+Zh=1
于是我们有
{ Z w = 1 − Z l − Z h Y l = 1 − X l − Z l Y h = X l − Y w + Z l X w = − Y w + Z l + Z h X h = 1 − X l + Y w − Z l − Z h \begin{cases} Z_w = 1 - Z_l - Z_h \\ Y_l = 1 - X_l - Z_l \\ Y_h = X_l -Y_w + Z_l \\ X_w = -Y_w + Z_l + Z_h \\ X_h = 1 - X_l + Y_w - Z_l - Z_h \end{cases} Zw=1ZlZhYl=1XlZlYh=XlYw+ZlXw=Yw+Zl+ZhXh=1Xl+YwZlZh
上面的变量都是 0-1 变量,所以我们增加约束如下:
Z l + Z h ⩽ 1 X l + Z l ⩽ 1 X l − Y w + Z l ⩽ 1 − X l + Y w − Z l ⩽ 0 − Y w + Z l + Z h ⩽ 1 Y w − Z l − Z h ⩽ 0 − X l + Y w − Z l − Z h ⩽ 0 X l − Y w + Z l + Z h ⩽ 1 \begin{aligned} &Z_l+Z_h\leqslant 1\\ &X_l+Z_l\leqslant 1 \\ &X_l -Y_w + Z_l\leqslant 1\\ &-X_l +Y_w - Z_l\leqslant 0 \\ &-Y_w + Z_l + Z_h\leqslant 1\\ &Y_w - Z_l - Z_h\leqslant 0\\ &- X_l + Y_w - Z_l - Z_h\leqslant 0\\ &X_l - Y_w + Z_l + Z_h\leqslant 1 \end{aligned} Zl+Zh1Xl+Zl1XlYw+Zl1Xl+YwZl0Yw+Zl+Zh1YwZlZh0Xl+YwZlZh0XlYw+Zl+Zh1
这种建模一共有 4 个变量,8 个约束。(但如果求LP的解不一定快,因为增加了自由变量后等价于之前的建模)

枚举建模方法(6变量1约束)

对于任意一个 carton,最多有六种不同方向的装箱。我们希望通过建模表示实际X、Y、Z轴 carton 的边长分别是多少。

  • ( l , w , h ) (l, w, h) (l,w,h) :carton的长、宽、高
  • ( l ′ , w ′ , h ′ ) (l', w', h') (l,w,h) :carton的在 X、Y、Z轴边长分别是多少
  • δ i \delta_{i} δi:0-1变量,代表 carton 方向

{ δ 1 + δ 2 + δ 3 + δ 4 + δ 5 + δ 6 = 1 l ′ = δ 1 l + δ 2 l + δ 3 w + δ 4 w + δ 5 h + δ 6 h w ′ = δ 1 w + δ 2 h + δ 3 l + δ 4 h + δ 5 l + δ 6 w h ′ = δ 1 h + δ 2 w + δ 3 h + δ 4 l + δ 5 w + δ 6 l \begin{cases} \delta_1+\delta_2+\delta_3+\delta_4+\delta_5+\delta_6=1 \\ l'=\delta_1l+\delta_2l+\delta_3w+\delta_4w+\delta_5h+\delta_6h \\ w'=\delta_1w+\delta_2h+\delta_3l+\delta_4h+\delta_5l+\delta_6w \\ h'=\delta_1h+\delta_2w+\delta_3h+\delta_4l+\delta_5w+\delta_6l \end{cases} δ1+δ2+δ3+δ4+δ5+δ6=1l=δ1l+δ2l+δ3w+δ4w+δ5h+δ6hw=δ1w+δ2h+δ3l+δ4h+δ5l+δ6wh=δ1h+δ2w+δ3h+δ4l+δ5w+δ6l

建模思路——carton 位置

在这里插入图片描述

平行轴建模方法

  • ( l i , w i , h i ) (l_i,w_i,h_i) (li,wi,hi):carton i i i 的长、宽、高
  • ( L , W , H ) (L,W,H) (L,W,H):Bin的长、宽、高
  • ( x i , y i , z i ) (x_i,y_i,z_i) (xi,yi,zi):连续决策变量,carton i i i 的左下后方点的坐标
  • ( X l i , Y l i , Z l i ) (X_{l_i},Y_{l_i},Z_{l_i}) (Xli,Yli,Zli) :布尔决策变量,分别表示 carton i i i 的长是否平行于 bin 的 X、Y、Z轴
  • ( X w i , Y w i , Z w i ) (X_{w_i},Y_{w_i},Z_{w_i}) (Xwi,Ywi,Zwi) :布尔决策变量,分别表示 carton i i i 的宽是否平行于 bin 的 X、Y、Z轴
  • ( X h i , Y h i , Z h i ) (X_{h_i},Y_{h_i},Z_{h_i}) (Xhi,Yhi,Zhi) :布尔决策变量,分别表示 carton i i i 的高是否平行于 bin 的 X、Y、Z轴
  • a i j , b i j , c i j a_{ij},b_{ij},c_{ij} aij,bij,cij:布尔变量,分别表示 carton i i i 和 carton j j j 的相对位置:若 i i i j j j 的前面(X轴),右面(Y轴),上面(Z轴),则为1,否则为0
  • M M M:足够大的常数

carton 不重叠
{ x i + l i X l i + w i X w i + h i X h i ⩽ x j + M ( 1 − a i j ) , i ≠ j y i + l i Y l i + w i Y w i + h i Y h i ⩽ y j + M ( 1 − b i j ) , i ≠ j z i + l i Z l i + w i Z w i + h i Z h i ⩽ z j + M ( 1 − c i j ) , i ≠ j \begin{cases} x_i + l_i X_{l_i} + w_i X_{w_i} + h_i X_{h_i} \leqslant x_j + M(1 - a_{ij}) ,\quad i\neq j \\ y_i + l_i Y_{l_i} + w_i Y_{w_i} + h_i Y_{h_i} \leqslant y_j + M(1 - b_{ij}) ,\quad i\neq j \\ z_i + l_i Z_{l_i} + w_i Z_{w_i} + h_i Z_{h_i} \leqslant z_j + M(1 - c_{ij}) ,\quad i\neq j \end{cases} xi+liXli+wiXwi+hiXhixj+M(1aij),i=jyi+liYli+wiYwi+hiYhiyj+M(1bij),i=jzi+liZli+wiZwi+hiZhizj+M(1cij),i=j

carton 都在 bin 中
{ x i + l i X l i + w i X w i + h i X h i ⩽ L y i + l i Y l i + w i Y w i + h i Y h i ⩽ W z i + l i Z l i + w i Z w i + h i Z h i ⩽ H \begin{cases} x_i + l_i X_{l_i} + w_i X_{w_i} + h_i X_{h_i} \leqslant L \\ y_i + l_i Y_{l_i} + w_i Y_{w_i} + h_i Y_{h_i} \leqslant W \\ z_i + l_i Z_{l_i} + w_i Z_{w_i} + h_i Z_{h_i} \leqslant H \end{cases} xi+liXli+wiXwi+hiXhiLyi+liYli+wiYwi+hiYhiWzi+liZli+wiZwi+hiZhiH
carton 相对位置限制
a i j + a j i + b i j + b j i + c i j + c j i ⩾ 1 , i ≠ j a_{ij}+a_{ji}+b_{ij}+b_{ji}+c_{ij}+c_{ji}\geqslant1,\quad i\neq j aij+aji+bij+bji+cij+cji1,i=j

枚举建模方法

  • ( l i , w i , h i ) (l_i,w_i,h_i) (li,wi,hi):carton i i i 的长、宽、高
  • ( l i ′ , w i ′ , h i ′ ) (l_i', w_i', h_i') (li,wi,hi) :carton i i i 在 X、Y、Z轴边长分别是多少
  • δ i 1 , δ i 2 , δ i 3 , δ i 4 , δ i 5 , δ i 6 \delta_{i1},\delta_{i2},\delta_{i3},\delta_{i4},\delta_{i5},\delta_{i6} δi1,δi2,δi3,δi4,δi5,δi6:0-1变量,代表 carton i i i 方向
  • ( L , W , H ) (L,W,H) (L,W,H):Bin的长、宽、高
  • ( x i , y i , z i ) (x_i,y_i,z_i) (xi,yi,zi):连续决策变量,carton i i i 的左下后方点的坐标
  • a i j , b i j , c i j a_{ij},b_{ij},c_{ij} aij,bij,cij:布尔变量,分别表示 carton i i i 和 carton j j j 的相对位置:若 i i i j j j 的前面(X轴),右面(Y轴),上面(Z轴),则为1,否则为0

carton 不重叠
{ x i + l i ′ ⩽ x j + L ( 1 − a i j ) , i ≠ j y i + w i ′ ⩽ y j + W ( 1 − b i j ) , i ≠ j z i + h i ′ ⩽ z j + H ( 1 − c i j ) , i ≠ j \begin{cases} x_i + l_i' \leqslant x_j + L(1 - a_{ij}) ,\quad i\neq j \\ y_i + w_i' \leqslant y_j + W(1 - b_{ij}) ,\quad i\neq j \\ z_i + h_i' \leqslant z_j + H(1 - c_{ij}) ,\quad i\neq j \\ \end{cases} xi+lixj+L(1aij),i=jyi+wiyj+W(1bij),i=jzi+hizj+H(1cij),i=j

carton 都在 bin 中
{ x i + l i ′ ⩽ L y i + w i ′ ⩽ W z i + h i ′ ⩽ H \begin{cases} x_i + l_i' \leqslant L \\ y_i + w_i' \leqslant W \\ z_i + h_i' \leqslant H \\ \end{cases} xi+liLyi+wiWzi+hiH
carton 相对位置限制
a i j + a j i + b i j + b j i + c i j + c j i ⩾ 1 , i ≠ j a_{ij}+a_{ji}+b_{ij}+b_{ji}+c_{ij}+c_{ji}\geqslant1,\quad i\neq j aij+aji+bij+bji+cij+cji1,i=j

Bin长宽一定,求最小高度(Three-dimensional bin packing problem with variable bin height)

完整建模

指标集(Indices)

  • i ∈ I i \in I iI:carton 的指标集

常量(Parameters)

  • ( l i , w i , h i ) (l_i,w_i,h_i) (li,wi,hi):每个carton的长、宽、高

  • M M M:足够大的常数

  • ( L , W ) (L,W) (L,W):Bin的长、宽

决策变量(Decision variables)

  • ( x i , y i , z i ) (x_i,y_i,z_i) (xi,yi,zi):连续决策变量,carton i i i 的左下后方点的坐标
  • ( X l i , Y l i , Z l i ) (X_{l_i},Y_{l_i},Z_{l_i}) (Xli,Yli,Zli) :布尔决策变量,分别表示 carton i i i 的长是否平行于 bin 的 X、Y、Z轴
  • ( X w i , Y w i , Z w i ) (X_{w_i},Y_{w_i},Z_{w_i}) (Xwi,Ywi,Zwi) :布尔决策变量,分别表示 carton i i i 的宽是否平行于 bin 的 X、Y、Z轴
  • ( X h i , Y h i , Z h i ) (X_{h_i},Y_{h_i},Z_{h_i}) (Xhi,Yhi,Zhi) :布尔决策变量,分别表示 carton i i i 的高是否平行于 bin 的 X、Y、Z轴
  • a i j , b i j , c i j a_{ij},b_{ij},c_{ij} aij,bij,cij:布尔变量,分别表示 carton i i i 和 carton j j j 的相对位置:若 i i i j j j 的前面(X轴),右面(Y轴),上面(Z轴),则为1,否则为0
  • H ~ \widetilde{H} H :Bin的高

目标函数(Objective function)

m i n H ~ \mathrm{min} \quad \widetilde{H} minH

约束(constraints)

carton 方向
{ X l i + X w i + X h i = 1 Y l i + Y w i + Y h i = 1 Z l i + Z w i + Z h i = 1 \begin{cases} X_{l_i} + X_{w_i} + X_{h_i} = 1 \\ Y_{l_i} + Y_{w_i} + Y_{h_i} = 1 \\ Z_{l_i} + Z_{w_i} + Z_{h_i} = 1 \end{cases} Xli+Xwi+Xhi=1Yli+Ywi+Yhi=1Zli+Zwi+Zhi=1

{ X l i + Y l i + Z l i = 1 X w i + Y w i + Z w i = 1 X h i + Y h i + Z h i = 1 \begin{cases} X_{l_i} + Y_{l_i} + Z_{l_i} = 1 \\ X_{w_i} + Y_{w_i} + Z_{w_i} = 1 \\ X_{h_i} + Y_{h_i} + Z_{h_i} = 1 \end{cases} Xli+Yli+Zli=1Xwi+Ywi+Zwi=1Xhi+Yhi+Zhi=1

carton 不重叠
{ x i + l i X l i + w i X w i + h i X h i ⩽ x j + M ( 1 − a i j ) , i ≠ j y i + l i Y l i + w i Y w i + h i Y h i ⩽ y j + M ( 1 − b i j ) , i ≠ j z i + l i Z l i + w i Z w i + h i Z h i ⩽ z j + M ( 1 − c i j ) , i ≠ j \begin{cases} x_i + l_i X_{l_i} + w_i X_{w_i} + h_i X_{h_i} \leqslant x_j + M(1 - a_{ij}) ,\quad i\neq j \\ y_i + l_i Y_{l_i} + w_i Y_{w_i} + h_i Y_{h_i} \leqslant y_j + M(1 - b_{ij}) ,\quad i\neq j \\ z_i + l_i Z_{l_i} + w_i Z_{w_i} + h_i Z_{h_i} \leqslant z_j + M(1 - c_{ij}) ,\quad i\neq j \\ \end{cases} xi+liXli+wiXwi+hiXhixj+M(1aij),i=jyi+liYli+wiYwi+hiYhiyj+M(1bij),i=jzi+liZli+wiZwi+hiZhizj+M(1cij),i=j

carton 都在 bin 中
{ x i + l i X l i + w i X w i + h i X h i ⩽ L y i + l i Y l i + w i Y w i + h i Y h i ⩽ W z i + l i Z l i + w i Z w i + h i Z h i ⩽ H ~ \begin{cases} x_i + l_i X_{l_i} + w_i X_{w_i} + h_i X_{h_i} \leqslant L \\ y_i + l_i Y_{l_i} + w_i Y_{w_i} + h_i Y_{h_i} \leqslant W \\ z_i + l_i Z_{l_i} + w_i Z_{w_i} + h_i Z_{h_i} \leqslant \widetilde{H} \\ \end{cases} xi+liXli+wiXwi+hiXhiLyi+liYli+wiYwi+hiYhiWzi+liZli+wiZwi+hiZhiH
carton 相对位置限制
a i j + a j i + b i j + b j i + c i j + c j i ⩾ 1 , i ≠ j a_{ij}+a_{ji}+b_{ij}+b_{ji}+c_{ij}+c_{ji}\geqslant1,\quad i\neq j aij+aji+bij+bji+cij+cji1,i=j

完整建模(少变量版本)

指标集(Indices)

  • i ∈ I i \in I iI:carton 的指标集

常量(Parameters)

  • ( l i , w i , h i ) (l_i,w_i,h_i) (li,wi,hi):每个carton的长、宽、高

  • M M M:足够大的常数

  • ( L , W ) (L,W) (L,W):Bin的长、宽

决策变量(Decision variables)

  • ( x i , y i , z i ) (x_i,y_i,z_i) (xi,yi,zi):连续决策变量,carton i i i 的左下后方点的坐标
  • ( X l i , Z l i ) (X_{l_i},Z_{l_i}) (Xli,Zli) :布尔决策变量,分别表示 carton i i i 的长是否平行于 bin 的 X、Z轴
  • Y w i Y_{w_i} Ywi :布尔决策变量,表示 carton i i i 的宽是否平行于 bin 的 Y轴
  • Z h i Z_{h_i} Zhi :布尔决策变量,表示 carton i i i 的高是否平行于 bin 的 Z轴
  • a i j , b i j , c i j a_{ij},b_{ij},c_{ij} aij,bij,cij:布尔变量,分别表示 carton i i i 和 carton j j j 的相对位置:若 i i i j j j 的前面(X轴),右面(Y轴),上面(Z轴),则为1,否则为0
  • H ~ \widetilde{H} H :Bin的高

目标函数(Objective function)

m i n H ~ \mathrm{min} \quad \widetilde{H} minH

约束(constraints)

carton 方向
X l i + Z l i ⩽ 1 Z l i + Z h i ⩽ 1 Z l i − Y w i + Z h i ⩽ 1 Z l i − Y w i + Z h i ⩾ 0 , 1 − X l i − Z l i + Y w i − Z h i ⩽ 1 1 − X l i − Z l i + Y w i − Z h i ⩾ 0 X l i + Z l i − Y w i ⩽ 1 X l i + Z l i − Y w i ⩾ 0 \begin{aligned} &X_{l_i}+Z_{l_i}\leqslant1\\ &Z_{l_i}+Z_{h_i}\leqslant1\\ &Z_{l_i}-Y_{w_i}+Z_{h_i}\leqslant1\\ &Z_{l_i}-Y_{w_i}+Z_{h_i}\geqslant0,\\ &1-X_{l_i}-Z_{l_i}+Y_{w_i}-Z_{h_i}\leqslant1\\ &1-X_{l_i}-Z_{l_i}+Y_{w_i}-Z_{h_i}\geqslant0\\ &X_{l_i}+Z_{l_i}-Y_{w_i}\leqslant1\\ &X_{l_i}+Z_{l_i}-Y_{w_i}\geqslant0 \end{aligned} Xli+Zli1Zli+Zhi1ZliYwi+Zhi1ZliYwi+Zhi0,1XliZli+YwiZhi11XliZli+YwiZhi0Xli+ZliYwi1Xli+ZliYwi0
carton 不重叠
{ x i + l i X l i + w i ( Z l i − Y w i + Z h i ) + h i ( 1 − X l i − Z l i + Y w i − Z h i ) ⩽ x j + M ( 1 − a i j ) , i ≠ j y i + w i Y w i + l i ( 1 − X l i − Z l i ) + h i ( X l i + Z l i − Y w i ) ⩽ y j + M ( 1 − b i j ) , i ≠ j z i + h i Z h i + w i ( 1 − Z l i − Z h i ) + l i Z l i ⩽ z j + M ( 1 − c i j ) , i ≠ j \begin{cases} x_i+l_iX_{l_i}+w_i(Z_{l_i}-Y_{w_i}+Z_{h_i})+h_i(1-X_{l_i}-Z_{l_i}+Y_{w_i}-Z_{h_i})\leqslant x_j+M(1-a_{ij}),\quad i\neq j\\ y_i+w_iY_{w_i}+l_i(1-X_{l_i}-Z_{l_i})+h_i(X_{l_i}+Z_{l_i}-Y_{w_i})\leqslant y_j+M(1-b_{ij}),\quad i\neq j\\ z_i+h_iZ_{h_i}+w_i(1-Z_{l_i}-Z_{h_i})+l_iZ_{l_i}\leqslant z_j+M(1-c_{ij}),\quad i\neq j\\ \end{cases} xi+liXli+wi(ZliYwi+Zhi)+hi(1XliZli+YwiZhi)xj+M(1aij),i=jyi+wiYwi+li(1XliZli)+hi(Xli+ZliYwi)yj+M(1bij),i=jzi+hiZhi+wi(1ZliZhi)+liZlizj+M(1cij),i=j

carton 都在 bin 中
{ x i + l i X l i + w i ( Z l i − Y w i + Z h i ) + h i ( 1 − X l i − Z l i + Y w i − Z h i ) ⩽ L y i + w i Y w i + l i ( 1 − X l i − Z l i ) + h i ( X l i + Z l i − Y w i ) ⩽ W z i + h i Z h i + w i ( 1 − Z l i − Z h i ) + l i Z l i ⩽ H ~ \begin{cases} x_i+l_iX_{l_i}+w_i(Z_{l_i}-Y_{w_i}+Z_{h_i})+h_i(1-X_{l_i}-Z_{l_i}+Y_{w_i}-Z_{h_i})\leqslant L\\ y_i+w_iY_{w_i}+l_i(1-X_{l_i}-Z_{l_i})+h_i(X_{l_i}+Z_{l_i}-Y_{w_i})\leqslant W\\ z_i+h_iZ_{h_i}+w_i(1-Z_{l_i}-Z_{h_i})+l_iZ_{l_i}\leqslant\widetilde{H} \end{cases} xi+liXli+wi(ZliYwi+Zhi)+hi(1XliZli+YwiZhi)Lyi+wiYwi+li(1XliZli)+hi(Xli+ZliYwi)Wzi+hiZhi+wi(1ZliZhi)+liZliH
carton 相对位置限制
a i j + a j i + b i j + b j i + c i j + c j i ⩾ 1 , i ≠ j a_{ij}+a_{ji}+b_{ij}+b_{ji}+c_{ij}+c_{ji}\geqslant1,\quad i\neq j aij+aji+bij+bji+cij+cji1,i=j

代码

在这里插入图片描述

枚举方法建模代码如下

import plotly.graph_objects as go
import gurobipy as gp
from gurobipy import GRB, quicksumdef add_box(fig, x, y, z, dx, dy, dz):"""向图形添加一个立方体"""fig.add_trace(go.Mesh3d(x=[x, x + dx, x + dx, x, x, x + dx, x + dx, x],y=[y, y, y + dy, y + dy, y, y, y + dy, y + dy],z=[z, z, z, z, z + dz, z + dz, z + dz, z + dz],i=[7, 0, 0, 0, 4, 4, 6, 6, 4, 0, 3, 2],j=[3, 4, 1, 2, 5, 6, 5, 2, 0, 1, 6, 3],k=[0, 7, 2, 3, 6, 7, 1, 1, 5, 5, 7, 6],opacity=1,flatshading=True,))class HeightProblemModel:"""Bin长宽一定,求最小高度(Three-dimensional bin packing problem with variable bin height)解决的是3D装箱问题的一个变种。不考虑 carton 的重量约束,仅仅考虑长宽高,方向可变,使得能装进尽可能多的东西。- carton :被装入bin中的小纸盒,每个都是规则的长方体,长宽高体积确定,放入bin中必须和坐标轴平行- bin: 包含carton的大纸盒,模型中假设底面积不变,高度是随着放入carton数量而变化的"""def __init__(self, carton_size, bin_size):"""carton_size = [[36, 36, 36],[59, 39, 20],[54, 40, 21],[58, 37, 21],[52, 33, 20],[40, 31, 21],[31, 31, 17],[31, 17, 16],[26, 23, 14],[33, 21, 4],]bin_size = [80, 58,100]Args:carton_size: 纸箱的长宽高bin_size: 纸盒尺寸"""self.L = bin_size[0]self.W = bin_size[1]self.H = bin_size[2]  # 纸盒最大高度self.l = [i[0] for i in carton_size]self.w = [i[1] for i in carton_size]self.h = [i[2] for i in carton_size]self.l2 = {}self.w2 = {}self.h2 = {}self.sigma = {}self.x = Noneself.y = Noneself.z = Noneself.m = Noneself.c = Noneself.b = Noneself.a = Nonedef create_solver(self, params: dict = None):self.m = gp.Model("Bin Packing - Height Problem")if params is None:params = {}for param_name, new_val in params.items():self.m.setParam(param_name, new_val)def add_vars(self):self.x = {}self.y = {}self.z = {}self.a = {}self.b = {}self.c = {}for i in range(len(carton_size)):self.x[i] = self.m.addVar(lb=0, ub=self.L, vtype=GRB.CONTINUOUS, name="x(%s)" % i)self.y[i] = self.m.addVar(lb=0, ub=self.W, vtype=GRB.CONTINUOUS, name="y(%s)" % i)self.z[i] = self.m.addVar(lb=0, ub=self.H, vtype=GRB.CONTINUOUS, name="z(%s)" % i)for j in range(6):self.sigma[i, j] = self.m.addVar(vtype=GRB.BINARY, name="x_l(%s)" % i)"""l'=\delta_1l+\delta_2l+\delta_3w+\delta_4w+\delta_5h+\delta_6h w'=\delta_1w+\delta_2h+\delta_3l+\delta_4h+\delta_5l+\delta_6w h'=\delta_1h+\delta_2w+\delta_3h+\delta_4l+\delta_5w+\delta_6l"""self.l2[i] = self.sigma[i, 0] * self.l[i] + self.sigma[i, 1] * self.l[i] + self.sigma[i, 2] * self.w[i] + \self.sigma[i, 3] * self.w[i] + self.sigma[i, 4] * self.h[i] + self.sigma[i, 5] * self.h[i]self.w2[i] = self.sigma[i, 0] * self.w[i] + self.sigma[i, 1] * self.h[i] + self.sigma[i, 2] * self.l[i] + \self.sigma[i, 3] * self.h[i] + self.sigma[i, 4] * self.l[i] + self.sigma[i, 5] * self.w[i]self.h2[i] = self.sigma[i, 0] * self.h[i] + self.sigma[i, 1] * self.w[i] + self.sigma[i, 2] * self.h[i] + \self.sigma[i, 3] * self.l[i] + self.sigma[i, 4] * self.w[i] + self.sigma[i, 5] * self.l[i]for j in range(len(carton_size)):if i == j:continueself.a[i, j] = self.m.addVar(vtype=GRB.BINARY, name="a(%s,%s)" % (i, j))self.b[i, j] = self.m.addVar(vtype=GRB.BINARY, name="b(%s,%s)" % (i, j))self.c[i, j] = self.m.addVar(vtype=GRB.BINARY, name="c(%s,%s)" % (i, j))self.H = self.m.addVar(lb=0, ub=self.H, vtype=GRB.CONTINUOUS, name="H")def set_obj(self):self.m.setObjective(self.H, GRB.MINIMIZE)def add_carton_direction_cons(self):for i in range(len(carton_size)):self.m.addConstr(quicksum(self.sigma[i, j] for j in range(6)) == 1, "carton_direction_cons(%s)" % i)def add_carton_no_overlap_cons(self):for i in range(len(carton_size)):for j in range(len(carton_size)):if i == j:continueself.m.addConstr(self.x[i] + self.l2[i] <= self.x[j] + self.L * (1 - self.a[i, j]),"carton_no_overlap_x_cons(%s,%s)" % (i, j))self.m.addConstr(self.y[i] + self.w2[i] <= self.y[j] + self.W * (1 - self.b[i, j]),"carton_no_overlap_y_cons(%s,%s)" % (i, j))self.m.addConstr(self.z[i] + self.h2[i] <= self.z[j] + self.H * (1 - self.c[i, j]),"carton_no_overlap_z_cons(%s,%s)" % (i, j))def add_carton_in_bin_cons(self):for i in range(len(carton_size)):for j in range(len(carton_size)):if i == j:continueself.m.addConstr(self.x[i] + self.l2[i] <= self.L, "carton_in_bin_x_cons(%s,%s)" % (i, j))self.m.addConstr(self.y[i] + self.w2[i] <= self.W, "carton_in_bin_y_cons(%s,%s)" % (i, j))self.m.addConstr(self.z[i] + self.h2[i] <= self.H, "carton_in_bin_z_cons(%s,%s)" % (i, j))def add_carton_limit_cons(self):for i in range(len(carton_size)):for j in range(len(carton_size)):if i == j:continueself.m.addConstr(self.a[i, j] + self.a[j, i] + self.b[i, j] + self.b[j, i] + self.c[i, j] + self.c[j, i] >= 1,"carton_limit_cons(%s,%s)" % (i, j))def add_conss(self):self.add_carton_direction_cons()self.add_carton_no_overlap_cons()self.add_carton_in_bin_cons()self.add_carton_limit_cons()def solve(self):self.m.optimize()return self.get_sol()def get_status(self):if self.m.status == GRB.status.OPTIMAL:return 'OPTIMAL'elif self.m.status == GRB.status.TIME_LIMIT:return 'TIME_LIMIT'def get_sol(self):status = self.get_status()gap = self.m.MIPGaplb = self.m.ObjBoundCub = self.m.ObjValruntime = self.m.Runtimereturn {'gap': gap, 'status': status, 'lb': lb, 'ub': ub, 'runtime': runtime}def make_model(self, params: dict = None):self.create_solver(params)self.add_vars()self.add_conss()self.set_obj()def plot(self):fig = go.Figure()for i in range(len(carton_size)):add_box(fig,self.x[i].X,self.y[i].X,self.z[i].X,self.sigma[i, 0].X * self.l[i] + self.sigma[i, 1].X * self.l[i] + self.sigma[i, 2].X * self.w[i] + \self.sigma[i, 3].X * self.w[i] + self.sigma[i, 4].X * self.h[i] + self.sigma[i, 5].X * self.h[i],self.sigma[i, 0].X * self.w[i] + self.sigma[i, 1].X * self.h[i] + self.sigma[i, 2].X * self.l[i] + \self.sigma[i, 3].X * self.h[i] + self.sigma[i, 4].X * self.l[i] + self.sigma[i, 5].X * self.w[i],self.sigma[i, 0].X * self.h[i] + self.sigma[i, 1].X * self.w[i] + self.sigma[i, 2].X * self.h[i] + \self.sigma[i, 3].X * self.l[i] + self.sigma[i, 4].X * self.w[i] + self.sigma[i, 5].X * self.l[i],)fig.update_layout(scene=dict(xaxis_title='X',yaxis_title='Y',zaxis_title='Z',))fig.show()if __name__ == '__main__':carton_size = [[36, 36, 36],[59, 39, 20],[54, 40, 21],[58, 37, 21],[52, 33, 20],[40, 31, 21],[31, 31, 17],[31, 17, 16],[26, 23, 14],[33, 21, 4],]bin_size = [80, 58, 200]model = HeightProblemModel(carton_size, bin_size)model.make_model()print(model.solve())model.plot()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/73444.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【计算机网络中的奈氏准则与香农定理】

文章目录 一、前言二、奈氏准则1. 概念2. 奈氏准则公式3. 奈氏准则的意义 三、香农定理1. 概念2. 香农定理公式3. 香农定理的意义 四、奈氏准则与香农定理的对比五、应用示例1. 奈氏准则示例2. 香农定理示例 六、总结 一、前言 在计算机网络中&#xff0c;数据的传输速率与信道…

【C++】回调函数和回调对象

文章目录 回调可调用对象函数指针作回调函数对象作回调函数对象的使用std::function【C11】作回调使用 【C11】Lambda表达式作回调【C11】bind对象作回调std::bind的使用作回调使用 回调 当发生某种事件时需要调用或触发另一个事件即为回调&#xff0c;回调的核心即为将可调用…

DeepSeek助力文案,智能音箱如何改变你的生活?

你好&#xff0c;我是三桥君 你有没有为写智能音箱的宣传文案而抓耳挠腮过&#xff1f;三桥君在这方面可是有些感想&#xff0c;今天就来给你唠唠怎么用DeepSeek写出超赞的智能音箱宣传文案。 首先&#xff0c;你得给DeepSeek喂足“料”。这就好比做饭&#xff0c;你得准备好各…

【区块链安全 | 第一篇】密码学原理

文章目录 1.哈希函数1.1 哈希函数的性质1.2 常见哈希算法1.3 Merkle Tree&#xff08;默克尔树&#xff09;1.4 HMAC&#xff08;哈希消息认证码&#xff09; 2. 公钥密码学2.1 对称加密 vs 非对称加密2.2 RSA 算法2.3 ECC&#xff08;椭圆曲线密码学&#xff09;2.4 Diffie-He…

基于websocketpp实现的五子棋项目

该博客对于学完C和linux操作系统&#xff0c;但不知道如何用C开发项目&#xff0c;已经不知道C如何使用第三方库的人来说一定很有帮助&#xff0c;请耐心看完&#xff01; 先看一下游戏会显示的前端界面&#xff0c;对理解这个游戏的前后端交互过程会有帮助 1. 开发环境 1.1 …

基于Redis分布锁+事务补偿解决数据不一致性问题

基于Redis的分布式设备库存服务设计与实现 概述 本文介绍一个基于Redis实现的分布式设备库存服务方案&#xff0c;通过分布式锁、重试机制和事务补偿等关键技术&#xff0c;保证在并发场景下库存操作的原子性和一致性。该方案适用于物联网设备管理、分布式资源调度等场景。 …

RK3568笔记八十: Linux 小智AI环境搭建

若该文为原创文章&#xff0c;转载请注明原文出处。 最近小智AI火了&#xff0c;韦老师出了 Linux 小智 AI 聊天机器人 版本&#xff0c;想移植到 RK3568上&#xff0c; 由于和韦老师硬件不同&#xff0c;所以需要交叉编译一些库&#xff0c;为后续移植做准备。 一、环境 1、…

C# SerialPort 使用详解

总目录 前言 在工业控制、物联网、嵌入式开发等领域&#xff0c;串口通信&#xff08;Serial Port Communication&#xff09;是连接串行设备&#xff08;如条码扫描器、GPS接收器等&#xff09;与计算机的重要手段。C# 提供了内置的 SerialPort 类&#xff0c;简化了串口开发…

3D点云的深度学习网络分类(按照作用分类)

1. 3D目标检测&#xff08;Object Detection&#xff09; 用于在点云中识别和定位目标&#xff0c;输出3D边界框&#xff08;Bounding Box&#xff09;。 &#x1f539; 方法类别&#xff1a; 单阶段&#xff08;Single-stage&#xff09;&#xff1a;直接预测3D目标位置&am…

LabVIEW 与 PLC 通讯的常见方式

在工业自动化和数据采集系统中&#xff0c;PLC&#xff08;可编程逻辑控制器&#xff09; 广泛用于控制和监测各种设备&#xff0c;而 LabVIEW 作为强大的图形化编程工具&#xff0c;常用于上位机数据处理和可视化。为了实现 LabVIEW 与 PLC 的高效通讯&#xff0c;常见的方法包…

2025 polarctf春季个人挑战赛web方向wp

来个弹窗 先用最基础的xss弹窗试一下 <script>alert("xss")</script>没有内容&#xff0c;猜测过滤了script&#xff0c;双写绕过一下 <scrscriptipt>alert("xss")</scscriptript>background 查看网页源代码 查看一下js文件 类…

【Ai】--- 可视化 DeepSeek-r1 接入 Open WebUI(超详细)

在编程的艺术世界里,代码和灵感需要寻找到最佳的交融点,才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里,我们将共同追寻这种完美结合,为未来的世界留下属于我们的独特印记。【Ai】--- 可视化 DeepSeek-r1 接入 Open WebUI(超详细) 开发环境一、前情提要:你…

7.1-7.2考研408数据结构查找算法核心知识点深度解析

考研408数据结构查找算法核心知识点深度解析 一、查找基本概念 1.1 核心定义与易错点 查找表与关键字 易错点:混淆静态查找表(仅查询)与动态查找表(含插入/删除操作)的应用场景。例如哈希表属于动态查找结构,而分块查找适用于静态数据。难点:理解平均查找长度(ASL)的…

Redis--redis客户端

目录 一、引言 二、数据库管理命令 三、redis客户端 四、Java客户端使用Redis 五、相关命令使用 1.get&#xff0c;set 2.exists&#xff0c;del 3.keys 4.expire&#xff0c;ttl 六、总结 一、引言 在之前学了redis相关类型命令之后&#xff0c;本篇文章&#xff0c;…

SpringBoot3.0不建议使用spring.factories,使用AutoConfiguration.imports新的自动配置方案

文章目录 一、写在前面二、使用imports文件1、使用2、示例比对3、完整示例 参考资料 一、写在前面 spring.factories是一个位于META-INF/目录下的配置文件&#xff0c;它基于Java的SPI(Service Provider Interface)机制的变种实现。 这个文件的主要功能是允许开发者声明接口的…

鸿蒙特效教程10-卡片展开/收起效果

鸿蒙特效教程10-卡片展开/收起效果 在移动应用开发中&#xff0c;卡片是一种常见且实用的UI元素&#xff0c;能够将信息以紧凑且易于理解的方式呈现给用户。 本教程将详细讲解如何在HarmonyOS中实现卡片的展开/收起效果&#xff0c;通过这个实例&#xff0c;你将掌握ArkUI中状…

hn航空app hnairSign unidbg 整合Springboot

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向分析 学习unidbg补环境。先弄一个…

奇怪的异形选项卡样式、弧形边框选项卡

<template><div :class"$options.name"><div class"tab">默认选项卡</div><div class"tab" active>选中选项卡</div><el-divider /><el-tabs v-model"tabActiveName" tab-click"(t…

特殊行车记录仪DAT视频丢失的恢复方法

行车记录仪是一种常见的车载记录仪&#xff0c;和常见的“小巧玲珑”的行车记录仪不同&#xff0c;一些特种车辆使用的记录仪的外观可以用“笨重”来形容。下边我们来看看特种车载行车记录仪删除文件后的恢复方法。 故障存储: 120GB存储设备/文件系统:exFAT /簇大小:128KB 故…

UE5小石子阴影在非常近距离才显示的问题

Unreal中采用LandscapeGrass生成的地形&#xff0c;在MovieRenderQueue中渲染时阴影显示距离有问题&#xff0c;在很近的时候才会有影子&#xff0c;怎么解决&#xff1f; 地面上通过grass生成的小石子的阴影只能在很近的时候才能显示出来&#xff0c;需要如下调整 r.Shadow.R…