Algorithm 不重复的盒子堆叠

Algorithm 不重复的盒子堆叠,algorithm,dynamic-programming,np,Algorithm,Dynamic Programming,Np,您将获得一组n种类型的矩形三维长方体,其中第i个长方体具有高度h(i)、宽度w(i)和深度D(i)(所有实数)。您希望创建一个尽可能高的长方体堆栈,但如果下部长方体的二维基座尺寸严格大于较高长方体的二维基座尺寸,则只能将长方体堆栈在另一个长方体的顶部。当然,您可以旋转一个长方体,使任何一侧都可以作为其基础。不允许在一个长方体上使用多个实例 这个问题是在SO()上提出的,但没有“不重复”的限制如何使用LIS解决此问题。 我想出了以下解决办法,可以讨论吗 H[j] = max(H[j],max(H[

您将获得一组n种类型的矩形三维长方体,其中第i个长方体具有高度h(i)、宽度w(i)和深度D(i)(所有实数)。您希望创建一个尽可能高的长方体堆栈,但如果下部长方体的二维基座尺寸严格大于较高长方体的二维基座尺寸,则只能将长方体堆栈在另一个长方体的顶部。当然,您可以旋转一个长方体,使任何一侧都可以作为其基础。不允许在一个长方体上使用多个实例

这个问题是在SO()上提出的,但没有“不重复”的限制如何使用LIS解决此问题。

我想出了以下解决办法,可以讨论吗

H[j] = max(H[j],max(H[i]|i<j, D[j] < D[i] , W[j]<W[i]+ H[j] -H[j'] )

H[j]=max(H[j],max(H[i]| i该结果最初是针对2D情况推导的,但仍适用于3D框,如最后所述

如果一个最佳塔中的所有箱子都与它们的长尺寸E-W对齐,这将非常方便

假设有一组盒子,其中有一个最佳塔,需要一些(非零)E-W和N-S所要面向的箱子的数量旋转这样的塔,使得最下面的箱子对齐E-W。现在考虑最低的箱子,I,N-S对齐。显然,箱I的长尺寸小于其支撑箱I-1的最小尺寸;因此箱I的长尺寸小于箱I-1的长尺寸。

同样,由于箱i的短尺寸小于箱i的长尺寸,通过传递性,我们知道箱i的短尺寸小于箱i-1的短尺寸。因此,从箱i向上的整个副塔可以旋转90度以对齐箱i E-W

当我们登上塔楼时,很明显,所有的盒子都可以在任何最佳塔楼中沿东西方向对齐

因此,每个盒子在最佳塔中只有这些可能的“方向”:

  • 高度方向:最长垂直尺寸,第二长E-W方向
  • 面向长度:最长尺寸E-W,第二长尺寸垂直
  • 宽度方向:最长尺寸E-W,第二长尺寸N-S
  • 缺席

您可以在中使用DP解决方案,并通过在每个位置使用大小为n的位图来摆脱“无重复”约束

这听起来确实像是您计划的解决方案,但我并没有完全遵循您的公式或代码

每个长方体的索引在其3次旋转之间是公共的,并且设置了该长方体索引位图中的位,以确保不会处理同一长方体的下一次旋转

for i = 1:n  
  Box b = inputi  
  (h3i  , w3i  , d3i  ) = getRotation1(b)  
  (h3i+1, w3i+1, d3i+1) = getRotation2(b)  
  (h3i+2, w3i+2, d3i+2) = getRotation3(b)  
  index3i = index3i+1 = index3i+2 = i

// sort the 4 fields simultaneously (hi, wi, di, indexi all belong to the same box)
// (easy to do in OOP by storing these 4 in the same object)
sortByAreaDesc(h, w, d, index)

H[0] = 0
bitmap0 = {false}

for j = 1:3n
  H[j] = maxi < j, wi > wj, di > dj { if (bitmapj[ indexi ]) 0 else H[i] } + hj  
  bitmapj = bitmapi from max
  bitmapj[ indexi from max ] = true

return maxj H[j]
对于i=1:n
框b=inputi
(h3i,w3i,d3i)=获取旋转1(b)
(h3i+1,w3i+1,d3i+1)=获取旋转2(b)
(h3i+2,w3i+2,d3i+2)=获取旋转3(b)
index3i=index3i+1=index3i+2=i
//同时对4个字段进行排序(hi、wi、di、indexi都属于同一个框)
//(通过在同一对象中存储这4个,在OOP中很容易做到)
SortByReadEsc(h、w、d、索引)
H[0]=0
位图0={false}
对于j=1:3n
H[j]=maxiwj,di>dj{if(bitmapj[indexi])0否则H[i]}+hj
bitmapj=最大值的bitmapi
bitmapj[indexi from max]=真
返回最大值H[j]

需要O(n2)的时间和空间。

除了LIS的经典维度外,您可能还需要另一个维度来指定框的方向。是的,该维度已存储,否则h[j']你的问题是什么?除了你的公式,我认为最好用文字解释你做什么,因为我们更容易遵循你的想法。我想要一个解决方案,最好是一个LIS。我已经在LIS中实现了,看起来它在所有情况下都不起作用。尽管它通过了我所有的测试用例。我会发布我的cod简言之,这是代码。不要在问题陈述中添加代码,因为这可能会稀释讨论。我要说的是哪个面用作基础(有3种选择),所以我会添加一个维度来指示框的哪个面被使用。我不确定你的答案是如何关联的。@nhahdh:Oops!我正在解决一个更简单的问题。TY。你确定要为I=1:3n开始循环吗?不是应该为j吗?因为框有3个组合,而且数组是根据面积排序的,同时计算h[j],我们如何确保h[j]所属的框未在h[i]中设置?@NandishA是的,只是我这边的一个打字错误。编辑的目的是希望让它的工作原理更加清晰。不,我不认为这会解决问题,它会得到不重复的结果,但我们得到的高度不是最好的!@NandishA请发布一个它不起作用的测试用例。它不适用于某些以前堆栈的情况S被忽略,因为它们包含当前框,但是如果它们中的框的当前类型将被旋转,则它们会给出更高的结果。考虑2D情况,2个框(基,高度):(4,1),(3,2),当尝试添加框的最后方向时(1, 4),你不能,因为你已经获得了次优解(4,1)-(2,3)。