动态规划多段图和货郎担问题

这篇具有很好参考价值的文章主要介绍了动态规划多段图和货郎担问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、实验目的

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;
}

运行结果示例:
货郎担问题动态规划,算法分析设计,动态规划,算法,c++
2.货郎担问题文章来源地址https://www.toymoban.com/news/detail-739821.html

#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;
}

到了这里,关于动态规划多段图和货郎担问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 动态规划课堂5-----子序列问题(动态规划 + 哈希表)

    目录 引言: 例题1:最长递增子序列 例题2:最长定差子序列 例题3:最长的斐波那契子序列的长度 例题4:最长等差数列 例题5:等差数列划分II-子序列 结语: 要想解决子序列问题那么就要理解子序列和子数组的区别,二者的定义如下。 子序列: 是由数组派生而来的序列,

    2024年03月13日
    浏览(65)
  • 动态规划问题实验:数塔问题

    动态规划是一种解决复杂问题的方法,它将一个问题分解为若干个子问题,然后从最简单的子问题开始求解,逐步推导出更复杂的子问题的解,最终得到原问题的最优解。动态规划的关键是找到子问题之间的递推关系,以及确定合适的边界条件和初始值。 数塔问题是一个经典

    2024年02月10日
    浏览(39)
  • 动态规划详细讲解c++|经典例题讲解认识动态规划|0-1背包问题详解

    uu们,你们好!这次的分享是动态规划,其中介绍了动态规划的相关概念和做题模板(三要素),同时为了uu们对动态规划方法有更加形象的认识,特地找了两个经典问题,和大家一起分析。并且呢,为了大家检验自己的学习成果,我专门在常用的oj上为uu们找到了相关题目的

    2024年04月11日
    浏览(56)
  • 租用游艇问题 石子合并问题 动态规划实验

    实验名称:                动态规划                          一、实验预习 1、实验目的 1. 理解并掌握动态规划方法的设计思想; 2. 提高应用动态规划方法解决问题和设计算法的能力; 3. 通过编程实现租用游艇问题和石子合并问题,进一步理解动态规划方

    2024年02月07日
    浏览(45)
  • 动态规划专题——背包问题

    🧑‍💻 文章作者:Iareges 🔗 博客主页:https://blog.csdn.net/raelum ⚠️ 转载请注明出处 本文主要介绍常见的四种背包问题,思维导图如下: 💡 现有 N N N 件物品和一个最多能承重 M M M 的背包,第 i i i 件物品的重量是 w i w_i w i ​ ,价值是 v i v_i v i ​ 。在背包能承受的范围内

    2024年02月03日
    浏览(41)
  • 动态规划(01背包问题)

    本文默认读者具有动态规划前置知识 动态规划的特点: 重叠子问题 状态转移方程 最优子结构 题型: 求最值 解题套路: 明确【状态】 明确【选择】 明确dp函数/数据的定义 明确base case 例:给你一个可装载容量为W的背包和N个物品,每个物品有重量和价值两个属性。其中第

    2024年04月16日
    浏览(37)
  • 动态规划——01背包问题

    由于本人实力尚浅,接触算法没多久,写这篇blog仅仅是想要提升自己对算法的理解,如果各位读者发现什么错误,恳请指正,希望和大家一起进步。(●’◡’●) 状态表示 :用一个数组 f[][] (数组可能是一维也可能是二维,根据具体题目具体分析)来表示某个集合,这个集合

    2024年02月03日
    浏览(42)
  • 动态规划——回文串问题

    目录 练习1:回文子串 练习2:最长回文子串 练习3:回文串分割IV 练习4:分割回文串 练习5:最长回文子序列 练习6:让字符串成为回文串的最小插入次数 本篇文章主要学习使用动态规划来解决回文串相关问题,我们通过相关练习来学习 题目链接: 647. 回文子串 - 力扣(Le

    2024年04月09日
    浏览(35)
  • 动态规划——零钱兑换问题

    1、题目 :力扣原题 2、分析 (1)结合我们之前分析的(动态规划解决背包问题),这里硬币有无限个对应完全背包问题。但又存在一点区别: 纯完全背包是能否凑成总的金额,本题是要求凑成总金额的组合个数 。 (2)要注意是求解组合 还是排列 问题。例如 221 和121可以

    2024年02月04日
    浏览(39)
  • 点菜问题动态规划

    ‏ “因为疫情问题,某公司员工就餐时需通过APP点外卖。每次点外卖的报销金额最大为M元,有N种菜品可以点,每种菜i都有一个评分Pi(即表示菜的受欢迎程度),每种菜i的价格为Vi。现该公司员工如何选择各种菜,能够在报销额度范围内使点到的菜的总评分最大。注意:由

    2024年02月12日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包