python 回溯算法(Backtracking)

devtools/2025/1/8 4:08:23/

回溯算法(Backtracking)是一种通过试错的方式寻找问题的解的算法设计方法。它通常用于解决组合问题,通过递归地尝试所有可能的解,并在发现当前路径不可能得到解时回退(回溯)。以下是使用Python实现回溯算法解决几个经典问题的示例:


1. 八皇后问题(N-Queens Problem)

八皇后问题要求在 ( N \times N ) 的棋盘上放置 ( N ) 个皇后,使得它们互不攻击。

python">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 Falsereturn Truedef backtrack(row):if row == n:solutions.append(board[:])returnfor col in range(n):if is_safe(board, row, col):board[row] = colbacktrack(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。

python">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 Falsereturn Truedef 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] = numif backtrack():return Trueboard[row][col] = 0  # 回溯return Falsereturn Truebacktrack()# 示例
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)

生成一个集合的所有子集。

python">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)
python">def permutations(nums):def backtrack(path):if len(path) == len(nums):result.append(path[:])returnfor 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)
python">def combinations(nums, k):def backtrack(start, path):if len(path) == k:result.append(path[:])returnfor 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]]

总结

回溯算法通过递归地尝试所有可能的解,并在发现当前路径不可能得到解时回退。它适用于组合问题、排列问题、搜索问题等。通过合理地剪枝和回溯,可以高效地找到问题的解。


http://www.ppmy.cn/devtools/147956.html

相关文章

在 Windows 上使用 SSH 密钥访问 Linux 服务器

本章目录: 前言1. 准备工作2. 生成 SSH 密钥对步骤 1:打开命令行步骤 2:运行 ssh-keygen 命令步骤 3:选择密钥保存位置步骤 4:设置密钥密码(可选)步骤 5:生成密钥对 3. 查看生成的密钥文件4. 将…

LeetCode:106.从中序与后序遍历序列构造二叉树

跟着carl学算法,本系列博客仅做个人记录,建议大家都去看carl本人的博客,写的真的很好的! 代码随想录 LeetCode:106.从中序与后序遍历序列构造二叉树 给定两个整数数组 inorder 和 postorder ,其中 inorder …

解锁 CSS Grid 的奇妙世界,探寻前端布局的无限可能

文章目录 一、引言二、CSS Grid 基础入门(一)基本概念解读(二)关键属性剖析 三、CSS Grid 实用技巧大放送(一)打造响应式布局(二)实现复杂的网格结构(三)灵活…

【论文阅读】SCGC : Self-supervised contrastive graph clustering

论文地址:SCGC : Self-supervised contrastive graph clustering - ScienceDirect 代码地址: https://github.com/gayanku/SCGC 摘要 图聚类旨在发现网络中的群体或社区。越来越多的模型使用自编码器(autoencoders)结合图神经网…

rear(Relax-and-Recover)全量备份RHEL8.6操作系统

目录 REAR介绍一、事前准备二、备份操作配置本地yum源、安装rear软件修改rear工具配置文件:/etc/rear/local.conf查看rear配置信息命令开始备份检查文件生成三、恢复主机REAR介绍 rear (Relax and Recover)是一个开源项目,用于备份和还原Linux系统。rear提供了一个简单的框架…

node.js之---事件循环机制

事件循环机制 Node.js 事件循环机制(Event Loop)是其核心特性之一,它使得 Node.js 能够高效地处理大量并发的 I/O 操作。Node.js 基于 非阻塞 I/O,使用事件驱动的模型来实现异步编程。事件循环是 Node.js 实现异步编程的基础&…

vue2框架配置路由设计打印单

业务效果: 查询出列表后&#xff0c;点击申请单按钮&#xff0c;弹出申请表格&#xff0c;可进行打印 后端实现 控制器、服务层等省略&#xff0c;关联查出数据提供接口给前端即可 <!--获取详细信息(用于申请单打印)--><select id"selectXxxxDetail" par…

Vue项目中生成node_modules文件夹的两种常用方法及npm优势

在Vue项目中生成node_modules文件夹的过程非常简单,主要步骤如下: 1、使用 npm 安装依赖包; 2、使用 yarn 安装依赖包。其中,推荐使用npm安装依赖包,原因如下: 兼容性更广:npm是Node.js的默认包管理工具,具有更高的兼容性。社区支持:npm拥有更大的用户基础和社区支持,…