簡體   English   中英

將N長方體划分為M個體積的較小長方體

[英]Dividing a cuboid of N into smaller cuboids of M volume

我有一個奇怪的具體問題:

什么是最有效的方法(導致最小數量的長方體)將任何大小的長方體(具有整數尺寸)划分為體積為4096或更小的長方體(具有整數尺寸)?

例如,給定234x45x322的面積,將它分成長方體的最有效方法是什么? 我應該制作盡可能多的16 ^ 3長方體,然后二元搜索其余的尺寸? 我應該嘗試將其划分為大小均勻的矩形嗎?

(我將在Lua中實現這一點,但這對解決方案來說並不是那么重要)

上限

當考慮具有寬度A,深度B和高度C的矩形框時,填充框所需的最大體積4096的長方體數的上限是:

roundUp(A / 16)×roundUp(B / 16)×roundUp(C / 16)

無論您使用16×16×16立方體填充大部分矩形框和末端較小的長方體,還是將兩側分成相等的長度,您將永遠不需要超過這個長方體的數量。

使用16×16×16立方體

使用與矩形盒子一樣多的16×16×16立方體,然后在體積的其余部分使用較小的長方體,但不能保證最佳效果。 考慮例如這個例子:

盒子尺寸:43×38×35
最佳解決方案:14個長方體,尺寸為43×19×5

如果您開始用8個尺寸為16×16×16的立方體填充矩形框,則剩余的體積由以下部分組成:

slab XY: 32 x 32 x  3  (4096 x 0.75)  
slab YZ: 32 x 32 x 11  (4096 x 2.75)  
slab ZX: 32 x 32 x  6  (4096 x 1.5)  
beam X:  32 x  6 x  3  (4096 x 0.140625)  
beam Y:  32 x  3 x 11  (4096 x 0.2578125)  
beam Z:  32 x  6 x 11  (4096 x 0.515625)  
corner:   6 x  3 x 11  (4096 x 0.04833984375)  

您可以將板與其兩個相鄰梁之一組合以創建更大的板,或者將板與兩個梁和角部組合以形成占據原始長方體的整個側面的板,或者將角與其中一個組合。光束可以產生更長的光束,但這些選項都不會產生這樣的情況,即您可以將剩余的體積分成僅6個長方體。

立方體,板,梁和角落

(用於解釋術語的圖像;不使用任何數值示例的大小)

但是,有幾種方法可以將剩余的體積分成7個部分,因此整體解決方案是15而不是14,這可能足以作為近乎最優的解決方案。

基於這種方法的算法要求您考慮7個剩余部分可以組合的不同方式,並找出哪個可以分成最小的長方體; 這意味着計算一側小於16的長方體的最佳分裂,這意味着它可以被視為2D問題,這更容易解決。

應該注意的是,即使剩余部件的總體積小於4096,由於其3D L形,您將始終需要3個長方體來填充它。

等長的立方體

一種簡單的方法是通過嘗試每種可能的組合來找到具有相等大小的立方體的解的最佳尺寸。 由於長方體的體積限制為4096,因此只需考慮34,720種不同的尺寸和方向。

下面的代碼示例在1634次迭代后找到43×38×35示例的最優解,並在30,183次迭代后找到999×9999×99999的解。 如上所述,它永遠不需要超過34,720次迭代,這使得即使在JavaScript中也非常快。

 function boxCutter(a, b, c) { var min = Math.ceil(a / 16) * Math.ceil(b / 16) * Math.ceil(c / 16); var solution = {x: 16, y: 16, z: 16, vol: 4096, num: min}; for (var x = 1; x <= a && x <= 4096; x++) { for (var y = 1; y <= b && y <= 4096 / x; y++) { var z = Math.floor(4096 / (x * y)); var num = Math.ceil(a / x) * Math.ceil(b / y) * Math.ceil(c / z); if (num < min) { min = num; solution = {x: x, y: y, z: z, vol: x * y * z, num: min}; } } } return solution; } document.write(JSON.stringify(boxCutter(43, 38, 35)) + "<br>"); document.write(JSON.stringify(boxCutter(999, 9999, 99999)) + "<br>"); 

結合方法

如果長方體的尺寸不能均勻地划分矩形框,那么通過再次運行最后一層截斷長方體的算法可以獲得小的改進,並且用不同尺寸的長方體填充該部分,類似於第二階段16×16×16立方體方法。

在999×9999×99999長方形盒子的例子中,在9×5×91的243,978,000個長方體中,有一個頂層222,000個長方體,其高度被截斷為81,以及一層121,989個長方體,其深度被截斷為4.用不同尺寸的長方體填充這些層中的一個,使長方體的數量分別減少24,198和24,309,或約占總長度的0.1%。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM