我正在尝试制作一个能够解决平铺问题中的大型tileset的算法。现在,它能够根据宽度和高度找到正确的瓷砖,但是在正确递归方面存在一些问题。
正如您所看到的那样,想法是在放置的每个瓷砖之后,该字段将在Field Right和Field Below中分开。该算法将首先尝试填充Field Right,并且一旦完成,它必须开始尝试填充Field Below。
我遇到的问题是,一旦Field Right得到解决,就必须以某种方式“回送”(我认为使用递归,虽然这很复杂)让它回到Tile并转到Field下面属于那个瓷砖。我把这个想法放在一些伪代码中让它更容易理解。
正如您所看到的,当FieldRightWidth被解决并且FieldBelowHeight也被解决时,我想让它返回到前一个tile以检查FieldBelow是否已解决。我认为这是我需要放置一些代码才能完成这项工作的地方,但经过数小时的谷歌搜索我仍然没有任何线索。
伪代码:
def Methods:
create global tileset
create local tileset (without duplicates)
If globaltiles is empty:
solved
end
else:
if fieldRightWidth == solved:
if fieldBelowHeight == solved:
return True???
#FIELD BELOW
else:
Search for Tile
Place Tile
Return Methods
#FIELD RIGHT
else:
Search for Tile
Place Tile
Return Methods
所有代码: http://pastebin.com/8t4PeiZP
http://www.filedropper.com/tilingnew
我仍然是编码的新手,所以非常感谢任何建议或帮助!
答案 0 :(得分:2)
好吧,我们认为你想要计算的区域是方形或矩形,(不是旋转的),它从最小[x,y]开始,最大结束[x,y],如下所示:
SMaxX = 5
SMinX = 0
SMaxY = 5
SMinY = 0
或者如果您熟悉2D矢量,您可以像这样优化它:
S = [5,5]
你可能知道2D矢量,以防我在2D笛卡尔坐标中解释什么是矢量:
S = [5,5]
表示如果S
从[0,0]
开始,则会以[5,5]
结束,(更简单吧?)
所以盒子也会如此:
#space each box taking
box1 = [3,3]
box2 = [2,2]
box3 = [1,1]
由于每个盒子都有优先权,让我们说:
#priority of each box
box1 = 6
box2 = 4
box3 = 2
我们可以将空格和优先级合并到字典中,如下所示:
#Items
dic = {'box1':{'space':[3,3] , 'priority ':6},
'box2':{'space':[2,2] , 'priority ':4},
'box3':{'space':[1,1] , 'priority ':2}}
具有每个框的优先级和空格,看起来像背包问题算法 如果您熟悉背包问题算法,我们会在表格中找到最优先填充空间的优先级,或者换句话说,最好的方式是拟合框。检查此link1和link2。
然而背包问题算法的图表是1D解决方案,如果你这样做,你将得到10,所以Box1和Box2。但由于它是2D并且你有不同的高度和宽度,所以标准的1D公式不会起作用,也许你需要查看它,看看你是否可以提出2D公式或询问周围是否有人这样做过。
除了背包问题算法之外,你可以尝试洪水填充算法,如果你有很大的区域,这有点慢,但它的运作方式就像俄罗斯方块游戏一样。
您需要设置标准大小,如1x1,然后用1x1数据定义整个区域,并将其存储在变量中并设置每个True(布尔值),然后使用更高优先级的框填充区域并设置这些1x1日期 False ,然后非常简单,你可以检查它们中有多少 True 以及它们正在采取什么领域。
无论如何,我试图找出不规则形状的同样的东西,所以我发现了所有这些,希望能帮助你。
(检查这个link,我得到了一些有用的答案。)
编辑:好吧,如果您使用俄罗斯方块想法在一个轴上定义区域和背包问题算法,然后基于标准俄罗斯方块区域,在其他轴上再次使用背包问题算法应该可以正常工作。