具有矩形的正方形的特定平铺

时间:2013-06-10 13:37:44

标签: algorithm

假设我们有一个边长为S的正方形,以及长度为X且宽度为Y的矩形图块的N个副本。程序必须显示这些副本可以在网格中排列的所有方式,以便没有两个副本可以互相接触

通过显示,我的意思是它必须显示网格中每个副本左上角的坐标集。

我尝试按以下方式进行:

  1. 找到一个基本案例,我尝试将每个副本放置为1平方分隔。 例如,对于6x6网格上的1x2图块的6个副本,基本情况为

    xx_xx_
    ______
    xx_xx_
    ______
    xx_xx_
    ______
    
  2. 将最后一个图块移动到可能的位置。

  3. 将最后一个图块返回到基本案例,将最后一个图块移动到可能的位置。重复步骤2.

  4. 为每个瓷砖做回来。

  5. 基本上问题是我找不到行数或列数差异为1但不相互接触的情况。例如,我找不到这种情况:

    xx____  This tile
    ___xx_  and this one has a difference in row numbers 1.
    xx____
    ___xx_
    xx____
    ___xx_
    
    你能说点什么吗?或者可能是更有效的算法?

    注意:我尝试在Prolog中实现它。

2 个答案:

答案 0 :(得分:3)

你会发现这个问题适合于约束编程(这与你试图使用的Prolog相差不远):

  • 给出S,
  • 你想要一组A = {(x,y)},其中x elem {1..S}和y elem {1..S},x和y表示你的瓷砖的左上角,< / LI>
  • 使得对于所有(x,y)(x + 1,y)不在A中并且(x + 2,y)不在A中并且(x + 3,y)不在A和(x)中,y + 1)不在A ...更多约束,这意味着如果你在(x,y)上有一个瓦片,则没有瓦片'开始'(x + 1,y)或(x + 2,y)或(x + 3,y)即它们不重叠且不接触。

美丽的是,通过上面你声明性地指定了问题,然后你最喜欢的约束求解器(我去GECODE)去找你所有的解决方案。如果您的规格不完整,您会得到以意想不到的方式触摸或重叠的瓷砖,您可以修改规格而不必重新发明轮子。这将适用于相当大的问题实例...当你可以添加巧妙的修剪搜索树的方法时,你只需要开始发明聪明的算法,如果你需要大量的S工资。

答案 1 :(得分:0)

每次填充特定行时,可以对上一行使用位掩码。例如:

如果前一行如下:

XX----

然后有一个像110000这样的位掩码。要填充下一行,请注意你不要使用位掩码中有1的位置。

所以你可以这样做:

for(int i=0;i<(1<<S);i++)
 if(i & bitmask)
 {
 //can't place tile in this fashion as few tiles of previous row touch this row's tiles
 continue;
 }
 else
 {
 //No conflicts between rows, but with in this row there could be touching tiles as in 111100
 //Use a for loop to check if the given row has no two tiles touching
 //Check if each string of 1's is of length X
 //If all is well recursively call this function to fill the next row using i as the bitmask
 }

我会让你弄清楚实际的实施情况。

相关问题