一、实验目的

1.掌握能用动态规划方法求解的问题应满足的条件;
2.加深对动态规划方法的理解与应用;
3.锻炼学生对程序跟踪调试能力;
4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。

二.实验内容

对于任意数目的n个城市,分别用1~n编号,则这个问题归结为在有向带权图中,寻找一条路径最短的哈密尔顿回路问题。

三.实验要求

(1)用动态规划方法货郎担问题;
(2)上机实现所设计的算法;

四.实验过程设计(算法设计过程)

动态规划的思想实质是分治思想和解决冗余。 与分治法类似的是,将原问题分解成若干个子问题,先求解子问题,再从这些子问题的解得到原问题的解。与分治法不同的是,经分解的子问题往往不是互相独立的。若用分治法来解,有些共同部分(子问题或子子问题)被重复计算了很多次。如果能够保存已解决的子问题的答案,在需要时再查找,这样就可以避免重复计算、节省时间。动态规划法用一个表来记录所有已解的子问题的答案。
动态规划方法的基本思想是,把求解的问题分成许多阶段或多个子问题,然后按顺序求解各子问题。最后一个子问题就是初始问题的解。
由于动态规划的问题有重叠子问题的特点,为了减少重复计算,对每一个子问题只解一次,将其不同阶段的不同状态保存在一个二维数组中。
1、多段图
1)从最后一段算起,找出每段的每个点的最短距离;
2)每段逐一向前推,直到算至起点;
3)比较从起点到终点的距离得出最短距离。
2、货郎担
假设周游路线是开始于结点1并终止于结点1的了条简单路径。每一条周游路线都由一条边(1,k)和一条由结点k到结点1的路径所组成,其中k∈V-{1};而这条由结点k到结点1的路径通过V-{1,k}的每个结点各一次。容易看出,如果这条周游路线是最优的,那么这条由k到1的路径必定是通过V-{1,k}中所有结点的由k到1的最短路径,因此最优性原理成立。设g(i,S)是由结点i开始,通过S中的所有结点,在结点1终止的一条最短路径长度。g(1,V-{1})是一条最优的周游路线长度。于是可以得出
g(1,V-{1})=min{ +g(k,V-{1,k})}
将其一般化可得
g(i,S)—min{ +g(j,S-{j})}

五.源代码

1、多段图

#include <iostream>
#include <vector>#define MAX 9999
using namespace std;void initGraph(vector<vector<int> > &g, vector<vector<int> > &s) {cout << "输入边信息:(顶点a 顶点b 权值w)(输入0结束)" << endl;int i, j;while (cin >> i && i) {cin >> j;cin >> g[i][j];}cout << "输入起点:";cin >> s[1][0];int level;cout << "输入中间阶段数:(不含起点和终点层)";cin >> level;int a = 2;for (int i = 1; i <= level; i++) {cout << "输入中间第" << i << "阶段的点:(输入0结束)";int k, j = 0;while (cin >> k && k) {s[a][j++] = k;}a++;}cout << "输入终点:";cin >> s[a][0];
}void way(vector<vector<int> > &g, vector<vector<int> > &s, vector<vector<int> > &f, vector<int> &result) {int n = g.size() - 1;int level, i;    for (i = 1; i <= n; i++) if (s[i][0] == 0)break;level = i - 1;int t = n;int start = s[1][0];int end = s[level][0];for (i = level - 1; i >= 1; i--){int j = 0;while (s[i][j]){int m = 0; f[i][j] = MAX;if (g[s[i][j]][end] == MAX){while (s[i + 1][m] != 0){if (g[s[i][j]][s[i + 1][m]] != MAX){if (f[i][j] > (f[i + 1][m] + g[s[i][j]][s[i + 1][m]])){f[i][j] = f[i + 1][m] + g[s[i][j]][s[i + 1][m]];result[s[i][j]] = s[i + 1][m];t--;}}m++;}}else{while (s[i + 1][m] != 0){if (f[i][j] > (f[i + 1][m] + g[s[i][j]][s[i + 1][m]])){f[i][j] = f[i + 1][m] + g[s[i][j]][s[i + 1][m]];result[s[i][j]] = s[i + 1][m];t--;}m++;}}j++;}}
}void print(vector<int> &result, vector<vector<int> > &s, vector<vector<int> > &f) {int n = result.size() - 1;cout << "最短路径为:";int t = s[1][0];cout << t;  while (result[t] != s[n][0]) {cout << " ->" << result[t];t = result[t];}cout << endl << "最短距离为:" << f[1][0] << endl;
}int main() {int vexNum;cout << "输入点的个数:";cin >> vexNum;vector<vector<int> > graph(vexNum + 1, vector<int>(vexNum + 1, MAX));vector<vector<int> > s(vexNum + 1, vector<int>(vexNum + 1, 0));   vector<vector<int> > f(vexNum + 1, vector<int>(vexNum + 1, 0)); vector<int > result(vexNum + 1, 0);  initGraph(graph, s);    way(graph, s, f, result);print(result, s, f);       system("pause");return 0;
}

运行结果示例:

2.货郎担问题

#include<iostream>
#include<iomanip>
using namespace std;int n;
int cost[20][20];
bool done[20] = { 1 };
int start = 0;
int imin(int num, int cur)
{if (num == 1)  return cost[cur][start];  int  mincost = 10000;for (int i = 0; i < n; i++){cout << i << "  i:" << done[i] << endl;if (!done[i] && i != start) {done[i] = 1;  int value = cost[cur][i] + imin(num - 1, i);if (mincost > value){mincost = value;cout << mincost << endl;}done[i] = 0;}}return mincost;
}int main()
{cout << "请输入n的值"<<endl;cin >> n;int cc[100][100];for (int i = 0; i < n; i++){for (int j = 0; j < n; j++){cout << "请输入各成本值" << endl;cin >> cc[i][j];cost[i][j] = cc[i][j];}}cout << imin(n, start) << endl;return 0;
}

动态规划多段图和货郎担问题相关推荐

  1. 动态规划——多段图问题

    多段图问题 多段图问题是利用动态规划思想解决的经典问题之一,在日常生活中应用广泛. 问题描述 若存在一个有向加权图G,且G能分出起点和终点以及中间的n的阶段,求起点到终点的最短(长)距离. 分析设计 ...

  2. 算法-动态规划2图问题-多段图的最短路径问题

    算法-动态规划2-多段图的最短路径问题 多段图的最短路径问题 问题:设图G=(V,E)是一个带权有向图,如果把顶点集合V划分成k个互不相交的子集Vi(2<=k<=n,1<=i< ...

  3. 多段图的动态规划算法(C/C++)

    1. 实验环境 (1)Visual Studio 2019(32位调试器) (2)Windows 10 2. 多段图描述 多段图G = (V,E)是一个带权有向图,它具有以下特性: 图中的节点被划分成 ...

  4. 动态规划求解多段图问题

    动态规划求解多段图问题(非递归) 问题描述 求解思路 动态规划逆序解法 逆序实现代码 动态规划逆序解法 顺序实现代码 问题描述 如图所示,在A处有一水库,现需要从A点铺设一条管道到E点,边上的数字表示 ...

  5. 动态规划求解多段图最短路径

    动态规划求解多段图最短路径 题目: 分析见源代码注释 源代码: #include<stdio.h> #define N 10//定义定点数,编号从1开始 #define M 5//定义层数 ...

  6. 动态规划中的多段图问题

    多段图的最短路径问题:只有相邻的节点之间有联系 多段图的定义: 1.多段图是一个有向.无环.带权 图. 2.有且仅有一个起始结点(原点source) 和 一个终止结点(汇点target). 3.它有n ...

  7. 在c语言中nextarc是什么意思,c语言求解多段图〔向前处理法〕.docx

    c语言求解多段图[向前处理法] #include#include#define Infinity 1000 //无穷大#define Max 45#define null 0 typedef stru ...

  8. 动态规划法——多段图的最短路径

    目录 动态规划法的基本思想 多段图的基本想法 代码块(Java) 运行结果 动态规划法的基本思想: 将大问题划分成若干个小问题进行解决,从而一步步获取最优解 动归从上到下分析问题,从下到上解决问题 动 ...

  9. UVA116 单向 DSP(多段图最短路)

    单向 DSP [题目链接]单向 DSP [题目类型]dp &题解: 紫书P271 这块的字典序排序我觉得挺厉害的,每次都把那3步sort一下,之后if (v< d[i][j]) 这块的小 ...

最新文章

  1. day5 python学习
  2. 【WP 8.1开发】解决摄像头翻转问题(RuntimeApp篇)
  3. 《南方都市报》:中国互联网“公共性”正在变形或流失
  4. python lxml模块解析html_用lxml解析HTML
  5. Linux-ubuntu学习(第一天)
  6. Python中的计数(词频)
  7. 10年Java老鸟忠告:技术人这4个错别再犯了!
  8. 解决清除浮动的最佳办法
  9. java中随机数彩票练习_跪求下面的题目答案
  10. lua脚本语言学习(一)
  11. ArrayList转换类型为DataTable类型
  12. 2017年7月19日晚作业
  13. MATLAB学习笔记——数组
  14. SpringCloud 与 SpringBoot 微服务 架构 | 面试题及答案详解
  15. 如何利用JClassLib修改.class文件
  16. 2022QS世界大学学科排名出炉,计算机学科有哪些信息值得关注?
  17. Spark ML 构建回归模型
  18. 花生壳配置代理域名访问内网API服务
  19. Mysql数据库最佳性能优化
  20. 【新媒体 | 自媒体 运营】虚拟素材(图片,字体,音频,视频)商用及CC版权相关问题

热门文章

  1. 老式马桶水封不足的唯一解决方案
  2. eclipse黑色主题黑色背景
  3. Amdahl定律和Gustafson定律
  4. 在总账模块结账的时候提示总账和明细账对账不平结不了账
  5. 归并排序及其优化(数组归并/链表归并,自顶向下/自底向上等)
  6. 身份证号码组件:lt;idcardgt; —— 快应用组件库H-UI
  7. 介绍一下3D游戏开发的简单常识,以及最终幻想13游戏流程为什么会过于线性的原因。
  8. 液晶电视英文linux使用教程,液晶电视如何使用 液晶电视正确使用方法介绍【详解】...
  9. Cosmos 白皮书
  10. 2020移动apn接入点哪个快_为什么别人的4g网总比你快? 手机这个设置没开启, 难怪网络...