数据结构与算法--回溯算法:马踏棋盘算法(骑士周游)Python实现马踏棋盘算法 一步步带你用Python实现马踏棋盘算法

基本概述

  • 概念:
    在这里插入图片描述
    在这里插入图片描述
  • 算法解析:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

Python实现

未优化前

# 马踏棋盘算法

class HorseChessBoard(object):
    def __init__(self, size):
        self.X = size  # 棋盘的列数
        self.Y = size  # 棋盘的行数
        # 创建一个二维数组,用于记录每一步所走的位置
        self.chess_board = [[0 for col in range(size)] for row in range(size)]
        # 创建一个数组,标记棋盘的各个位置是否被访问过,boolean,默认都是False
        self.visited = [[False for col in range(size)] for row in range(size)]
        # 是否完成游戏标志
        self.finished = False

    def travel_chess_board(self, row: int, col: int, step: int):
        """
        :param chess_board: 传入棋盘
        :param row: 马儿当前的位置行 第几行,从0开始(x)
        :param col: 马儿当前的位置列 第几列,从0开始(y)
        :param step: 是第几步,初始位置是第1步
        :return:
        """
        self.chess_board[row][col] = step
        # 标记该位置已经访问
        self.visited[row][col] = True
        # 获取当前位置可以走的下一个位置的集合
        next_step = self.get_next(row, col)
        # 遍历 next_step
        for p in next_step:  # 取出下一个可以走的位置
            if not self.visited[p[0]][p[1]]:  # 判断该点是否已经访问过
                self.travel_chess_board(p[0], p[1], step + 1)
        # 判断马儿是否完成了任务,使用 step 和 应该走的步数比较
        # 如果没有达到数量,则表示没有完成任务,将整个棋盘置为0
        # 说明:棋盘到目前位置仍然没有走完,处于回溯状态
        if (step < self.X * self.Y) & (not self.finished):  # 如果已经无路可走但仍未结束,或者处于回溯过程中
            self.chess_board[row][col] = 0
            self.visited[row][col] = False
        else:  # 已经完成游戏
            self.finished = True

    def get_next(self, x, y):
        """
        返回当前位置的下一步所有可走位置集合
        :return: res
        """
        res = []
        # 表示走6 的位置
        if (x - 1 >= 0) & (y - 2 >= 0):
            res.append([x - 1, y - 2])
        # 表示走5 的位置
        if (x - 2 >= 0) & (y - 1 >= 0):
            res.append([x - 2, y - 1])
        # 表示走7 的位置
        if (x + 1 < self.X) & (y - 2 >= 0):
            res.append([x + 1, y - 2])
        # 表示走0 的位置
        if (x + 2 < self.X) & (y - 1 >= 0):
            res.append([x + 2, y - 1])
        # 表示走4 的位置
        if (x - 2 >= 0) & (y + 1 < self.Y):
            res.append([x - 2, y + 1])
        # 表示走3 的位置
        if (x - 1 >= 0) & (y + 2 < self.Y):
            res.append([x - 1, y + 2])
        # 表示走1 的位置
        if (x + 2 < self.X) & (y + 1 < self.Y):
            res.append([x + 2, y + 1])
        # 表示走2 的位置
        if (x + 1 < self.X) & (y + 2 < self.Y):
            res.append([x + 1, y + 2])

        return res


if __name__ == '__main__':
    game = HorseChessBoard(6)
    game.travel_chess_board(3, 2, 1)
    # 输出棋盘的最后情况
    for rows in game.chess_board:
        for steps in rows:
            print(steps, end=" ")
        print()
'''输出结果
8 3 6 29 32 21 
5 28 9 22 15 30 
2 7 4 31 20 33 
27 10 1 16 23 14 
36 17 12 25 34 19 
11 26 35 18 13 24 
'''
  • 用游戏来验证一下结果:

    在这里插入图片描述
    在这里插入图片描述
    发现完成正确哦~接下来就是进行优化!

贪心算分优化

# 马踏棋盘算法

class HorseChessBoard(object):
    def __init__(self, size):
        self.X = size  # 棋盘的列数
        self.Y = size  # 棋盘的行数
        # 创建一个二维数组,用于记录每一步所走的位置
        self.chess_board = [[0 for col in range(size)] for row in range(size)]
        # 创建一个数组,标记棋盘的各个位置是否被访问过,boolean,默认都是False
        self.visited = [[False for col in range(size)] for row in range(size)]
        # 是否完成游戏标志
        self.finished = False

    def travel_chess_board(self, row: int, col: int, step: int):
        """
        :param chess_board: 传入棋盘
        :param row: 马儿当前的位置行 第几行,从0开始(x)
        :param col: 马儿当前的位置列 第几列,从0开始(y)
        :param step: 是第几步,初始位置是第1步
        :return:
        """
        self.chess_board[row][col] = step
        # 标记该位置已经访问
        self.visited[row][col] = True
        # 获取当前位置可以走的下一个位置的集合
        next_step = self.get_next(row, col)
        # 通过贪心算法进行优化,按照下一步的所有可走位置的数量进行非递减排序(升序)
        next_step.sort(key=lambda x: len(self.get_next(x[0], x[1])))
        # 遍历 next_step
        for p in next_step:  # 取出下一个可以走的位置
            if not self.visited[p[0]][p[1]]:  # 判断该点是否已经访问过
                self.travel_chess_board(p[0], p[1], step + 1)
        # 判断马儿是否完成了任务,使用 step 和 应该走的步数比较
        # 如果没有达到数量,则表示没有完成任务,将整个棋盘置为0
        # 说明:棋盘到目前位置仍然没有走完,处于回溯状态
        if (step < self.X * self.Y) & (not self.finished):  # 如果已经无路可走但仍未结束,或者处于回溯过程中
            self.chess_board[row][col] = 0
            self.visited[row][col] = False
        else:  # 已经完成游戏
            self.finished = True

    def get_next(self, x, y):
        """
        返回当前位置的下一步所有可走位置集合
        :return: res
        """
        res = []
        # 表示走6 的位置
        if (x - 1 >= 0) & (y - 2 >= 0):
            res.append([x - 1, y - 2])
        # 表示走5 的位置
        if (x - 2 >= 0) & (y - 1 >= 0):
            res.append([x - 2, y - 1])
        # 表示走7 的位置
        if (x + 1 < self.X) & (y - 2 >= 0):
            res.append([x + 1, y - 2])
        # 表示走0 的位置
        if (x + 2 < self.X) & (y - 1 >= 0):
            res.append([x + 2, y - 1])
        # 表示走4 的位置
        if (x - 2 >= 0) & (y + 1 < self.Y):
            res.append([x - 2, y + 1])
        # 表示走3 的位置
        if (x - 1 >= 0) & (y + 2 < self.Y):
            res.append([x - 1, y + 2])
        # 表示走1 的位置
        if (x + 2 < self.X) & (y + 1 < self.Y):
            res.append([x + 2, y + 1])
        # 表示走2 的位置
        if (x + 1 < self.X) & (y + 2 < self.Y):
            res.append([x + 1, y + 2])

        return res


if __name__ == '__main__':
    game = HorseChessBoard(8)
    game.travel_chess_board(1, 2, 1)
    # 输出棋盘的最后情况
    for rows in game.chess_board:
        for steps in rows:
            print(steps, end=" ")
        print()
发布了146 篇原创文章 · 获赞 37 · 访问量 7841

猜你喜欢

转载自blog.csdn.net/storyfull/article/details/104015020