马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
回溯算法(Backtracking)是一种通过试错的方式寻找问题的解的算法设计方法。它通常用于办理组合问题,通过递归地实验所有可能的解,并在发现当前路径不可能得到解时回退(回溯)。以下是使用Python实现回溯算法办理几个经典问题的示例:
1. 八皇后问题(N-Queens Problem)
八皇后问题要求在 ( N \times N ) 的棋盘上放置 ( N ) 个皇后,使得它们互不攻击。
- def solve_n_queens(n):
- def is_safe(board, row, col):
- # 检查列是否有冲突
- for i in range(row):
- if board[i] == col:
- return False
- # 检查对角线是否有冲突
- if abs(board[i] - col) == abs(i - row):
- return False
- return True
- def backtrack(row):
- if row == n:
- solutions.append(board[:])
- return
- for col in range(n):
- if is_safe(board, row, col):
- board[row] = col
- backtrack(row + 1)
- board[row] = -1 # 回溯
- solutions = []
- board = [-1] * n # 初始化棋盘
- backtrack(0)
- return solutions
- # 示例
- n = 4
- solutions = solve_n_queens(n)
- for solution in solutions:
- print(solution)
- # 输出:
- # [1, 3, 0, 2]
- # [2, 0, 3, 1]
复制代码 2. 数独求解(Sudoku Solver)
数独求解问题要求添补一个 ( 9 \times 9 ) 的数独网格,使得每行、每列和每个 ( 3 \times 3 ) 子网格都包罗数字 1 到 9。
- def solve_sudoku(board):
- def is_valid(row, col, num):
- # 检查行和列
- for i in range(9):
- if board[row][i] == num or board[i][col] == num:
- return False
- # 检查 3x3 子网格
- start_row, start_col = 3 * (row // 3), 3 * (col // 3)
- for i in range(3):
- for j in range(3):
- if board[start_row + i][start_col + j] == num:
- return False
- return True
- def backtrack():
- for row in range(9):
- for col in range(9):
- if board[row][col] == 0: # 找到空白格
- for num in range(1, 10):
- if is_valid(row, col, num):
- board[row][col] = num
- if backtrack():
- return True
- board[row][col] = 0 # 回溯
- return False
- return True
- backtrack()
- # 示例
- board = [
- [5, 3, 0, 0, 7, 0, 0, 0, 0],
- [6, 0, 0, 1, 9, 5, 0, 0, 0],
- [0, 9, 8, 0, 0, 0, 0, 6, 0],
- [8, 0, 0, 0, 6, 0, 0, 0, 3],
- [4, 0, 0, 8, 0, 3, 0, 0, 1],
- [7, 0, 0, 0, 2, 0, 0, 0, 0],
- [0, 6, 0, 0, 0, 0, 2, 8, 0],
- [0, 0, 0, 4, 1, 9, 0, 0, 5],
- [0, 0, 0, 0, 8, 0, 0, 7, 9]
- ]
- solve_sudoku(board)
- for row in board:
- print(row)
- # 输出:
- # [5, 3, 4, 6, 7, 8, 9, 1, 2]
- # [6, 7, 2, 1, 9, 5, 3, 4, 8]
- # [1, 9, 8, 3, 4, 2, 5, 6, 7]
- # [8, 5, 9, 7, 6, 1, 4, 2, 3]
- # [4, 2, 6, 8, 5, 3, 7, 9, 1]
- # [7, 1, 3, 9, 2, 4, 8, 5, 6]
- # [9, 6, 1, 5, 3, 7, 2, 8, 4]
- # [2, 8, 7, 4, 1, 9, 6, 3, 5]
- # [3, 4, 5, 2, 8, 6, 1, 7, 9]
复制代码 3. 子集生成(Subset Generation)
生成一个聚集的所有子集。
- def subsets(nums):
- def backtrack(start, path):
- result.append(path[:])
- for i in range(start, len(nums)):
- path.append(nums[i])
- backtrack(i + 1, path)
- path.pop() # 回溯
- result = []
- backtrack(0, [])
- return result
- # 示例
- nums = [1, 2, 3]
- print(subsets(nums))
- # 输出: [[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]]
复制代码 4. 分列组合(Permutations and Combinations)
生成一个聚集的所有分列或组合。
分列(Permutations)
- def permutations(nums):
- def backtrack(path):
- if len(path) == len(nums):
- result.append(path[:])
- return
- for num in nums:
- if num not in path:
- path.append(num)
- backtrack(path)
- path.pop() # 回溯
- result = []
- backtrack([])
- return result
- # 示例
- nums = [1, 2, 3]
- print(permutations(nums))
- # 输出: [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
复制代码 组合(Combinations)
- def combinations(nums, k):
- def backtrack(start, path):
- if len(path) == k:
- result.append(path[:])
- return
- for i in range(start, len(nums)):
- path.append(nums[i])
- backtrack(i + 1, path)
- path.pop() # 回溯
- result = []
- backtrack(0, [])
- return result
- # 示例
- nums = [1, 2, 3, 4]
- k = 2
- print(combinations(nums, k))
- # 输出: [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
复制代码 总结
回溯算法通过递归地实验所有可能的解,并在发现当前路径不可能得到解时回退。它实用于组合问题、分列问题、搜索问题等。通过公道地剪枝和回溯,可以高效地找到问题的解。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |