算法设计与分析实验二:动态规划法求解TSP问题和01背包问题

这篇具有很好参考价值的文章主要介绍了算法设计与分析实验二:动态规划法求解TSP问题和01背包问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


【实验内容】
(1)tsp问题:利用动态规划算法编程求解TSP问题,并进行时间复杂性分析。
输入:n个城市,权值,任选一个城市出发;
输出:以表格形式输出结果,并给出向量解和最短路径长度。
(2)01背包问题:利用动态规划算法编程求解0-1背包问题,并进行时间复杂性分析。
输入:n个物品,重量为{w1, w2, … ,wn}、价值为{v1, v2, … ,vn},容量为C的背包;
输出:表格输出结果,并给出向量解和最优值。

【编译环境】devc++ 5.11

【解题思路】
tsp问题:
1.输入图的结点个数和代价矩阵

2.按顺序生成集合的子集

3.动态规划法依次处理子集

4.对于复杂性

【参考内容】
d[i][j]表示从顶点i经过子集v[j]中的顶点一次且仅一次,最后回到出发点0的路径长度。
算法设计与分析实验二:动态规划法求解TSP问题和01背包问题
【代码分析】

一.TSP问题主要解决三个问题

1.顺序表示集合

头文件

#include <stdio.h>
#include<malloc.h>
#include<stdlib.h>

生成集合的函数

long unsigned int* collect(int max)//max表示元素最大值。 
{
	//sum表示子集数量 
	int sum;
	//index指向遍历位置 
	int index = 0; 
	//indexin指向填表位置 
	int indexin = 0;
	//n用来存储中间量 
	unsigned int n=0;
	//组合结果总个数,不包含全空的情况,故减一 
	sum = (int)pow(2,max)-1;
	long unsigned int* col = (long unsigned int*)malloc(sizeof(int)*sum);
	//初始化为二进制1,10,100,1000,10000... 
	//即集合{1,2}表示为011,集合{3}表示为100,通过固定位上是否为1表示集合中是否含有这个数 
	for(int i=0;i<max;i++)
	{
		col[indexin++] = (unsigned int)pow(2,i);
	}
	while(index<=sum)
	{
		for(int i=max-1;i>=0;i--)//从高位判断,集合的最高位方便生成下一位 
		{
			n = (unsigned int)pow(2,i);
			//判断固定位上是否位1 
			if((col[index]&n) != 0 )//!=的优先级大于&运算符的优先级所以要加括号 
			{
				if(i==max-1)
				{
					break;
				}
				for(int j=i+1;j<max;j++)//j<max表示最高生成的集合元素位max 
				{
					//利用加法表示集合001+010相当于集合{1,2} 
					col[indexin++] = col[index]+(unsigned int)pow(2,j);
				}
				break;
			}
		}
		//生成完毕,开始下一次循环 
		index++;
	}
	//方便展示生成的集合 
	/*
	for(int i=0;i<sum;i++)//二进制格式输出 
	{
		char s[max+1];
		itoa(col[i],s,2);
		printf("%s\n",s);
	}
	*/
	return col; 
}

展示生成的集合,形式如下
节点个数为5时:
算法设计与分析实验二:动态规划法求解TSP问题和01背包问题

一些解释
算法设计与分析实验二:动态规划法求解TSP问题和01背包问题

2.从集合中去除一个顶点

因为生成集合的函数使用位数表示集合元素是否存在,所以很方便通过与和非操作去除一个顶点

vindex[j]&(~(long unsigned int)pow(2,h-1))

假设vindex[j]为二进制1111即集合{1,2,3,4}
当h为2时,则pow(2,h-1):10为二进制10即集合{2}
非:1101
再进行与操作:1111与1101->1101即从原集合中去除了元素2。

3.动态规划法依次处理集合和数据

生成数据并初始化第一列数据

头文件和宏定义

#include<time.h> 
#include<random>
#define MAX 999//设置最大权值   
#define MAXNODE 5//节点数 
#define INF 99999//默认最大值 

数据初始化

int main() { 
	int node;
	 
	//自动生成方式
	//数据写入文件 
	FILE* fp = fopen("demo.TXT","w");
	//生成随机数 
	srand((unsigned)time(NULL));
	node = MAXNODE;
	//生成数组矩阵,用一维数组表示二维数组 
	int *d = (int*)malloc(sizeof(int)*999*999);
	for(int i=0;i<node;i++)
	{
		for(int j=0;j<node;j++)
		{ 
			//行列相等默认最大值 
			if(j == i)
				d[i*node+j] = INF;
			else
				d[i*node+j] = rand()%MAX+1;
			fprintf(fp, "%d\t",d[i*node+j]);
			fprintf(fp, " ");
		}
		fprintf(fp, "\n");
	}
	//关闭文件 
	fclose(fp);
	//调用tsp函数 
    tsp(d,node);
}

TSP算法实现

算法实现按照参考图片中第二步

//d表示数组矩阵。n表示节点个数(包括0节点) 
void tsp(int* d,int n)
{
	//数组的索引序号,表示数组处理的顺序 
	long unsigned int*vindex;
	//数组下标代表不同子集,数组存储相应节点对应的最短路径长度 
	int *v = (int*)malloc(sizeof(int)*n*(int)pow(2,n));
	//记录向量解
	int vec[n*(int)pow(2,n)+1]={0}; 
	//初始化
	for(int i=0;i<n;i++)
	{
		v[i*(int)pow(2,n)+0] = d[i*n+0];
		for(int j=1;j<(int)pow(2,n);j++)
		{
			v[i*(int)pow(2,n)+j] = INF;
		}
	}
	//vindex存储的就是遍历子集的顺序,n-1表示子集元素最多为n-1个,0作为出发点 
	vindex = collect(n-1);
	//以下算法每一步都是解释算法书上的伪代码
	int j=0;
	while(j<pow(2,n-1)-1)//依次处理每一个子集数组v[j] 
	{
		if(j==pow(2,n-1)-2)//此时是全集的情况,输出最短路径 
		{
			long unsigned int min=INF;
			int m=0;
			for(int h=1;h<n;h++)//遍历全集中每一个元素
			{
				if(min>d[0*n+h]+v[h*(int)pow(2,n)+(vindex[j]&(~(long unsigned int)pow(2,h-1)))])
				{
					min=d[0*n+h]+v[h*(int)pow(2,n)+(vindex[j]&(~(long unsigned int)pow(2,h-1)))];
					vec[0*((int)pow(2,n)+1)+vindex[j]]=h;
				}				
			}
			v[0*(int)pow(2,n)+vindex[j]]=min;
			
			break;//跳出循环直接输出 
		}
		//开始处理每一个子集
		for(int i=1;i<n;i++)
		{
			if((vindex[j]&(int)pow(2,i-1))==0)//v[j]中不包含i 
			{
				long unsigned int min=INF;
				//对Vindex[j]中每一个元素h,计算v[i][j]=min{d[i][h]+v[h][j-1]}
				for(int h=1;h<n;h++)//遍历每一个元素,计算最小路径 
				{
					if((vindex[j]&(long unsigned int)pow(2,h-1))!=0)//判断元素h在vindex[j]中 
					{
						if(min>d[i*n+h]+v[h*(int)pow(2,n)+(vindex[j]&(~(long unsigned int)pow(2,h-1)))])
						{
							min=d[i*n+h]+v[h*(int)pow(2,n)+(vindex[j]&(~(long unsigned int)pow(2,h-1)))];
							vec[i*((int)pow(2,n)+1)+vindex[j]]=h;
						}
					}
				}
				v[i*(int)pow(2,n)+vindex[j]]=min;
			}
		}
		j++; 
	}
	//打印表格,向量解,最短路径长度 
	printout(d,v,vindex,vec,n);
}

输出函数

void printout(int*d,int*v,unsigned long int*vindex,int*vec,int n)
{
		//输出表格
	printf("\t%-8d",0);
	for(int i=0;i<pow(2,n-1)-1;i++)//二进制格式输出 
	{
		char s[n];
		itoa(vindex[i],s,2);
		printf("%-8s",s);
	}
	printf("\n");
	for(int i=0;i<n;i++)
	{
		printf("%-8d",i);
		if(d[i*n+0]<INF)
			printf("%-8d",d[i*n+0]);
		else
			printf("%-8d",0);
		for(int j=0;j<pow(2,n-1)-1;j++)
		{
			if(v[i*(int)pow(2,n)+vindex[j]]>=INF)
				printf("%-8d",0);
			else
				printf("%-8d",v[i*(int)pow(2,n)+vindex[j]]);
		}
		printf("\n");
	}
	//输出向量解
	//记录每一层循环里最小的值作为下一个节点
	int maxcomb=pow(2,n-1)-2;//减去空集减去全集减去编号从0开始造成的偏移,所以减3 
	int last;
	int nextlast = vec[0*((int)pow(2,n)+1)+vindex[(int)pow(2,n-1)-2]];
	int vecindex= vindex[(int)pow(2,n-1)-2];//全集的第一个向量 
	unsigned long int min;
	printf("向量解:<%d->%d> ",0,nextlast);
	for(int j=n;j>1;j--)//寻找n次向量解,每个阶段一次 
	{
		if(j==2)
		{
			printf("<%d->%d> \n",nextlast,0);
			break;
		}
		last = nextlast;
		vecindex = (vecindex&(~(long unsigned int)pow(2,last-1)));//集合中删除last 
		nextlast = vec[last*((int)pow(2,n)+1)+vecindex]; 
		printf("<%d->%d> ",last,nextlast);
	}
	//输出最短路径长度 
	printf("最短路径:%ld",v[vindex[(int)pow(2,n-1)-2]]);
}

输出

算法设计与分析实验二:动态规划法求解TSP问题和01背包问题

数据

算法设计与分析实验二:动态规划法求解TSP问题和01背包问题

4.复杂度分析

算法设计与分析实验二:动态规划法求解TSP问题和01背包问题

5.TSP问题源代码

#include <stdio.h>
#include<malloc.h>
#include<time.h> 
#include<random>
#include<stdlib.h>
//宏定义区 
#define MAX 99//设置最大权值   
#define MAXNODE 5//节点数 
#define INF 9999//默认最大值 

//全局变量区

//函数声明区
void tsp(int*,int); 
long unsigned int* collect(int);
void printout(int*,int*,unsigned long int*,int*,int);//数组矩阵,子集值,子集索引,子集向量解,最大元素 


int main() { 
	int node;
	 
	//自动生成方式
	//数据写入文件 
	FILE* fp = fopen("demo.TXT","w");
	//生成随机数 
	srand((unsigned)time(NULL));
	node = MAXNODE;
	//生成数组矩阵,用一维数组表示二维数组 
	int *d = (int*)malloc(sizeof(int)*999*999);
	for(int i=0;i<node;i++)
	{
		for(int j=0;j<node;j++)
		{ 
			//行列相等默认最大值 
			if(j == i)
				d[i*node+j] = INF;
			else
				d[i*node+j] = rand()%MAX+1;
			fprintf(fp, "%d\t",d[i*node+j]);
			fprintf(fp, " ");
		}
		fprintf(fp, "\n");
	}
	//关闭文件 
	fclose(fp);
	//调用tsp函数 
    tsp(d,node);
}


long unsigned int* collect(int max)//max表示元素最大值。 
{
	//sum表示子集数量 
	int sum;
	//index指向遍历位置 
	int index = 0; 
	//indexin指向填表位置 
	int indexin = 0;
	//n用来存储中间量 
	unsigned int n=0;
	//组合结果总个数,不包含全空的情况,故减一 
	sum = (int)pow(2,max)-1;
	long unsigned int* col = (long unsigned int*)malloc(sizeof(int)*sum);
	//初始化为二进制1,10,100,1000,10000... 
	//即集合{1,2}表示为011,集合{3}表示为100,通过固定位上是否为1表示集合中是否含有这个数 
	for(int i=0;i<max;i++)
	{
		col[indexin++] = (unsigned int)pow(2,i);
	}
	while(index<=sum)
	{
		for(int i=max-1;i>=0;i--)//从高位判断,集合的最高位方便生成下一位 
		{
			n = (unsigned int)pow(2,i);
			//判断固定位上是否位1 
			if((col[index]&n) != 0 )//!=的优先级大于&运算符的优先级所以要加括号 
			{
				if(i==max-1)
				{
					break;
				}
				for(int j=i+1;j<max;j++)//j<max表示最高生成的集合元素位max 
				{
					//利用加法表示集合001+010相当于集合{1,2} 
					col[indexin++] = col[index]+(unsigned int)pow(2,j);
				}
				break;
			}
		}
		//生成完毕,开始下一次循环 
		index++;
	}
	//方便展示生成的集合 
	/*
	for(int i=0;i<sum;i++)//二进制格式输出 
	{
		char s[max+1];
		itoa(col[i],s,2);
		printf("%s\n",s);
	}
	*/
	return col; 
}

void printout(int*d,int*v,unsigned long int*vindex,int*vec,int n)
{
		//输出表格
	printf("\t%-8d",0);
	for(int i=0;i<pow(2,n-1)-1;i++)//二进制格式输出 
	{
		char s[n];
		itoa(vindex[i],s,2);
		printf("%-8s",s);
	}
	printf("\n");
	for(int i=0;i<n;i++)
	{
		printf("%-8d",i);
		if(d[i*n+0]<INF)
			printf("%-8d",d[i*n+0]);
		else
			printf("%-8d",0);
		for(int j=0;j<pow(2,n-1)-1;j++)
		{
			if(v[i*(int)pow(2,n)+vindex[j]]>=INF)
				printf("%-8d",0);
			else
				printf("%-8d",v[i*(int)pow(2,n)+vindex[j]]);
		}
		printf("\n");
	}
	//输出向量解
	//记录每一层循环里最小的值作为下一个节点
	int maxcomb=pow(2,n-1)-2;//减去空集减去全集减去编号从0开始造成的偏移,所以减3 
	int last;
	int nextlast = vec[0*((int)pow(2,n)+1)+vindex[(int)pow(2,n-1)-2]];
	int vecindex= vindex[(int)pow(2,n-1)-2];//全集的第一个向量 
	unsigned long int min;
	printf("向量解:<%d->%d> ",0,nextlast);
	for(int j=n;j>1;j--)//寻找n次向量解,每个阶段一次 
	{
		if(j==2)
		{
			printf("<%d->%d> \n",nextlast,0);
			break;
		}
		last = nextlast;
		vecindex = (vecindex&(~(long unsigned int)pow(2,last-1)));//集合中删除last 
		nextlast = vec[last*((int)pow(2,n)+1)+vecindex]; 
		printf("<%d->%d> ",last,nextlast);
	}
	//输出最短路径长度 
	printf("最短路径:%ld",v[vindex[(int)pow(2,n-1)-2]]);
}

//d表示数组矩阵。n表示节点个数(包括0节点) 
void tsp(int* d,int n)
{
	//数组的索引序号,表示数组处理的顺序 
	long unsigned int*vindex;
	//数组下标代表不同子集,数组存储相应节点对应的最短路径长度 
	int *v = (int*)malloc(sizeof(int)*n*(int)pow(2,n));
	//记录向量解
	int vec[n*(int)pow(2,n)+1]={0}; 
	//初始化
	for(int i=0;i<n;i++)
	{
		v[i*(int)pow(2,n)+0] = d[i*n+0];
		for(int j=1;j<(int)pow(2,n);j++)
		{
			v[i*(int)pow(2,n)+j] = INF;
		}
	}
	//vindex存储的就是遍历子集的顺序,n-1表示子集元素最多为n-1个,0作为出发点 
	vindex = collect(n-1);
	//以下算法每一步都是解释算法书上的伪代码,vec数组用于后面方便输出
	int j=0;
	while(j<pow(2,n-1)-1)//依次处理每一个子集数组v[j] 
	{
		if(j==pow(2,n-1)-2)//此时是全集的情况,输出最短路径 
		{
			long unsigned int min=INF;
			int m=0;
			for(int h=1;h<n;h++)//遍历全集中每一个元素
			{
				if(min>d[0*n+h]+v[h*(int)pow(2,n)+(vindex[j]&(~(long unsigned int)pow(2,h-1)))])
				{
					min=d[0*n+h]+v[h*(int)pow(2,n)+(vindex[j]&(~(long unsigned int)pow(2,h-1)))];
					vec[0*((int)pow(2,n)+1)+vindex[j]]=h;
				}				
			}
			v[0*(int)pow(2,n)+vindex[j]]=min;
			
			break;//跳出循环直接输出 
		}
		//开始处理每一个子集
		for(int i=1;i<n;i++)
		{
			if((vindex[j]&(int)pow(2,i-1))==0)//v[j]中不包含i 
			{
				long unsigned int min=INF;
				//对Vindex[j]中每一个元素h,计算v[i][j]=min{d[i][h]+v[h][j-1]}
				for(int h=1;h<n;h++)//遍历每一个元素,计算最小路径 
				{
					if((vindex[j]&(long unsigned int)pow(2,h-1))!=0)//判断元素h在vindex[j]中 
					{
						if(min>d[i*n+h]+v[h*(int)pow(2,n)+(vindex[j]&(~(long unsigned int)pow(2,h-1)))])
						{
							min=d[i*n+h]+v[h*(int)pow(2,n)+(vindex[j]&(~(long unsigned int)pow(2,h-1)))];
							vec[i*((int)pow(2,n)+1)+vindex[j]]=h;
						}
					}
				}
				v[i*(int)pow(2,n)+vindex[j]]=min;
			}
		}
		j++; 
	}
	//打印表格,向量解,最短路径长度 
	printout(d,v,vindex,vec,n);
}

二.01背包问题

【解题思路】
1.获取背包容量packvol,物品数量n,物品价值和重量value[],weigth[]

2.动态规划法求解01背包问题

3.对于复杂性
【参考内容】
背包最大价值
算法设计与分析实验二:动态规划法求解TSP问题和01背包问题
装入背包的物品
算法设计与分析实验二:动态规划法求解TSP问题和01背包问题
算法设计与分析实验二:动态规划法求解TSP问题和01背包问题
【代码分析】

1.动态规划法求解背包最大价值

初始化

	//价值矩阵 
	int v[n+1][packvol+1]={0};
	//背包是否装入物品 
	int x[n+1]; 
	//初始化第0行和第0列 
	for(int i=0;i<=packvol;i++)
	{
		v[0][i]=0;
	}
	for(int i=0;i<=n;i++)
	{
		v[i][0]=0;
		x[i]=0;
	}

动态规划法遍历价值矩阵

	//依次遍历数组 
	for(int i=1;i<=n;i++)//物品 
	{
		for(int j=1;j<=packvol;j++)//背包容量 
		{
			if(weight[i-1]>j)//装不下 
				v[i][j]=v[i-1][j];
			if(weight[i-1]<=j)//装的下,继续判断是否最优 
			{
				v[i][j] = v[i-1][j-weight[i-1]]+value[i-1]>v[i-1][j]?v[i-1][j-weight[i-1]]+value[i-1]:v[i-1][j];
			}
		}
	}

2.按要求输出

表格

	//输出表格
	for(int i=0;i<=n;i++)
	{
		for(int j=0;j<=packvol;j++)
		{
			printf("%-4d",v[i][j]);//左对齐输出 
		}
		printf("\n");
	}

向量解

	//向量解
	printf("向量解{行,列}:");
	for(int i=n,j=packvol;i>0;i--)
	{
		printf("{%d,%d}->",i,j);
		if(v[i][j]>v[i-1][j])
		{
			x[i]=1;//参考内容第三个图片 
			j= j-weight[i-1];
		}
		if(i==1)
		{
			printf("{%d,%d}",i-1,j);
		}
	}

最优解和最大价值

	//最优解 
	printf("\n最优解:"); 
	for(int i=1;i<=n;i++)
	{
		printf("%d",x[i]);
	}
	printf("\n最大价值:%d",v[n][packvol]);

输出

算法设计与分析实验二:动态规划法求解TSP问题和01背包问题

数据

算法设计与分析实验二:动态规划法求解TSP问题和01背包问题

3.复杂度分析

算法设计与分析实验二:动态规划法求解TSP问题和01背包问题文章来源地址https://www.toymoban.com/news/detail-438938.html

4.01背包问题源代码

#include<stdio.h>
#include<time.h>
#include<random>

//宏定义区 
#define MAX 60//背包最大容量 
#define MAXN 30//最大物品数 
#define MAXW 7//物品最大重量 
#define MAXV 7//物品最大价值 
//全局变量区 


//自定义函数区 
void randomint(int,int,int*,int*);
void fwritein(int,int,int*,int*);
void Pack(int,int,int*,int*);

int main()
{
	int n,packvol;
	srand(time(NULL));
	n = rand()%MAXN;
	packvol = rand()%MAX+1;
	int w[n],v[n];
	randomint(packvol,n,w,v);
	Pack(n,packvol,w,v);
	return 0;
}
 
void fwritein(int packvol,int n,int* weight,int* value)
{
	FILE* fp = fopen("demo2-2.TXT","w");
	fprintf(fp,"背包容量:%d\n",packvol);
	fprintf(fp,"物品数量:%d\n",n);
	for(int i=0;i<n;i++)
	{
		fprintf(fp,"%d\t%d\t%d\n",i,weight[i],value[i]);
	}
	fclose(fp);
}

void randomint(int packvol,int n,int* weight,int* value)
{
	for(int i=0;i<n;i++)
	{
		weight[i]=rand()%MAXW+1;
		value[i]=rand()%MAXV+1;
	}
	fwritein(packvol,n,weight,value);
	return;
}

void Pack(int n,int packvol,int* weight,int* value)
{
	int v[n+1][packvol+1]={0};
	int x[n+1]; 
	for(int i=0;i<=packvol;i++)
	{
		v[0][i]=0;
	}
	for(int i=0;i<=n;i++)
	{
		v[i][0]=0;
		x[i]=0;
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=packvol;j++)
		{
			if(weight[i-1]>j)
				v[i][j]=v[i-1][j];
			if(weight[i-1]<=j)
			{
				v[i][j] = v[i-1][j-weight[i-1]]+value[i-1]>v[i-1][j]?v[i-1][j-weight[i-1]]+value[i-1]:v[i-1][j];
			}
		}
	}
	for(int i=0;i<=n;i++)
	{
		for(int j=0;j<=packvol;j++)
		{
			printf("%-4d",v[i][j]);
		}
		printf("\n");
	}
	printf("向量解{行,列}:");
	for(int i=n,j=packvol;i>0;i--)
	{
		printf("{%d,%d}->",i,j);
		if(v[i][j]>v[i-1][j])
		{
			x[i]=1;
			j= j-weight[i-1];
		}
		if(i==1)
		{
			printf("{%d,%d}",i-1,j);
		}
	}
	printf("\n最优解:"); 
	for(int i=1;i<=n;i++)
	{
		printf("%d",x[i]);
	}
	printf("\n最大价值:%d",v[n][packvol]);
}


到了这里,关于算法设计与分析实验二:动态规划法求解TSP问题和01背包问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 矩阵链相乘(动态规划法)

    矩阵链乘法是耳熟能详的问题了,有很多矩阵,排列成矩阵链,矩阵链的要求是相邻的两个是可以相乘的,可以相乘是有条件的,两个矩阵能够相乘的条件就是行、列之间是有关系的,两个矩阵如果能够相乘,就是前面矩阵的列号和后面矩阵的行号是一致的。 如何确定矩阵的

    2024年02月09日
    浏览(33)
  • C++每日一练:打家劫室(详解动态规划法)

    这题目出得很有意思哈,打劫也是很有技术含量滴!不会点算法打劫这么粗暴的工作都干不好。 提示:以下是本篇文章正文内容,下面案例可供参考 题目名称: 打家劫舍 题目描述: 一个小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素

    2024年02月02日
    浏览(30)
  • 最优控制理论 九、Bellman动态规划法用于最优控制

    尽管DP也是最优控制理论的三大基石之一,但长久以来,动态规划法(Dynamic Programming)被认为只能在较少控制变量的多阶段决策问题中使用,维数灾难使他不可能搜索得了整个连续最优控制问题的高维状态空间,因此仍然只能在一些维数较低的离散决策变量最优选择中取得较好

    2024年02月01日
    浏览(33)
  • 算法分析与设计——动态规划求解01背包问题

    假设有四个物品,如下图,背包总容量为8,求背包装入哪些物品时累计的价值最多。 我们使用动态规划来解决这个问题,首先使用一个表格来模拟整个算法的过程。 表格中的信息表示 指定情况下能产生的最大价值 。例如, (4, 8)表示在背包容量为8的情况下,前四个物品的最

    2024年02月04日
    浏览(41)
  • 算法设计与分析实验---动态规划

    任务描述 沿着河岸摆放 N 堆石子,现要将石子有次序地合并成一堆,规定每次只能选相邻的 2 堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。 例如: 4 堆石子 4,5,9,4 ,可以按 (((4,5),9),4) 合并。 第一次合并得分是 9 分,合并之后石子堆是 9,9,4 第二次合并得

    2024年02月08日
    浏览(32)
  • 算法设计与分析 实验三 动态规划

    1.打家劫舍:  给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 入: 每组测试案例有两行,第一行只有一个整数N,代表着有N间房屋 第二行有N个整数,代表着每间房屋里的金额,金额范围[0, 1000]。 出:

    2024年01月24日
    浏览(59)
  • 算法设计与分析实验:动态规划与贪心

    目录 一、零钱兑换 1.1 思路一:动态规划 1.2 思路二:贪心 二、安排工作以达到最大效益 2.1 具体思路 2.2 思路呈现 2.3 代码实现 2.4 复杂度分析 2.5 运行结果 三、雇佣k名工人的最低成本 3.1 具体思路 3.2 思路展示 3.3 代码实现 3.4 复杂度分析 3.5 运行结果 结尾语 “生活有意思的

    2024年02月19日
    浏览(34)
  • 算法设计与分析—动态规划作业一(头歌实验)

    任务描述 本关任务:求一个序列的最长上升子序列。 相关知识 最长上升子序列问题 当一个序列 Bi 满足 B1 B2 ... Bs 的时候,我们称这个序列是 上升 的。对于给定的一个序列 a1, a2, ..., aN ,我们可以在其中找到一些上升的子序列。 现在给你一个序列,请你求出其中 最长 的上

    2024年02月04日
    浏览(87)
  • 算法设计与分析—动态规划作业二(头歌实验)

    任务描述 本关任务:计算寻宝人所能带走的宝物的最大价值。 一个寻宝人在沙漠中发现一处神秘的宝藏,宝藏中共有 n 个宝物( n 不超过 20 ),每个宝物的重量不同,价值也不同,宝物 i 的重量是 wi ,其价值为 vi 。 寻宝人所能拿走的宝物的总重量为 m ( m 不超过 50 )。请

    2024年02月06日
    浏览(53)
  • 湘潭大学 算法设计与分析实验 回溯 动态规划 贪心 模拟退火解决背包问题

    https://download.csdn.net/download/SQ_ZengYX/88620871 测试用例

    2024年02月02日
    浏览(44)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包