回溯算法 (Backtracking)
Published: Sun Feb 22 2026 | Modified: Sat Feb 07 2026 , 3 minutes reading.
回溯算法:撤销的勇气
算法背后的故事:迷宫
想象你置身于一个巨大的石头迷宫中。你想找到出口。
- 你来到一个岔路口:左还是右?你选择了左边。
- 你走了 10 分钟,撞上了一堵死墙。
- 你会坐在那里哭吗?不。你会退回到上一个岔路口,尝试右边的路径。
这就是 回溯算法 (Backtracking)。它是一种系统地尝试所有候选解的方法。如果一个候选解不可能导致有效的最终解,算法就会“回溯”(撤销最后一步),并尝试下一个候选解。
本质上,它是在一棵“决策树”上进行的 深度优先搜索 (DFS)。
为什么需要它?
- 智力游戏: 解决数独、填字游戏或魔方。
- 最优化问题: N 皇后问题——在棋盘上放置 8 个皇后,使它们互不攻击。
- 组合数学: 生成长度为 8 的所有可能密码。
- 资源管理: 在复杂的约束条件下为工人分配任务。
算法是如何“思考”的
该算法遵循一个简单的递归模板:
- 状态: 当前的解看起来是什么样的?
- 选择: 下一步有哪些可能的动作?
- 约束检查: 这个动作合法吗?
- 目标: 我们完成了吗?
- 撤销 (The Undo): 如果我们撞了墙,撤销上一步的选择,尝试下一个。
剪枝 (Pruning): 一个聪明的冒险者如果在路口看到了“死路”的牌子,就不会再往里走 10 分钟。在回溯中,剪枝是指因为违反规则而尽早砍掉整个决策分支的行为。
工程决策:状态空间爆炸
回溯算法可能非常慢,因为可能性的数量呈指数级增长( 或 )。
- 优化: 工程师使用“启发式搜索”来优先尝试最可能的路径。
- 尽早失败: 你越早检测到死胡同,算法运行得就越快。
实现参考 (Python)
# N 皇后问题:在 NxN 的棋盘上放置 N 个皇后
def solve_n_queens(n):
result = []
board = [['.' for _ in range(n)] for _ in range(n)]
def is_safe(row, col):
# 检查列
for i in range(row):
if board[i][col] == 'Q': return False
# 检查左上对角线
for i, j in zip(range(row-1, -1, -1), range(col-1, -1, -1)):
if board[i][j] == 'Q': return False
# 检查右上对角线
for i, j in zip(range(row-1, -1, -1), range(col+1, n)):
if board[i][j] == 'Q': return False
return True
def backtrack(row):
# 基础情况:达成目标
if row == n:
result.append(["".join(r) for r in board])
return
# 尝试所有选择(每一列)
for col in range(n):
if is_safe(row, col):
# 1. 做出选择
board[row][col] = 'Q'
# 2. 探索
backtrack(row + 1)
# 3. 撤销选择 (回溯)
board[row][col] = '.'
backtrack(0)
return result
# 使用示例
solutions = solve_n_queens(4)
print(f"4 皇后问题的解法总数: {len(solutions)}")小结
回溯算法教会我们:探索需要谦逊。我们必须愿意承认自己是错的,并有纪律地回到上一个确定的点。它提醒我们,在充满无限可能的世界里,寻找真理的唯一方法就是尝试一切——并知道何时停止。
