一个三维装箱问题的搜索树算法

三维装箱问题的业务场景可以参考电商业务中的纸箱推荐问题. 文中考虑了如下问题.

输入 : 长宽高为 ( L , W , H ) (L, W, H) (L,W,H)的箱子和 n n n个物品, 其长宽高为 ( l i , w i , h i ) (l_i, w_i, h_i) (li,wi,hi), i = 1 , 2 , … , n i=1,2,\ldots,n i=1,2,,n. 假设物品是长方体, 长度不可变(没有弹性). 装箱时可以对商品进行90度旋转, 但不能倾斜.
输出 : 判断所有物品是否能装入箱子.

本文提供一个基于搜索树的精确算法. 基本思想是把三维装箱问题归约(Reduce)到一个有向无环图(Directed Acyclic Graph)上的问题. 算法搜索到一个符合约束条件的有向无环图则返回true, 否则返回false.

物品的位置

如下图所示, 考虑任意一个物品(或者箱子), 我们可以用 a a a, b b b两点的三维坐标描述其位置和大小. 设 a = ( x a , y a , z a ) a=(x_a,y_a,z_a) a=(xa,ya,za), 那么 b = ( x a + L , y a + W , z a + H ) b=(x_a+L, y_a+W, z_a+H) b=(xa+L,ya+W,za+H), 其中 L , W , H L, W, H L,W,H是物品的长宽高. 为了方便描述, 我们用 a a a点的坐标表示物品的位置.

有向无环图

假设所有物品能够被装入箱子中. 此时我们考虑一种可行的摆放方式. 对两个物品 i ≠ j i \neq j i=j, 分别考虑 x , y , z x, y, z x,y,z轴方向物品之间的相对位置关系.

首先考虑 x x x轴方向, i i i j j j只有两种位置关系

  1. i i i j j j的左边, 即 x i ≤ x j x_i \leq x_j xixj, 其中 x i , x j x_i, x_j xi,xj为物品在 x x x轴的坐标;
  2. i i i j j j的右边, 即 x i > x j x_i > x_j xi>xj.

下面我们构造有向图 D x = ( V , u x , A x ) D_x = (V, u^x, A_x) Dx=(V,ux,Ax). 其中

  • V = { 1 , 2 , … , n } V=\{1, 2, \ldots, n\} V={1,2,,n}是所有物品的集合.
  • u x u^x ux为顶点权重的集合, 即 u i x = l i u^x_i=l_i uix=li, ∀ i = 1 , 2 , … , n \forall i=1, 2, \ldots, n i=1,2,,n.
  • A x A_x Ax为弧(Arc)的集合. 如果 i i i j j j的左边, 则 ( i , j ) ∈ A x (i, j)\in A_x (i,j)Ax, 否则 ( j , i ) ∈ A x (j,i)\in A_x (j,i)Ax(如下图所示).
    注意: 如果 ( i , j ) , ( j , k ) ∈ A x (i, j), (j,k) \in A_x (i,j),(j,k)Ax, 则 ( i , k ) ∈ A x (i,k)\in A_x (i,k)Ax. 换句话说, D x D_x Dx无环.

S x , T x S_x, T_x Sx,Tx分别代表 D x D_x Dx中入度(in-degree)为0和出度(out-degree)为0的点集. 以上图为例, S x = { 1 , 2 } S_x = \{1, 2\} Sx={1,2}(蓝色的点), T x = { 4 , 6 , 7 } T_x=\{4, 6, 7\} Tx={4,6,7}(红色的点). 对任意的 s ∈ S x s\in S_x sSx, t ∈ T x t\in T_x tTx, 用 P s , t x P^x_{s,t} Ps,tx代表从 s s s t t t的路径. 令 u ( P s , t x ) u(P^x_{s,t}) u(Ps,tx)代表 P s , t x P^x_{s,t} Ps,tx中顶点的总权重, 即
u ( P s , t x ) = ∑ i ∈ P s , t x u i x = ∑ i ∈ P s , t x l i . u(P^x_{s, t}) = \sum_{i\in P^x_{s,t}}{u^x_i} = \sum_{i\in P^x_{s,t}}{l_i}. u(Ps,tx)=iPs,txuix=iPs,txli.

考虑到装入箱子的物品总长度不能超过箱子的长, 我们要求 max ⁡ s ∈ S x , t ∈ T x u ( P s , t x ) ≤ L \max_{s\in S_x, t\in T_x} u(P^x_{s, t}) \leq L maxsSx,tTxu(Ps,tx)L.

用类似的方法考虑 y y y轴和 z z z轴方向并构造 D y = ( V , u y , A y ) D_y=(V, u^y, A_y) Dy=(V,uy,Ay) D z = ( V , u z , A z ) D_z=(V,u^z, A_z) Dz=(V,uz,Az), 其中

  • u i y = w i u^y_i=w_i uiy=wi, u i z = h i u^z_i=h_i uiz=hi, i = 1 , 2 , … , n i=1, 2, \ldots, n i=1,2,,n.
  • ( i , j ) ∈ A y (i, j) \in A_y (i,j)Ay表示 i i i j j j的后方(反之 i i i j j j的前方).
  • ( i , j ) ∈ A z (i, j) \in A_z (i,j)Az表示 i i i j j j的下方(反之 i i i j j j的上方).

下面我们得到所有物品能装入箱子的充要条件:

  1. G = ( V , E ( A x ∪ A y ∪ A z ) ) G=(V, E(A_x\cup A_y \cup A_z)) G=(V,E(AxAyAz))是一个团(Clique), 其中记号 E ( A ) E(A) E(A)代表有向边集合 A A A对应的无向边集合.
  2. max ⁡ s ∈ S x , t ∈ T x u ( P s , t x ) ≤ L \max_{s\in S_x, t\in T_x} u(P^x_{s, t}) \leq L maxsSx,tTxu(Ps,tx)L.
  3. max ⁡ s ∈ S y , t ∈ T y u ( P s , t y ) ≤ W \max_{s\in S_y, t\in T_y} u(P^y_{s, t}) \leq W maxsSy,tTyu(Ps,ty)W.
  4. max ⁡ s ∈ S z , t ∈ T z u ( P s , t z ) ≤ H \max_{s\in S_z, t\in T_z} u(P^z_{s, t}) \leq H maxsSz,tTzu(Ps,tz)H.

搜索策略

结合前文的讨论, 我们先总结分支的因素:

  • 需要比较任意两个物品之间的相对位置, 共有 C n 2 C_n^2 Cn2种情况.
  • 两个物品之间共有6种相对位置关系: 左右, 后前, 下上.
  • 每种物品最多有6种不同的摆放方式: ( l , w , h ) , ( l , h , w ) , ( w , l , h ) , ( w , h , l ) , ( h , l , w ) , ( h , w , l ) (l, w, h), (l, h, w), (w, l, h), (w, h, l), (h, l, w), (h, w, l) (l,w,h),(l,h,w),(w,l,h),(w,h,l),(h,l,w),(h,w,l).

I k ( 1 ≤ k ≤ n ) I_k (1\leq k \leq n) Ik(1kn)表示一个装箱问题的实例, 其中物品集合为 { 1 , 2 , … , k } \{1, 2, \ldots, k\} {1,2,,k}. 我们搜索的策略是用深度优先的方式依次判断 I 1 , I 2 , … , I n I_1, I_2, \ldots, I_n I1,I2,,In的可行性. 设 I k I_k Ik可行. 考虑 I k + 1 I_{k+1} Ik+1时, 我们需要对比 ( 1 , k + 1 ) , ( 2 , k + 1 ) , … , ( k , k + 1 ) (1, k+1), (2, k+1), \ldots, (k, k+1) (1,k+1),(2,k+1),,(k,k+1). 此外, 对每个物品对(pair) ( i , k + 1 ) (i, k+1) (i,k+1), 1 ≤ i ≤ k 1\leq i\leq k 1ik, 我们要考虑 6 × 6 = 36 6\times 6 = 36 6×6=36种相对位置和排放方式. 因此, 对 I k I_k Ik的任意一搜索节点, 它的分支数量是 36 k 36k 36k(示意图如下).

说明 : 从根节点root开始搜索. 第一层是判断 I 1 I_1 I1是否可行, 由于 I 1 I_1 I1包含1个物品, 因此只需要考虑6种摆放方式, 即 ( 1 ) 1 , … , ( 1 ) 6 (1)^1, \ldots, (1)^6 (1)1,,(1)6; 第二层判断 I 2 I_2 I2是否可行, 需要比较两个物品 ( 1 , 2 ) (1, 2) (1,2), 其中每个节点有36个分支, 对应6种相对位置关系和物品2的六种摆放方式的组合; 第三, 四层判断 I 3 I_3 I3是否可行, 需要比较 ( 1 , 3 ) (1,3) (1,3) ( 2 , 3 ) (2,3) (2,3); 依次类推.

注意 : 分支前必须检查两个物品间是否已经有位置关系, 若有, 则当前节点不需要分支(确保无环). 例如, 如果物品1在物品2的左边, 物品2在物品3的左边, 那么物品1一定在物品3的左边, 因此无需比较物品3在物品1左边的情况.

优化策略

  1. 物品的排序比较重要. 直观的做法是把物品按照体积由大到小排序.
  2. 物品的摆放方式实际上是1-6种. 如果物品是立方体, 则只需要考虑1种摆放方式. 在实际中应该额外考虑三边相同和两边相同的情况.
  3. 判定 I 2 I_2 I2时可以考虑物品的对称性, 因此相对位置只要考虑左, 后, 下.
  4. 比较物品间的相对位置时按照"从外到内"的原则, 即右, 前, 上, 左, 后, 下.

可行性判定

考虑三维装箱实例 I k I_k Ik, 1 ≤ k ≤ n 1\leq k\leq n 1kn. 令 D x k , D y k , D z k D^k_x, D^k_y, D^k_z Dxk,Dyk,Dzk x , y , z x,y,z x,y,z轴方向的有向无环图. 令 D k = ( D x k , D y k , D z k ) D^k=(D^k_x, D^k_y, D^k_z) Dk=(Dxk,Dyk,Dzk). 如上图所示, 我们的搜索过程需要判断 D 1 , D 2 , … , D n D^1, D^2, \ldots, D^n D1,D2,,Dn的可行性. 考虑 D k D^k Dk: 顶点个数是 3 k 3k 3k, 边的个数是 O ( k 2 ) O(k^2) O(k2), 因此 最长路(顶点权重之和最大) 的计算可以在 O ( k 2 ) O(k^2) O(k2)的时间内完成. 具体来说, 以 D x k D^k_x Dxk为例, 我们可以维护每个顶点 i ( 1 ≤ i ≤ k ) i(1\leq i\leq k) i(1ik)的最长路程. 当考虑 D x k + 1 D^{k+1}_x Dxk+1时, 例如增加弧 ( i , k + 1 ) (i, k+1) (i,k+1) ( k + 1 , i ) (k+1, i) (k+1,i), 我们只需要更新 k + 1 k+1 k+1所有子节点的最长路程即可.

时间复杂度

搜索树第 k k k层(root是第0层)对应的节点数量是 3 6 k − 1 36^{k-1} 36k1. 如上图所示, 实例 I k ( ≥ 2 ) I_k(\geq 2) Ik(2)包含了 k − 1 k-1 k1层. 因此, 从第二层到叶子节点一共有 n ( n − 1 ) / 2 n(n-1)/2 n(n1)/2层. 因此, 搜索树的节点总数 N N N为:
N = ∑ k = 1 n ( n − 1 ) / 2 3 6 k − 1 + 7 = O ( 6 n 2 ) . N = \sum_{k=1}^{n(n-1)/2} 36^{k-1} + 7 = O(6^{n^2}). N=k=1n(n1)/236k1+7=O(6n2).
每个节点判断可行性的时间为 O ( n 2 ) O(n^2) O(n2). 因此算法的时间复杂度为 O ( 6 n 2 ⋅ n 2 ) O(6^{n^2}\cdot n^2) O(6n2n2).


公众号:生活研究生(mo_hulage)

  • 11
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值