动态规划范例——驿站马车问题

问题描述

驿站马车问题是阐述动态规划和介绍动态规划术语构建的特殊问题,19世纪中叶,密苏里州的一位淘金者决定去加利福尼亚州淘金,旅程需要乘坐驿站马车,途径那些有遭遇抢到袭击危险的无人乡村,虽然他的出发点和目的地已定,但他有相当多的选择来决定经过哪些州,如图所示

淘金者从A出发,最终到达目的地J州需要经过4个中间阶段
淘金者相当担心自己的安全,想出了一个巧妙的办法,每位驿站马车的乘客都有人寿保险,由于对乘坐任何驿站马车保单的成本都是基于该线路安全性的仔细评估,因而最安全的路线应该是全部人寿保险保单中最便宜的。

问题求解

  • 贪心思想
    为每个连续阶段提供最省钱的路线是一种目光短浅的方法,不能得到全局最优策略,也就是说贪心思想(每一步都选择当前最优的一步走)是在这里是不适用的
  • 枚举法
    虽然枚举法可以得到最优解,但在路线多的情况下将会有极大的工作量
  • 动态规划
    动态规划从原始问题的很小一部分开始,给这个小问题找到最优解,然后初见扩大问题,从前面的问题找到最优解,直到求得全部原始问题的解,得到全局最优解
    从小问题开始,就是淘金者几乎完成了他的旅行,这声最后一个阶段,即为即将到达J州,再扩大这个问题,从每个州到下一个州的最优解,可以从前面重复的结果寻找

动态规划问题的特征

  1. 策略决策,将一个问题分为几个阶段,每个阶段都有一个策略决策,而上述问题可以分为四个阶段,每个阶段都会做出决策,决定选择哪一份人寿保险。
  2. 每个阶段都有与之对应的状态,上述问题中,淘金者旅途的驿站中可以落脚的州就是状态,状态是各种可能的条件。
  3. 每个阶段策略决策的结果都是从当前状态变成下一个阶段开始的状态
  4. 设计求解的过程就是为整个问题找到一个最优策略,每个阶段对每个可能的状态进行最优策略决策的指令
  5. 已知目前状态,对于剩余阶段的最优策略与先前采用的策略无关,最优策略只取决于当前状态,而与如何到达这个状态的过程无关,即最优原理
  6. 求解最后阶段找到最优策略开始
  7. 如果知道n+1阶段的最优策略,就可以确定第n阶段的最优策略,得到一个递推关系,上述的问题的递推关系即d(x)from = min{d(x)from, d(x)to + weight~from, to~}
  8. 通过上述的递推关系,求解过程从终点开始并逐步逆序移动,每次都找到该阶段的最优策略,直到起点,得到的最优策略即为整个问题的解决方案

算法思路

构建有向图,从最后阶段开始,即从终点开始,distance数组对应值为对应顶点距离终点的最短距离,终点初始化为0,其他为无穷大,从终点开始向起点移动,每次决策得到当前结点到终点最短距离,直到起点,得到起点到终点的最短距离,动态转移方程为distance[adjacentList[i][j].from] = min(adjacentList[i][j].weight + distance[i],distance[adjacentList[i][j].from]) ;,每个阶段取决于下一个阶段,每个顶点到终点的最短距离取决于上一个最近邻接结点,逐个求得最优子结构,最后得到全局最优解

void Graph::dynamicProgramming() {for (int i = adjacentList.size() - 1; i >= 0; i--) {for (int j = 0; j < adjacentList[i].size(); j++) {distance[adjacentList[i][j].from] = min(distance[adjacentList[i][j].from], adjacentList[i][j].weight + distance[i]);}}
}

实现代码

/*
author : eclipse
email  : eclipsecs@qq.com
time   : Mon Jun 15 18:17:58 2020
*/
#include <bits/stdc++.h>
using namespace std;struct Edge {int from;int weight;
};class Graph {private:static const int INF = 1024;vector< vector<Edge> > adjacentList;vector<int> distance;int vextexNumber;
public:Graph(int vextexNumber, vector< pair< pair<int, int> , int> > edges);void dynamicProgramming();void traverse();
};Graph::Graph(int vextexNumber, vector< pair< pair<int, int> , int> > edges) {this->vextexNumber = vextexNumber;adjacentList.resize(vextexNumber);distance.resize(vextexNumber);for (int i = 0; i < vextexNumber; i++) {distance[i] = INF;}distance[vextexNumber - 1] = 0;for (int i = 0; i < edges.size(); i++) {adjacentList[edges[i].first.second].push_back((Edge) {edges[i].first.first, edges[i].second});}
}void Graph::dynamicProgramming() {for (int i = adjacentList.size() - 1; i >= 0; i--) {for (int j = 0; j < adjacentList[i].size(); j++) {distance[adjacentList[i][j].from] = min(distance[adjacentList[i][j].from], adjacentList[i][j].weight + distance[i]);}}
}void Graph::traverse() {for (int i = 0; i < distance.size(); i++) {printf("%d ", distance[i]);}
}int main(int argc, char const *argv[]) {vector< pair< pair<int, int> , int> > edges;int vextexNumber, edgeNumber;scanf("%d%d", &vextexNumber, &edgeNumber);for (int i = 0; i < edgeNumber; i++) {int from, to, weight;scanf("%d%d%d", &from, &to, &weight);edges.push_back(make_pair(make_pair(from, to), weight));}Graph *graph = new Graph(vextexNumber, edges);graph->dynamicProgramming();graph->traverse();return 0;
}

输入数据

10 20
0 1 2
0 2 4
0 3 3
1 4 7
1 5 4
1 6 6
2 4 3
2 5 2
2 6 4
3 4 4
3 5 1
3 6 5
4 7 1
4 8 4
5 7 6
5 8 3
6 7 3
6 8 3
7 9 3
8 9 4

输入结果

11 11 7 8 4 7 6 3 4 0

鸣谢

《运筹学导论》

最后

  • 由于博主水平有限,不免有疏漏之处,欢迎读者随时批评指正,以免造成不必要的误解!

动态规划范例——驿站马车问题相关推荐

  1. 《暗黑地牢》—“克苏鲁”式的绝望冒险

    玻璃心玩家慎入. 年龄不大,网龄不小.在这不长不短的十余年里,体验过的游戏也算是五花八门.大部分游戏都认真的为新手做了各种各样的游戏教程,无论是直接的展现亦或是侧面的指导,都是在努力地将游戏的魅力和最 ...

  2. 20221222英语学习

    托福词汇 sociology n.社会学 given adj.规定的,特定的:假定的 narrative n.叙述:记叙体,叙述技巧 deplore vt.悲叹,哀叹,公开谴责 despoil vt. ...

  3. 20221223英语学习

    今日托福词汇 review n.复习; 回顾, 检讨; 检阅; 评论; 详检, 审核; 回放功能 tentative adj.试验性的; 不确定的; 暂时的; 犹豫的, 踌躇不决的 synonym n ...

  4. 美国人的10个文化偶像

    美国<男人>.<传记>等媒体联合评选出了美国文化的十大偶像.据称,他们的评选标准是:只要提到他或她的名字,人们就会联想到美国:不管人们喜欢还是憎恨,在别国人的眼里,他们都代表着 ...

  5. 美国人的10个文化偶像(2005 评出)

    美国人的10个文化偶像 美国<男人>.<传记>等媒体联合评选出了美国文化的十大偶像.据称, 他们的评选标准是:只要提到他或她的名字,人们就会联想到美国:不管人们喜欢还是憎恨,在 ...

  6. oracle数据绷带条件,手法复位“8”字绷带外固定

    [单选题]药物装硬胶囊时,易风化药物易使胶囊 [单选题] [多选题]下列说法正确的有 [单选题]患者王某,因肝硬化腹水合并肺部感染而收入院,体温39.0°C度. 护理患者的措施中哪项不妥 [判断题]工 ...

  7. 面试必备:高频算法题汇总「图文解析 + 教学视频 + 范例代码」之 字符串处理+动态规划 合集!

    Attention 秋招接近尾声,我总结了 牛客.WanAndroid 上,有关笔试面经的帖子中出现的算法题,结合往年考题写了这一系列文章,所有文章均与 LeetCode 进行核对.测试.欢迎食用 本 ...

  8. 【算法数据结构Java实现】Java实现动态规划(背包问题)

    1.背景      追随着buptwusuopu大神的脚步,最近在研习动态规划.动态规划应该叫一种解决问题的思想,记得又一次去某公司面试就被问到了这个. 多于动态规划的理解,大致是这样的,从空集合开始 ...

  9. 动态规划:斐波那契数列里面的东西?

    斐波那契数列 我想每个人都会写斐波那契数列吧!! 斐波那契数列的定义 f(0) = 1,f(1) = 1,f(n) = f(n-1) + f(n-2) 基于递归的方式实现,讲到递归都会用到: def ...

最新文章

  1. PyTorch官方教程大更新:增加标签索引,更加新手友好
  2. 高倍数泡沫装置PHP_平衡式泡沫比例混合装置 PHP - 压力式比例混合装置 - 武汉鑫澳龙消防设备有限公司...
  3. 【Python】Python之函数讲解
  4. Maven+Mybatis+Spring配置
  5. 深入学习http协议(转)
  6. java面试手写单链表_(转)面试大总结之一:Java搞定面试中的链表题目
  7. Spark RDD、DataFrame原理及操作详解
  8. redis-数据类型-列表list类型
  9. android listpreference 自定义,Android中Fragmen首选项使用自定义的ListPreference的方法
  10. 服务器没权限修改,ftp服务器没有修改权限
  11. atitit.jndi的架构与原理以及资源配置and单元测试实践
  12. 如何高效的批量删除亿级大表数据
  13. shopex admincore.php,shopex网店系统更换空间后出错:Fatal error: Incompatible file format:...
  14. WPS如何在同一篇文档针对不同章节设置不同的页眉页脚
  15. 从 virtio 网卡收包段错误问题出发反思个人问题分析的过程
  16. lucas–kanade_Lucas–Kanade光流算法学习
  17. 田野调查手记·浮山摩崖石刻(十三)
  18. VB全局HOOK写游戏盗号木马
  19. 使用Excel制作一个动态计划表
  20. 在JSP中,点击网页某个按钮或者超链接执行某些需要确认的命令时,弹出确认框如下效果: 如果点击确定,则执行要操作的命令。如果点击取消则不执行。 实现步骤: 1:在jsp,或者html

热门文章

  1. ArcGIS Enterprise部署介绍
  2. Oracle工具包使用规则整理
  3. C语言:关键字---struct(声明结构体类型)
  4. 怎么正确理解「辩证法」
  5. 使用Visual Studio Code进行ABAP开发
  6. 《STM32单片机开发应用教程(HAL库版)---基于国信长天嵌入式竞赛实训平台(CT117E-M4)》第二章 软件安装与使用
  7. ASP.NET Core 企业开发架构概述
  8. JavaC++题解与拓展——leetcode310.最小高度树【复习链式前向星】
  9. 图解 JavaScript 对象
  10. win32 play flash file