用回溯法解决三元组拼图的Python算法

时间:2014-05-19 20:48:03

标签: python recursion puzzle backtracking recursive-backtracking

我们说我有这样的董事会

. . x . . .
. . . . . .
. . x . . x

x用于框和'。'免费的。我需要用三聚体填充所有区域,因此不会有自由细胞。 Triomines是L形的,我用相同的数字标记相同的triomino。

所以解决方案可能是这样的:

1 1 x 3 5 5
1 2 3 3 4 5
2 2 x 4 4 x

可能的回溯python算法是什么?

1 个答案:

答案 0 :(得分:1)

算法非常简单,首先我们得到这个板配置中可用单元的列表,基本上,列出所有可能的单元减去禁用的单元。

然后我们通过迭代可用的单元格列表并尝试将三角形块放入这个特定的单元格位置,使用4种可能的方向(可用单元格是角落,我们因旋转而有4个方向)来制作解决方案步骤。 / p>

如果该部件适合,增加步骤,从列表中删除占用的单元并再次尝试解决,直到没有可用的单元 - 这意味着整个板都被覆盖。

#!/usr/bin/env python

solution = {}

orientations = [(1,1),(1,-1),(-1,1),(-1,-1)]    # 4 possible orientations

def solve( avl, step ) :
    if not len(avl) :
        print 'done!'
        return True

    for i,j in avl :
        for oi,oj in orientations :
            if (i+oi,j) in avl and (i,j+oj) in avl :
                occupied = [(i,j),(i+oi,j),(i,j+oj)]
                # remove occupied from available, increase step and keep solving
                if solve( [a for a in avl if a not in occupied], step + 1 ) :
                    for occ in occupied :
                        solution[occ] = step
                    return True

# initial conditions for this configuration
#
# . . x . . .
# . . . . . .
# . . x . . x

X_SIZE, Y_SIZE = 6, 3
forbidden_cells = [(0,2),(2,2),(2,5)]

if __name__ == '__main__' :
    available = []

    # fill the available cells list
    for i in range(Y_SIZE) :
        for j in range(X_SIZE) :
            if (i,j) not in forbidden_cells :
                available.append( (i,j) )

    # print the original problem
    for i in range(Y_SIZE) :
        for j in range(X_SIZE) :
            print '.' if (i,j) in available else 'x',
        print

    # solve away!
    if solve( available, 1 ) :
        for i in range(Y_SIZE) :
            for j in range(X_SIZE) :
                print solution[(i,j)] if (i,j) in available else 'x',
            print
    else :
        print 'sorry, no solution found'

输出结果为:

$ ./triomines.py 
. . x . . .
. . . . . .
. . x . . x
done!
1 1 x 3 2 2
1 4 3 3 5 2
4 4 x 5 5 x
$