5---------回溯算法

回溯算法又称为试探发

  • 排序问题:

普通方式解决

def solvepermutationbadway(array):
    solution = []
    for i in range(len(array)):
        newsolution1 = solution + [array[i]]
        newarray1 = array[:i] + array[i + 1:]
        for i in range(len(newarray1)):
            newsolution2 = newsolution1 + [newarray1[i]]
            newarray2 = newarray1[:i] + newarray1[i + 1:]
            for i in range(len(newarray2)):
                newsolution3 = newsolution2 + [newarray2[i]]
                newarray3 = newarray2[:i] + newarray2[i + 1:]
                for i in range(len(newarray3)):
                    newsolution4 = newsolution3 + [newarray3[i]]
                    print(newsolution4)


array = ['红', '黄', '蓝', '绿']
solvepermutationbadway(array)

用回溯算法解决:

class Solution():
    def solvepermutation(self, array):
        self.helper([], array)  # 调用helper方法

    def helper(self, solution, array):
        if len(solution) == 0:  # 如果没有剩余排序对象
            print(solution)  # 输出结果
            return  # 返回上一次被调用的地方
        for i in range(len(array)):  # 第一本书的选择
            newsolution = solution + [array[i]]  # 加入书本
            newarray = array[:i] + array[i + 1:]  # 删除书本
            self.helper(newsolution, newarray)  # 寻找剩余对象的排序组合
  • 典型问题的组合
class Solution():
    def solvecombinationbadway(self, array, n):
        solution = []
        for i in range(len(array)):
            solution1 = solution + [array[i]]
            newarray = array[i + 1:]
            for i in range(len(newarray)):
                solution2 = solution1 + [array[i]]
                print(solution2)


Solution().solvecombinationbadway(['数学', '英语', '语文', '计算机'], 2)
# 这是不用回溯的写法,如果N很小,这样写没问题,前提是你知道N是多少,但是,一旦N很大,代码就会变得烦琐。

回溯算法解决:

class Solution():
    def solvecombination(self, array, n):
        self.helper(array, n, [])

    def helper(self, array, n, solution):
        if len(solution) == n:
            print(solution)
            return
        for i in range(len(array)):
            newsolution = solution + [array[i]]
            newarray = array[i + 1:]
            self.helper(newarray, n, newsolution)


Solution().solvecombination(['数学', '英语', '语文', '计算机'], 2)
  • 查找单词问题
class Solution():
    def wordsearch(self, board, word):
        for i in range(len(board)):
            for j in range(len(board[0])):
                if self.helper(board, word, i, j):
                    return True
        return False

    def helper(self, board, current, row, column):  # helper方法(回溯方法)
        if len(current) == 0:
            return True
        if row > 0 and row < len(board) and column > 0 and column < len(board[0]):
            if board[row][column] == current[0]:
                board[row][column] = ' '
                if self.helper(board, current[1:], row - 1, column):  # 上下左右检查剩余字母
                    return True
                if self.helper(board, current[1:], row + 1, column):
                    return True
                if self.helper(board, current[1:], row, column - 1):
                    return True
                if self.helper(board, current[1:], row, column + 1):
                    return True
                board[row][column] = current[0]  # 如果没有在上下左右中找到下一个字母就说明不对把字母填回到盘面中
        return False

  • 八皇后问题
class Solution(object):
    def solveNQueens(self, n):
        self.helper([-1] * n, 0, n)

    def helper(self, columnposition, rowindex, n):  # columnposition用来储存保安位置的数组  rowindex记录当前行数   n为区域大小
        if rowindex == n:
            self.printsolution(columnposition, n)
            return
        for column in range(n):
            columnposition[rowindex] = column  # 下标是行,值是列   假设第rowindex行保安的位置
            if self.isvalid(columnposition, rowindex):  # 如果可行
                self.helper(columnposition, rowindex + 1, n)  # 行+1,继续假设保安的位置

    def isvalid(self, columnposition, rowindex):  # 判断函数
        for i in range(rowindex):  # for i in range(0)没有输出
            if columnposition[i] == columnposition[rowindex]:  # 检查是否同一列
                return False
            elif abs(columnposition[i] - columnposition[rowindex]) == rowindex - i:  # 检查是否在同一斜线上
                return False
        return True

    def printsolution(self, columnposition, n):  # 输出函数
        for row in range(n):  # N行
            line = ' '
            for column in range(n):  # N列
                if columnposition[row] == column:  # 如果是保安的位置
                    line += 'Q'
                else:  # 不是保安的位置
                    line += '.'
            print(line)
        print('\n')


Solution().solveNQueens(8)

  • 解数独
class Solution():
    def solvesudoku(self, board):
        self.helper(board, 0)

    def helper(self, board, index):
        if index >= 81:  # 如果盘面已满
            self.printsolution(board)  # 输出结果
            return  # 返回上一格
        if board[index] == 0:  # 如果是空白的格子
            for i in range(1, 10):  # 填入数字
                if self.isvalid(board, index, i):  # 如果检验正确
                    board[index] = i  # 填入数字
                    self.helper(board, index + 1)  # 继续假设下一个
                    board[index] = 0  # 假设不成立就填回空白
        else:  # 如果当前格已有数
            self.helper(board, index + 1)

    def printsolution(self, board):
        for i in range(0, 81, 9):
            print(board[i:i + 9])

    def isvalid(self, board, index, num):
        row = index // 9
        column = index % 9
        for i in range(index + 9, 81, 9):  # 检查同列下方的格子是否矛盾
            if board[i] == num:
                return False
        for i in range(index - 9, -1, -9):  # 检查同列上方的格子是否矛盾
            if board[i] == num:
                return False
        for i in range(9 * row, 9 * (row + 1)):  # 检查同行的格子是否矛盾
            if board[i] == num:
                return False
        for i in range(row - row % 3, 3 + row - row % 3):  # 行和列都是0~8,index是从0~80
            for j in range(column - column % 3, 3 + column - column % 3):
                if board[j + i * 9] == num:
                    return False
        return True




Solution().solvesudoku([4, 1, 0, 0, 0, 7, 8, 5, 0,
                        8, 0, 6, 0, 0, 0, 0, 0, 9,
                        0, 2, 0, 0, 9, 0, 6, 0, 0,
                        0, 0, 4, 0, 0, 0, 0, 1, 2,
                        2, 0, 0, 5, 8, 0, 0, 7, 0,
                        0, 0, 0, 0, 0, 0, 5, 0, 0,
                        0, 0, 0, 7, 0, 2, 0, 0, 0,
                        0, 0, 8, 0, 1, 0, 0, 0, 0,
                        0, 7, 0, 0, 6, 0, 0, 0, 0])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值