货郎担问题
一个的组合优化问题,目标是在给定的一组城市和城市间的距离数据下,寻找一条最短路径,使得每个城市恰好访问一次,并最后回到起始城市。
python实现(动态规划):
import sys
def tsp(graph, curr_city, visited, n, count, path, ans, min_dist):
if count == n and graph[curr_city][0]:
ans.append(path.copy())
min_dist[0] = min(min_dist[0], path[n-1][0] + graph[curr_city][0])
return
for i in range(n):
if visited[i] == False and graph[curr_city][i]:
visited[i] = True
path.append((graph[curr_city][i], i))
tsp(graph, i, visited, n, count+1, path, ans, min_dist)
visited[i] = False
path.pop()
def solve_tsp(graph):
n = len(graph)
visited = [False] * n
visited[0] = True
path = [(0, 0)]
ans = []
min_dist = [sys.maxsize]
tsp(graph, 0, visited, n, 1, path, ans, min_dist)
return ans, min_dist[0]
graph = [
[0, 10, 15, 20],
[10, 0, 35, 25],
[15, 35, 0, 30],
[20, 25, 30, 0]
]
solve_tsp(graph)
连续邮资问题
一种组合优化问题,给定一系列不同面值的邮票,如何用最少的邮票凑出给定的邮资金额。
python实现(回溯法):
def func(postage, stamps):
result = float('inf')
path = []
def dfs(remaining):
nonlocal result
if remaining == 0: # 当前路径组合的邮资金额等于所需金额
result = min(result, len(path))
return
for stamp in stamps:
if remaining >= stamp and len(path) < result:
path.append(stamp) # 尝试将当前面值的邮票加入路径
dfs(remaining - stamp) # 继续向下递归
path.pop() # 回溯,将当前尝试的邮票移出路径
dfs(postage)
if result == float('inf'):
return 0
return result
postage = 18
stamps = [1, 5, 10] # 邮票面值
result = func(postage, stamps)
print(f"使用{result}张邮票凑出邮资金额{postage}")
python实现(动态规划):
def func(postage, stamps):
dp = [float('inf')] * (postage + 1)
dp[0] = 0
for i in range(1, postage + 1):
for stamp in stamps:
if i >= stamp:
dp[i] = min(dp[i], 1 + dp[i - stamp]) # 动态规划求解最优解
if dp[postage] == float('inf'):
return "无法凑出该邮资金额"
else:
return dp[postage]
# 示例使用
postage = 18
stamps = [1, 5, 10] # 邮票面值
result = func(postage, stamps)
print(f"需要最少使用{result}张邮票凑出邮资金额{postage}")
本文仅为学习记录,如有错误欢迎指出。