我有这块瓷砖,宽36英尺36英寸,高。
所以我有块8x8,6x6,6x8,4x8可以旋转90度以适应任何可能的地方。 我的任务是制作应用程序来计算应该选择哪个和多少个块,以便所有块一起适合给定的墙壁oppening。在这个例子中,操作36 x 36。
注意:oppening应尽可能少地填充,这意味着更大的tile具有优先级
我应该使用哪种算法进行磁贴放置?
另一个例子。 Field 30 x 30绘制如下:
50 x 50
答案 0 :(得分:1)
由于amit给了general case answer,我将特别提到这一点。使用这四个块大小,并假设它甚至可能(维度均匀且> = 6等),您可以使用半贪心算法:
第一个目标是最大化8x8块的数量。要做到这一点,您需要确定每个方向需要多少6
个大小的块。对于每个维度,只需检查8的可除性。如果它不可分,则减去6.重复直到可以整除(它不应超过3次尝试)。
无论多少次,在这个维度上你需要6x6块。从它们中形成一个矩形并将其放在一个角落里。从8x8块中形成另一个矩形,并将它们放在对角。这两个矩形的角应该是触摸的。
所以现在你可能有一些剩余的空间,在对角的两个矩形的形式。我们知道每个维度的一个维度可以被8整除,一个维度可以被6整除。这里的简单方法是用适当的6x8块填充它,但这不会保证最大数量的大(8x8)块。例如,对于50x50,您将有两个18x32的矩形。你可以用12个6x8瓷砖填充它们。你甚至不能做优于每个12块,但你可以在那里适应更多的8x8块。
如果这不是一个问题,那么你已经完成了(万岁)。这种方式的好处是你永远不需要使用4x8块。
如果你做想要最大化8x8块,你将不得不采取另一个步骤。我们在这里专注于可被6整除的维度,因为8很容易。我们可能需要的每个尺寸(8x8,6x8,4x8)完美地堆叠在那里。
另一方面,它只有3个可能的数字:6,12和18.如果是其他任何东西,第一步没有做好。然后采取以下行动:
完成!
要看到差异,我们这里有两个50x50网格:
Blue - 8x8
Red - 6x6
Green - 6x8
Gray - 4x8
这个第一个例子给了我们49个总积木。蓝色是32x32区域(16个区块),红色是18x18(9个区块),其余的只是填充6x8(24个区块)。
此示例仍然总共提供了49个,但还有更多的8x8块。这里我们有24个大块,而不是最后一个例子中的16个。现在还使用了4x8块。
答案 1 :(得分:1)
在这里,你用Python:
def aux(x):
# in h we store the pre-calculated results for small dimensions
h = {18:[6,6,6], 16:[8,8], 14:[8,6], 12:[6,6], 10:[6,4], 8:[8], 6:[6], 4:[4]}
res = []
while x > 18:
# as long as the remaining space is large, we put there tiles of size 8
res.append(8)
x -= 8
if x not in h:
print("no solution found")
return []
return res + h[x]
def tiles( x, y ):
ax = aux(x) # split the x-dimension into tiles
ay = aux(y) # split the y-dimension into tiles
res = [ [ (x,y) for x in ax ] for y in ay ]
for u in res:
print(u)
return res
tiles( 30, 30 )
基本思想是你可以独立解决x和y,然后将两种解决方案结合起来。
编辑:正如Dukeling所说,这段代码很乐意使用4x6和4x4块,这与要求相反。但是,我认为只有在没有其他办法的情况下才会这样做。因此,如果结果包含这样的块,那么没有这些块就没有解决方案。如果您没有现成的Python,可以在此处使用此代码:http://ideone.com/HHB7F8,只需在源代码上方按 fork 即可。
答案 2 :(得分:0)
假设您正在寻找一般案例答案,我很遗憾地说 - 但这个问题是NP-Complete。它基本上是Subset Sum Problem的二维变体。
子集求和问题:给定一组S
和一个数字x
- 找出是否有S
的子集加到x
。
很容易看出,通过将子集和问题减少到大小为1*x
的“字段”以及s
中的每个S
,我们都有一个图块1*s
- 解决一个问题也是另一个问题的解决方案。
因此 - 对这个问题没有已知的多项式解,并且大多数人认为不存在。
但请注意,这里也可以使用pseudo-polynomial dynamic programming solution to subset sum。