【路径规划】全局路径规划算法——动态规划算法(含python实现)

参考资料

1. 算法简介

  • 动态规划是运筹学的一个分支,是求解多阶段决策过程最优化问题的数学方法。
  • 各个阶段决策的选取不是任意确定的,它依赖于当前面临的状态,又影响以后的发展。当各个阶段的决策确定后,就组成了一个决策序列,因而也就决定了整个过程的一条活动路线,这样的一个前后关联具有链状结构的多阶段过程就称为多阶段决策问题。
  • 动态规划在车辆工程技术领域有着广泛的应用,如“两档变速器最优换挡规律”、“混合动力汽车最优能量管理策略”、“栅格地图最优路径搜索”等。

2. 算法思想

  • 动态规划的思想就是将多阶段决策问题转化为一系列单阶段最优化问题

  • 对最佳路径(最佳决策过程)所经过的各个阶段,其中每个阶段始点到全过程终点的路径,必定是该阶段起始点到全
    过程终点的一切可能路径中的最佳路径(最优决策),这就是Bellman提出的著名的最优化原理

  • 简言之, 一个最优策略的子策略必然也是最优的

DP算法逆向寻优,正向求解,本质由三层循环构成:

  • 第一层遍历每一个阶段;
  • 第二层遍历第 i i i个阶段的每一个状态;
  • 第三层循环遍历第 i i i阶段的第 j j j个状态到第 i − 1 i-1 i1阶段的每一条路径, 更新当前状态的到上一个阶段的状态的最短距离

3. 算法示例

如图,设终点为 E E E,逆向运用DP算法:

  • 第Ⅳ阶段(D →E): D 有两条路线到终点E ,权重分别为
    f 4 ( D 1 ) = 5 f 4 ( D 2 ) = 2 f_4(D_1)=5\\ f_4(D_2)=2\\ f4(D1)=5f4(D2)=2

  • 第Ⅲ阶段(C →D): C 到D 有 6 条路线。第3阶段的C有3个状态值,分别讨论经过该状态
    值的最优路线。

    • 经过C1
      f 3 ( C 1 ) = min ⁡ { d ( C 1 , D 1 ) + f 4 ( D 1 ) d ( C 1 , D 2 ) + f 4 ( D 2 ) } = min ⁡ { 3 + 5 9 + 2 } = 8 \begin{aligned} f_{3}\left(C_{1}\right)=\min &\left\{\begin{array}{l} d\left(C_{1}, D_{1}\right)+f_{4}\left(D_{1}\right) \\ d\left(C_{1}, D_{2}\right)+f_{4}\left(D_{2}\right) \end{array}\right\}=\min \left\{\begin{array}{l} 3+5 \\ 9+2 \end{array}\right\}=8 \\ \end{aligned} f3(C1)=min{d(C1,D1)+f4(D1)d(C1,D2)+f4(D2)}=min{3+59+2}=8
      最短路线为 C 1 → D 1 → E C 1 \rightarrow D 1 \rightarrow E C1D1E

    • 经过C2
      f 3 ( C 2 ) = min ⁡ { d ( C 2 , D 1 ) + f 4 ( D 1 ) d ( C 2 , D 2 ) + f 4 ( D 2 ) } = min ⁡ { 6 + 5 5 + 2 } = 7 \begin{aligned} f_{3}\left(C_{2}\right)=\min \left\{\begin{array}{l} d\left(C_{2}, D_{1}\right)+f_{4}\left(D_{1}\right) \\ d\left(C_{2}, D_{2}\right)+f_{4}\left(D_{2}\right) \end{array}\right\}=\min \left\{\begin{array}{l} 6+5 \\ 5+2 \end{array}\right\}=7 \\ \end{aligned} f3(C2)=min{d(C2,D1)+f4(D1)d(C2,D2)+f4(D2)}=min{6+55+2}=7
      最短路线为 C 2 → D 2 → E C2\rightarrow D2 \rightarrow \mathrm{E} C2D2E

    • 经过C3
      f 3 ( C 3 ) = min ⁡ { d ( C 3 , D 1 ) + f 4 ( D 1 ) d ( C 3 , D 2 ) + f 4 ( D 2 ) } = min ⁡ { 8 + 5 10 + 2 } = 12 f_{3}\left(C_{3}\right)=\min \left\{\begin{array}{l} d\left(C_{3}, D_{1}\right)+f_{4}\left(D_{1}\right) \\ d\left(C_{3}, D_{2}\right)+f_{4}\left(D_{2}\right) \end{array}\right\}=\min \left\{\begin{array}{l} 8+5 \\ 10+2 \end{array}\right\}=12 f3(C3)=min{d(C3,D1)+f4(D1)d(C3,D2)+f4(D2)}=min{8+510+2}=12
      最短路线为 C 3 → D 2 → E C 3 \rightarrow D 2 \rightarrow E C3D2E

  • 第Ⅱ阶段(B →C): B 到C 有 9 条路线。第Ⅱ阶段的B有3个状态值,类似地,分别讨论经过该状态值的最优路线。

    • 经过B1
      f 2 ( B 1 ) = min ⁡ { d ( B 1 , C 1 ) + f 3 ( C 1 ) d ( B 1 , C 2 ) + f 3 ( C 2 ) d ( B 1 , C 3 ) + f 3 ( C 3 ) } = min ⁡ { 12 + 8 14 + 7 10 + 12 } = 20 f_{2}\left(B_{1}\right)=\min \left\{\begin{array}{l} d\left(B_{1}, C_{1}\right)+f_{3}\left(C_{1}\right) \\ d\left(B_{1}, C_{2}\right)+f_{3}\left(C_{2}\right) \\ d\left(B_{1}, C_{3}\right)+f_{3}\left(C_{3}\right) \end{array}\right\}=\min \left\{\begin{array}{l} 12+8 \\ 14+7 \\ 10+12 \end{array}\right\}=20 f2(B1)=mind(B1,C1)+f3(C1)d(B1,C2)+f3(C2)d(B1,C3)+f3(C3)=min12+814+710+12=20
      最短路线为 B 1 → C 1 → D 1 → E B 1 \rightarrow C 1 \rightarrow D 1 \rightarrow E B1C1D1E
    • 经过B2
      f 2 ( B 2 ) = min ⁡ { d ( B 2 , C 1 ) + f 3 ( C 1 ) d ( B 2 , C 2 ) + f 3 ( C 2 ) d ( B 2 , C 3 ) + f 3 ( C 3 ) } = min ⁡ { 6 + 8 10 + 7 4 + 12 } = 14 f_{2}\left(B_{2}\right)=\min \left\{\begin{array}{l} d\left(B_{2}, C_{1}\right)+f_{3}\left(C_{1}\right) \\ d\left(B_{2}, C_{2}\right)+f_{3}\left(C_{2}\right) \\ d\left(B_{2}, C_{3}\right)+f_{3}\left(C_{3}\right) \end{array}\right\}=\min \left\{\begin{array}{l} 6+8 \\ 10+7 \\ 4+12 \end{array}\right\}=14 f2(B2)=mind(B2,C1)+f3(C1)d(B2,C2)+f3(C2)d(B2,C3)+f3(C3)=min6+810+74+12=14
      最短路线为 B 2 → C 1 → D 1 → E B 2 \rightarrow C 1 \rightarrow D 1 \rightarrow E B2C1D1E
    • 经过B3
      f 2 ( B 3 ) = min ⁡ { d ( B 3 , C 1 ) + f 3 ( C 1 ) d ( B 3 , C 2 ) + f 3 ( C 2 ) d ( B 3 , C 3 ) + f 3 ( C 3 ) } = min ⁡ { 13 + 8 12 + 7 11 + 12 } = 19 f_{2}\left(B_{3}\right)=\min \left\{\begin{array}{l} d\left(B_{3}, C_{1}\right)+f_{3}\left(C_{1}\right) \\ d\left(B_{3}, C_{2}\right)+f_{3}\left(C_{2}\right) \\ d\left(B_{3}, C_{3}\right)+f_{3}\left(C_{3}\right) \end{array}\right\}=\min \left\{\begin{array}{l} 13+8 \\ 12+7 \\ 11+12 \end{array}\right\}=19 f2(B3)=mind(B3,C1)+f3(C1)d(B3,C2)+f3(C2)d(B3,C3)+f3(C3)=min13+812+711+12=19
      最短路线为 B 3 → C 2 → D 2 → E B 3 \rightarrow C 2 \rightarrow D 2 \rightarrow E B3C2D2E
  • 第Ⅰ阶段(A →B): A 到B 有 3 条路线。
    f 1 ( A ) = min ⁡ { d ( A , B 1 ) + f 2 ( B 1 ) d ( A , B 2 ) + f 2 ( B 2 ) d ( A , B 3 ) + f 2 ( B 3 ) } = min ⁡ { 2 + 20 5 + 14 1 + 19 } = 19 f_{1}(A)=\min \left\{\begin{array}{l} d\left(A, B_{1}\right)+f_{2}\left(B_{1}\right) \\ d\left(A, B_{2}\right)+f_{2}\left(B_{2}\right) \\ d\left(A, B_{3}\right)+f_{2}\left(B_{3}\right) \end{array}\right\}=\min \left\{\begin{array}{l} 2+20 \\ 5+14 \\ 1+19 \end{array}\right\}=19 f1(A)=mind(A,B1)+f2(B1)d(A,B2)+f2(B2)d(A,B3)+f2(B3)=min2+205+141+19=19
    最短路线为 A → B 2 → C 1 → D 1 → E A \rightarrow B 2 \rightarrow C 1 \rightarrow D 1 \rightarrow E AB2C1D1E

4. python实现

根据第3节的分析,我们可以写出以下python程序(程序参考自知乎):

INF = float('INF')
### 状态节点定义
graph = {
    '4': {'D1': {'E': 5}, 'D2': {'E': 2}},
    '3': {'C1': {'D1': 3, 'D2': 9}, 'C2': {'D1': 6, 'D2': 5}, 'C3': {'D1': 8, 'D2': 10}},
    '2': {'B1': {'C1': 12, 'C2': 14, 'C3': 10}, 'B2': {'C1': 6, 'C2': 10, 'C3': 4}, 'B3': {'C1': 13, 'C2': 12, 'C3': 11}},
    '1': {'A': {'B1': 2, 'B2': 5, 'B3': 1}}
    }

### 最优路径及其距离值定义
INF = float('INF')
# 初始时距离为无穷大
dists = {
    'A': INF,
    'B1': INF,
    'B2': INF,
    'B3': INF,
    'C1': INF,
    'C2': INF,
    'C3': INF,
    'D1': INF,
    'D2': INF,
    'E': 0
    }

path_opt = {
    'A': ['A'],
    'B1': ['B1'],
    'B2': ['B2'],
    'B3': ['B3'],
    'C1': ['C1'],
    'C2': ['C2'],
    'C3': ['C3'],
    'D1': ['D1'],
    'D2': ['D2'],
    'E': ['E']
}


# 每一个节点的父节点
parents = {
    'A': None,
    'B1': None,
    'B2': None,
    'B3': None,
    'C1': None,
    'C2': None,
    'C3': None,
    'D1': None,
    'D2': None,
    'E': None
    }

# 动态规划函数
def DP(graph, dists, parents):
    for period_key in graph.keys():  # 遍历每一个阶段
        for key_i in graph[period_key].keys():  # 遍历每个阶段的每一个状态节点
            min_key = None
            for key_i_dist in graph[period_key][key_i].keys(): # 遍历当前阶段的每个状态节点到下一阶段的每一条路径
                if graph[period_key][key_i][key_i_dist] + dists[key_i_dist] < dists[key_i]:
                    dists[key_i] = graph[period_key][key_i][key_i_dist] + dists[key_i_dist]
                    parents[key_i] = key_i_dist
                    min_key = key_i_dist  # 找出最小距离值的节点
            path_opt[key_i].extend(path_opt[min_key])  # 将最小距离值的节点添加到最优路径集合



DP(graph, dists, parents)
print("E到每个节点的最短距离:\n",dists)
print("====================")
print("最优时每个节点的父节点:\n",parents)
print("====================")
print("最优路径:\n",path_opt)


代码仓库见github

以下是一个使用动态规划解决旅行商问题(TSP)的Python代码示例: ```python import numpy as np def tsp_dp(distance_matrix): num_cities = distance_matrix.shape[0] all_sets = 2 ** num_cities dp = np.full((num_cities, all_sets), -1) # 初始化动态规划表 def tsp(mask, pos): if mask == all_sets - 1: # 所有城市都已经访问过了 return distance_matrix[pos][0] # 返回回到起始城市的距离 if dp[pos][mask] != -1: # 如果已经计算过该状态,则直接返回结果 return dp[pos][mask] ans = float('inf') # 初始化最小距离为正无穷 for city in range(num_cities): if (mask >> city) & 1 == 0: # 如果城市未访问过 new_mask = mask | (1 << city) # 将该城市添加到访问集合中 distance = distance_matrix[pos][city] + tsp(new_mask, city) ans = min(ans, distance) # 更新最小距离 dp[pos][mask] = ans # 记录结果 return ans return tsp(1, 0) # 示例使用 distance_matrix = np.array([ [0, 10, 15, 20], [10, 0, 35, 25], [15, 35, 0, 30], [20, 25, 30, 0] ]) print("最优路径长度:", tsp_dp(distance_matrix)) ``` 该代码使用动态规划思想求解旅行商问题,其中 `distance_matrix` 是一个表示城市之间距离的矩阵。代码使用了递归函数 `tsp` 来实现动态规划,并利用状态压缩技巧来记录城市的访问状态。最后输出的是最优路径的长度。 请注意,该代码仅仅计算了最优路径的长度,如果需要输出具体的路径,还需要进行额外的操作。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CHH3213

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值