首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解决n皇后难题

解决n皇后难题
EN

Stack Overflow用户
提问于 2011-01-27 23:20:53
回答 6查看 12.5K关注 0票数 4

我刚刚解决了python中的nqueen问题。该解决方案输出了将n个皇后放置在nXn棋盘上的解决方案的总数,但使用n=15尝试需要一个多小时才能得到答案。有没有人可以看一下代码,给我一些加速这个程序的提示……一个python程序员新手。

代码语言:javascript
复制
#!/usr/bin/env python2.7

##############################################################################
# a script to solve the n queen problem in which n queens are to be placed on
# an nxn chess board in a way that none of the n queens is in check by any other
#queen using backtracking'''
##############################################################################
import sys
import time
import array

solution_count = 0

def queen(current_row, num_row, solution_list):
    if current_row == num_row:
        global solution_count 
        solution_count = solution_count + 1
    else:
        current_row += 1
        next_moves = gen_nextpos(current_row, solution_list, num_row + 1)
        if next_moves:
            for move in next_moves:
                '''make a move on first legal move of next moves'''
                solution_list[current_row] = move
                queen(current_row, num_row, solution_list)
                '''undo move made'''
                solution_list[current_row] = 0
        else:
            return None

def gen_nextpos(a_row, solution_list, arr_size):
    '''function that takes a chess row number, a list of partially completed 
    placements and the number of rows of the chessboard. It returns a list of
    columns in the row which are not under attack from any previously placed
    queen.
    '''
    cand_moves = []
    '''check for each column of a_row which is not in check from a previously
    placed queen'''
    for column in range(1, arr_size):
        under_attack =  False
        for row in range(1, a_row):
            '''
            solution_list holds the column index for each row of which a 
            queen has been placed  and using the fact that the slope of 
            diagonals to which a previously placed queen can get to is 1 and
            that the vertical positions to which a queen can get to have same 
            column index, a position is checked for any threating queen
            '''
            if (abs(a_row - row) == abs(column - solution_list[row]) 
                    or solution_list[row] == column):
                under_attack = True
                break
        if not under_attack:
            cand_moves.append(column)
    return cand_moves

def main():
    '''
    main is the application which sets up the program for running. It takes an 
    integer input,N, from the user representing the size of the chessboard and 
    passes as input,0, N representing the chess board size and a solution list to
    hold solutions as they are created.It outputs the number of ways N queens
    can be placed on a board of size NxN.
    '''
    #board_size =  [int(x) for x in sys.stdin.readline().split()]
    board_size = [15]
    board_size = board_size[0]
    solution_list = array.array('i', [0]* (board_size + 1))
    #solution_list =  [0]* (board_size + 1)
    queen(0, board_size, solution_list)
    print(solution_count)


if __name__ == '__main__':
    start_time = time.time()
    main()
    print(time.time() 
EN

回答 6

Stack Overflow用户

发布于 2011-01-28 00:06:32

N-Queens问题的回溯算法在最坏的情况下是阶乘算法。所以对于N=8来说,8!在最坏的情况下检查解决方案的数量,N=9将其设置为9!,等等。可以看到,可能的解决方案的数量增长非常大,非常快。如果你不相信我,就去计算器那里,从1开始乘以连续的数字,告诉我计算器耗尽内存的速度有多快。

幸运的是,并不是所有可能的解决方案都必须检查。不幸的是,正确解决方案的数量仍然遵循大致的阶乘增长模式。因此,算法的运行时间以阶乘速度增长。

由于您需要找到所有正确的解决方案,因此在加速程序方面真的无能为力。在修剪搜索树中不可能的分支方面,您已经做得很好了。我不认为还有什么会产生重大影响。这只是一个很慢的算法。

票数 5
EN

Stack Overflow用户

发布于 2011-01-28 00:33:29

可以使用Donald Knuth的随机估计方法来估计解决方案的数量。

从没有放置的皇后开始,下一行的允许位置数为n。随机选择一个位置,计算下一行的允许位置数(p),乘以n,并将其存储为解的总数(total =n* p),然后随机选择一个允许位置。

对于此行,计算下一行的允许位置数(p),并将总解数乘以此( *=,p)。重复此操作,直到无法求解棋盘,在这种情况下,解数等于零,或者直到棋盘解出。

重复多次并计算平均解的数量(包括任何零)。这应该会给你一个快速和相当准确的近似解的数量,随着你运行的次数越多,近似值越高。

我希望这是有意义的;)

票数 2
EN

Stack Overflow用户

发布于 2011-02-21 21:31:48

我建议您查看Python源代码中的test_generators.py,以获得N-Queens问题的另一种实现。

代码语言:javascript
复制
Python 2.6.5 (release26-maint, Sep 12 2010, 21:32:47) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from test import test_generators as tg
>>> n= tg.Queens(15)
>>> s= n.solve()
>>> next(s)
[0, 2, 4, 1, 9, 11, 13, 3, 12, 8, 5, 14, 6, 10, 7]
>>> next(s)
[0, 2, 4, 6, 8, 13, 11, 1, 14, 7, 5, 3, 9, 12, 10]
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4818201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档