用回溯法实现n皇后问题,01背包问题,旅商问题代码实现
时间: 2023-07-20 07:46:00 浏览: 107
好的,下面是三个问题的完整代码实现:
1. n皇后问题
```python
def n_queens(n):
# 初始化棋盘
board = [['.' for i in range(n)] for j in range(n)]
# 定义辅助函数
def backtrack(row):
# 如果已经搜索到了最后一行,说明找到了一个可行解,将其加入结果集
if row == n:
res.append([''.join(row) for row in board])
return
# 在当前行中逐一尝试放置皇后
for col in range(n):
# 判断当前位置是否合法
if is_valid(row, col):
# 放置皇后
board[row][col] = 'Q'
# 继续搜索下一行
backtrack(row + 1)
# 恢复状态
board[row][col] = '.'
# 判断当前位置是否合法
def is_valid(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, n)):
if board[i][j] == '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
return True
# 初始化结果集
res = []
# 从第一行开始搜索
backtrack(0)
return res
```
2. 01背包问题
```python
def knapsack01(C, w, v):
# 定义辅助函数
def backtrack(i, cw, cv):
# 如果所有物品都已经选择完毕或者背包已经装满,则更新最大价值
if i == n or cw == C:
nonlocal max_value
max_value = max(max_value, cv)
return
# 选择将当前物品放入背包中
if cw + w[i] <= C:
backtrack(i + 1, cw + w[i], cv + v[i])
# 选择不将当前物品放入背包中
backtrack(i + 1, cw, cv)
# 初始化最大价值
max_value = 0
# 物品的数量
n = len(w)
# 从第一个物品开始搜索
backtrack(0, 0, 0)
return max_value
```
3. 旅行商问题
```python
def tsp(dist):
# 定义辅助函数
def backtrack(path, visited, dist):
# 如果所有城市都已经访问过一次,且当前路程比之前的最短路程更短,则更新最短路程
if len(path) == n and dist + dist_matrix[path[-1]][0] < min_dist[0]:
min_dist[0] = dist + dist_matrix[path[-1]][0]
return
# 从当前城市出发,尝试访问其他城市
for i in range(1, n):
if i not in visited:
# 记录访问过的城市和当前走过的路程
visited.add(i)
path.append(i)
# 继续搜索下一个城市
backtrack(path, visited, dist + dist_matrix[path[-2]][i])
# 恢复状态
path.pop()
visited.remove(i)
# 初始化最短路程
min_dist = [float('inf')]
# 城市的数量
n = len(dist)
# 计算城市之间的距离矩阵
dist_matrix = [[0] * n for _ in range(n)]
for i in range(n):
for j in range(n):
dist_matrix[i][j] = dist[i][j] if i != j else float('inf')
# 从起点开始搜索
backtrack([0], set([0]), 0)
return min_dist[0]
```
阅读全文