Python中n-queen拼图的2个解决方案的区别

时间:2017-03-11 14:04:57

标签: python n-queens

对于n-queen问题,我有两个看似相同的解决方案。两者都产生完全相同的结果(我在网上找到了),但第二个产生的时间是第一个产生的时间的两倍多。你能帮我解释一下,区别在哪里?

from itertools import permutations
import time

punkt1 = time.time()
N=8
sol=0
cols = range(N)
for combo in permutations(cols):                      
    if N==len(set(combo[i]+i for i in cols))==len(set(combo[i]-i for i in cols)):
        sol += 1
        print('Solution '+str(sol)+' : '+str(combo)+'\n')  
        #print("\n".join(' o ' * i + ' X ' + ' o ' * (N-i-1) for i in combo) + "\n\n\n\n")
punkt2 = time.time()
czas = punkt2 - punkt1




###################################
def queensproblem(rows, columns):
    solutions = [[]]
    for row in range(rows):
        solutions = add_one_queen(row, columns, solutions)
    return solutions

def add_one_queen(new_row, columns, prev_solutions):
    return [solution + [new_column]
            for solution in prev_solutions
            for new_column in range(columns)
            if no_conflict(new_row, new_column, solution)]

def no_conflict(new_row, new_column, solution):
    return all(solution[row]       != new_column           and
               solution[row] + row != new_column + new_row and
               solution[row] - row != new_column - new_row
               for row in range(new_row))
punkt3 = time.time()
i = 1

for solution in queensproblem(8, 8):
    print('Solution', i,':', solution, '\n')
    i = i + 1

punkt4 = time.time()
czas2 = punkt4 - punkt3
print ("Czas wykonania pierwszej metody:")
print (czas,'\n')
print ("Czas wykonania drugiej metody:")
print (czas2)

1 个答案:

答案 0 :(得分:2)

乍一看,您似乎在说这些算法会产生相同的结果,并且在时间上会因常数因素而不同,这在谈论算法时无关紧要。

但是,如果你将N作为一个函数参数并检查N = 9或N = 10的时间,你会看到它们显着不同。在N = 11时,itertools.permutations版本需要12分钟,相比之下其他28秒。如果它们以不同的速率增长,它就会成为算法问题。

在排列中调用" for combo的函数"从字面上看每个可能的棋盘,所以你可以连续排队三个皇后,它仍然认为"我必须继续添加皇后,看看它是否有效"。 (这可以用符号表示每个可能的板。符号本身消除了很多,但还不够。)

另一个功能是能够停止检查不良组合,从而立即消除许多不良候选人。查看N = 4的决策树的打印输出,通过在queensproblem for循环中添加print(行,解决方案)生成:

0 [[0], [1], [2], [3]]
1 [[0, 2], [0, 3], [1, 3], [2, 0], [3, 0], [3, 1]]
2 [[0, 3, 1], [1, 3, 0], [2, 0, 3], [3, 0, 2]]
3 [[1, 3, 0, 2], [2, 0, 3, 1]]

在逻辑的早期,它看了[0,0]和[0,1]并简单地消除了它们。因此它从未看过[0,0,0]或......许多其他人。它继续仅为通过早期检查的解决方案添加新的皇后。由于" all"和"和"。