八皇后问题(回溯算法的Python代码)

八皇后问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。

一言以蔽之:就是在递归回溯的过程中实现条件过滤,最后得到想要的结果;

代码一:

"""
八皇后问题:
回溯算法
"""
# 设置棋盘的大小规模
max_coordinate = 8
# 构建数据结构
# 初始化坐标列表,
# 列表的value为纵坐标值(即棋盘上行数的标记值),
# 列表的index为横坐标值(即棋盘列数标记值)
queen_list = [None]*8


def show():
    column = 0
    # 对列进行遍历,打印坐标
    while column < max_coordinate:
        print("(%d, %d)" % (column, queen_list[column]), end=" ")
        column += 1
    print("")


# 对第棋盘上第column列的情况进行检查,看看是否能够放置皇后
def check(column):
    column_2 = 0
    # 对比column小的列进行遍历
    while column_2 < column:
        # 如果比column小的列中有和column对应的queen_list的值相等(即在同一行),
        # 或者有二者的行标记之差的绝对值等于列标记之差的情况(即在其对角线上),
        # 则不能放置该皇后
        if (queen_list[column_2] == queen_list[column]) or (abs(queen_list[column_2] - queen_list[column]) == column - column_2):
            return False
        column_2 += 1
    # 否则,可以放置该皇后
    return True


# 回溯算法的递归函数主体
# 传入一个初始的横坐标值(即对应棋盘上的列数的标记值)
def put_queen(column):
    row = 0
    # 
    # 对棋盘的行进行遍历:0~7行
    while row < max_coordinate:
        # 假设该皇后可以放置在棋盘的第row行,第column列上
        queen_list[column] = row
        # 对第棋盘的column列进行检查,如果满足条件则进行下一列的放置
        if check(column):
            # 如果已至最后一列,则调用显示方法,打印结果,跳出递归
            if column == max_coordinate - 1:
                show()
            else:
                # 如果未至最后一列,则递归调用自身,实现在下一列中放置另一个皇后
                put_queen(column + 1)
        row += 1


def main():
    put_queen(0)
    print("="*10)


if __name__ == '__main__':
    main()

代码二:
"""
八皇后问题
递归回溯算法
"""

def queen(queen_list, current_column=0):
    
    for row in range(len(queen_list)):
        # 如果已至最后一列,则打印结果,跳出递归
        if current_column == len(queen_list):
            for i in range(len(queen_list)):
                print("(%d, %d)" % (i, queen_list[i]), end=" ")
            print("")
            return 

        # 假设当前列能够放置一个皇后,用queen_list的index记录列标,value记录行标
        # flag为可行性的标记
        queen_list[current_column],flag = row,True
        # 对当前列之前的各列进行遍历
        for column in range(current_column):
            # 排除同行及对角线上的位置,将flag设置为False
            if (queen_list[column] == row) or (abs(row - queen_list[column]) == current_column - column):
                flag = False
                # 只要有一个不满足的条件,就跳出遍历
                break
        # 如果可以放置,则递归调用自身,对下一列进行筛选
        if flag:
            queen(queen_list, current_column + 1)

queen([None]*8)


你可能感兴趣的:(Python)