算法设计与分析实验报告c++实现(矩阵链相乘、投资问题、完全背包问题、数字三角形、最小生成树、背包问题)

一、实验目的

1.加深学生对分治法算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;
2.提高学生利用课堂所学知识解决实际问题的能力;
3.提高学生综合应用所学知识解决实际问题的能力。

二、实验任务

用动态规划算法实现:

1、矩阵链相乘问题

image-20240403221859941

2、投资问题

image-20240403221853588

3、求解完全背包问题

问题描述:有n种重量和价值分别为wivi(1≤in)的物品,从这些物品中挑选总重量不超过W的物品,求出挑选物品价值总和最大的挑选方案,这里每种物品可以挑选任意多件。4、数字三角形
问题描述:在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或右下走。

4、数字三角形

问题描述:在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或右下走。

image-20240403221846682

用贪心算法实现:

5、最小生成树问题(Prim算法和Kruskal算法)

设G=(V,E)是一个无向连通网,生成树上各边的权值之和称为该生成树的代价,在G的所有生成树中,代价最小的生成树称为最小生成树(Minimal Spanning Trees)。

6、背包问题
【问题描述】设有编号为1、2、…、n的n个物品,它们的重量分别为w1、w2、…、wn,价值分别为v1、v2、…、vn,其中wi、vi(1≤i≤n)均为正数。
有一个背包可以携带的最大重量不超过W。求解目标:在不超过背包负重的前提下,使背包装入的总价值最大(即效益最大化),与0/1背包问题的区别是,这里的每个物品可以取一部分装入背包。

三、实验设备及编程开发工具

实验设备:惠普Win10电脑
开发工具:Java和python环境下,eclipse和pycharm编程工具

四、实验过程设计(算法思路及描述,代码设计)

一.矩阵相乘问题

基本原理和思路:
1、动态规划的第一步:寻找最优子结构。为方便起见,使用Ai…j表示AiAi+1…Aj的乘积结果矩阵。对于k(i<=k<j), 计算Ai…j所需要的计算量为:Ai…k 和 Ak+1…j 以及二者相乘的代价和。
2、设m[i][j]为Ai…j的最优计算顺序所要花费的代价。则其求解公式为:
if i == j, m[i][j] = 0; //因为只有一个矩阵时计算代码为0,即不需要计算。
m[i][j]=min{m[i][k] + m[k+1][j] + Pi-1PkPj} i<=k<j
3、为了能够输出求解顺序,需要保存区间中的一些分割点。假如Ai…j中的最优分割点为k,则我们使用s[i][j]=k。即在Ai…j中,分别计算Ai…k 和 Ak+1…j 所用的计算开销最小。
4、采用自底向上的表格法。依次求解矩阵长度为2,3,…,n的最优计算顺序。

代码实现如下:

#include <stdio.h>
int m[1002][1002],s[1002][1002];
void matrix_chain(int a[], int n)
{int l, i, j, k, tmp;for(l=2; l<=n; l++){for(i=1; i<=n-l+1; i++)		//长度为l的区间,其最小下标为1~n-l+1{j=i+l-1;m[i][j] = 0x7fffffff;for(k=i; k<j; k++)		//i~k, k+1~j, 所以k<j{tmp = m[i][k]+m[k+1][j]+a[i-1]*a[k]*a[j];if(tmp < m[i][j]){m[i][j] = tmp;s[i][j] = k;}}}}}
void print(int i, int j)
{if(i == j)printf("A%d",i);else{printf("(");print(i, s[i][j]);print(s[i][j]+1, j);printf(")");}
}
int main()
{int n, a[1002];int i,j,l;while(scanf("%d",&n)==1)	//输入有n个矩阵{for(i=0; i<n+1; i++)scanf("%d",&a[i]);//memset(m, 0x7fffffff,sizeof(m));for(i=0; i<n+1; i++)m[i][i] = 0;matrix_chain(a, n);printf("%d\n",m[1][n]);print(1, n);printf("\n");}return 0;
}

img

分析:时间复杂度为O(N3), 我们只需要存储一个矩阵就可以了,所以空间复杂度是 O(N2)。

二.投资问题

基本原理和思路:假设分配给第 i 个项目的钱数是 xi,问题描述为:
目标函数:max{f1(x1)+f2(x2)+…+fn(xn)}
约束条件:x1+x2+…+xn=m,xi∈N;设Fk(x)表示x元投给前k个项目的最大效益,k=1,2,…,n,x=1,2,…,m递推方程:Fk(x)=max{fk(xk)+Fk-1(x-xk)}(0≤xk≤x),k=2,3,…,n边界条件:F1(x)=f1(x),Fk(0)=0,k=1,2,…,n*说明:第k步,前后共分配x万元,分配给第k个项目xk;x-xk万元,分配给前k-1个项目;

代码实现如下:

#include <iostream>
#include <vector>using namespace std;int main() {int m, n;//m元钱,n项投资int i, j;int tmp_m, tmp_F = 0;cout << "请输入投资金额和项目数" << endl;cin >> m >> n;vector<vector<int>> f(n, vector<int>(m + 1));//f[i][x], 0<i<=n,0<=x<=m;vector<vector<int>> F(n, vector<int>(m + 1));//F[i][x],将x元钱投入到前i个项目上最大的收益//在第(i+1)个项目上投入0元,收益为0,注意i从0开始for (i = 0; i < n; i++) {f[i][0] = 0;}cout << "请输入各项目对应投资金额的收益(从1开始)" << endl;for (i = 0; i < n; i++) {for (j = 1; j < m + 1; j++) {cin >> f[i][j];}}//初始化,给F[0][0-m]赋值for (j = 0; j < m + 1; j++) {F[0][j] = f[0][j];//第一个项目上投入0-m元钱的最大收益等于f[0][0-m]}for (i = 1; i < n; i++) {//项目编号,从1开始for (j = 0; j < m + 1; j++) {//钱数,从0开始for (tmp_m = 0; tmp_m <= j; tmp_m++) {//递推公式tmp_F = F[i - 1][j - tmp_m] + f[i][tmp_m];//取最大值if (tmp_F > F[i][j]) {F[i][j] = tmp_F;}	}}}cout << "最大总收益: " << F[n - 1][m] << endl;
}

分析:复杂度 W(n,m)=O(nm2)。

三. 求解完全背包问题

基本原理和思路:1.设置动态规划二维数组dp,dp[i][j]表示从前i个物品中选出重量不超过j(或者剩余容量为j)的物品的最大总价值。
①显然有边界条件:dp[i][0]=0(背包不能装入任何物品时,总价值为0),dp[0][j]=0(没有任何物品可装入时,总价值为0),可以采用memset函数一次性初始化为0.
②另外设置二维数组fk,其中fk[i][j]存放dp[i][j]得到最大值时物品i挑选的件数。

代码实现如下:

//求解完全背包问题的算法
#include <stdio.h>
#include <string.h>
#define MAXN 20				//最多物品数
#define MAXW 100			//最大限制重量
#define max(x,y) ((x)>(y)?(x):(y))
//问题表示
int n,W;
int w[MAXN],v[MAXN];
//求解结果表示
int dp[MAXN+1][MAXW+1],fk[MAXN+1][MAXW+1];
int solve()					//求解多重背包问题
{int i,j,k;for (i=1;i<=n;i++){for (j=0;j<=W;j++)for (k=0;k*w[i]<=j;k++){if (dp[i][j]<dp[i-1][j-k*w[i]]+k*v[i]){dp[i][j]=dp[i-1][j-k*w[i]]+k*v[i];fk[i][j]=k;		//物品i取k件}									}}return dp[n][W];
}
void Traceback()				//回推求最优解
{int i=n,j=W;while (i>=1){printf("物品%d共%d件 ",i,fk[i][j]);j-=fk[i][j]*w[i];		//剩余重量i--;}printf("\n");
}
void prin(){   //查看dp数组与fk数组 int i,j,k;printf("fk[i][j]:\n");for (i=1;i<=n;i++){for (j=0;j<=W;j++){printf("%d ",fk[i][j]);}printf("\n");}printf("dp[i][j]:\n");for (i=1;i<=n;i++){for (j=0;j<=W;j++){printf("%d ",dp[i][j]);}printf("\n");}
}
int main()
{w[1]=3; w[2]=2; w[3]=6;w[4]=2;v[1]=7; v[2]=2; v[3]=5;v[4]=3;n=4; W=9;memset(dp,0,sizeof(dp));memset(fk,0,sizeof(fk));printf("最优解:\n");printf("  总价值=%d\n",solve());printf("  方案: ");Traceback();printf("\n");prin();return 0;
} 

img

分析:空间复杂度O(nV) 时间复杂度O(nV)。

四.数字三角形

基本原理和思路:MaxSum(i,j):从第i行j列到底边的最大数字之和
从最后一行开始递推,MaxSum(n,j)=D(n,j)//n行j列,MaxSum(n-1,j) = D(n-1,j) + max( MaxSum(n,j) , MaxSum(n,j+1) )
然后为了减少空间,不需要用二维数组来存储MaxSum(n,j)的值,只需要求MaxSum(n,j)的时候存储下一行MaxSum(n+1,j)的值就可以,然后计算完第n行的MaxSum之后再覆盖原来的第n+1行的MaxSum的值。

代码实现如下:

#include <iostream>
#include <algorithm>
using namespace std;
#define Max 101
int D[Max][Max];
int n;
int maxSum[Max][Max];
int MaxSum(int i,int j)
{if(maxSum[i][j]!=-1)return maxSum[i][j];if(i==n)maxSum[i][j]=D[i][j];else{int x=MaxSum(i+1,j);int y=MaxSum(i+1,j+1);maxSum[i][j]=max(x,y)+D[i][j];}return maxSum[i][j];
}
int main()
{int i,j;cin>>n;for(i=1;i<=n;i++)for(j=1;j<=i;j++){cin>>D[i][j];maxSum[i][j]=-1;}cout<<MaxSum(1,1)<<endl;return 0;
}

分析:时间复杂度是n2。

五.最小生成树问题

prim算法

基本原理和思路:设G=(V, E)是具有n个顶点的连通网,
T=(U, TE)是G的最小生成树,
T的初始状态为U={u0}(u0∈V),TE={ },
重复执行下述操作:
在所有u∈U,v∈V-U的边中找一条代价最小的边(u, v)并入集合TE,同时v并入U,直至U=V。
数组lowcost[n]:用来保存集合V-U中各顶点与集合U中顶点最短边的权值,lowcost[v]=0表示顶点v已加入最小生成树中;
数组adjvex[n]:用来保存该边所依附的(集合V-U中各顶点与集合U中顶点的最短边)集合U中的顶点。

代码实现如下:

void prime(MGraph G){for(int i=1;i<G.vertexNu;i++){lowcost[i]=G.arc[0][i];  adjvex[i]=0;}lowcost[0]=0;for(i=1;i<G.vertexNum;i+++){k=MinEdge(lowcost,G.vertexNum)cout<<K<<adjvex[k]<<lowcost[k];lowcost[k]=0;for(j=1;j<G.vertexNum;j++)if((G.arc[k][j]<lowcost[j]){lowcost[j]=G.arc[k][j];arcvex[j]=k;}
}

六.背包问题

基本原理和思路:利用动态规划思想 ,子问题为:f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。其状态转移方程是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]} //这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只和前i-1件物品相关的问题。
1.如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为f[i-1; v];
2.如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为
v-Ci的背包中”,此时能获得的最大价值就是f[i-1][v-c[i]]再加上通过放入第i件物品获得的价值Wi

代码实现如下:

int n = 5;
double W = 100;
struct NodeType
{double w;double v;double p;bool operator<(const NodeType &s)const{return p > s.p;}
};NodeType A[] = { {0},{10,20},{20,30},{30,66},{40,40},{50,60} };
double V;
double x[MAXN];void Knap()
{V = 0;double weight = W;memset(x, 0, sizeof(x));int i = 1;while (A[i].w < weight)//物品可以全部装入{x[i] = 1;weight -= A[i].w;V += A[i].v;i++;}if (weight > 0)//余下物品重量大于0{x[i] = weight / A[i].w;V += x[i] * A[i].v;}
}

分析:时间复杂度为O(nlog2n)

实验小结(包括问题和解决方法、心得体会等)

经过这次试验收获颇多,代码实现过程中也遇到一些问题,有的问题确实也有一定的难度,所以也是通过了网络搜索才得出的解决方案,思维上得到了很好的训练,同时也明白了一个道理:纸上得来终觉浅,绝知此事要躬行。尤其是算法和编程这门课程更是要勤于动手方能获得收获。希望下次实验或者之后的编程学习能吸取这些教训。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/821317.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[RK3399 Linux] 使用busybox 1.36.1制作rootfs

一、 编译、安装、配置 busybox 1.1 下载源码 根文件系统是根据busybox来制作的。 下载地址:https://busybox.net/downloads/。 这里就以1.36.1版本为例进行编译安装介绍: 注意:编译linux内核与文件系统中的所有程序要使用相同的交叉编译器。 下载完成后解压: mkdir …

java(网络编程)

什么是网络编程? 在网络通信协议下&#xff0c;不同计算机上运行的程序&#xff0c;进行的数据传输。 应用场景&#xff1a;即时通信、网游对战、金融证券、国际贸易、邮件、等等 不管是什么场景&#xff0c;都是计算机跟计算机之间通过网络进行数据传输 Java中可以使用ja…

vue3: 报错ResizeObserver loop completed with undelivered notifications.解决方法

错误提示&#xff1a; 组件重新绘制大小时dev环境出现报错提示&#xff0c;如在VUE3中使用ant-design-vue表格自适应窗口大小时webpack会报错。 常用解决方案有重写ResizeObserver或者时间间隔内限制执行方式&#xff0c;可以设置屏蔽方式跳过提示。 解决办法&#xff1a; 修…

汽车车灯用肖特基二极管,选什么型号好?

肖特基二极管种类繁多&#xff0c;有低压降肖特基二极管、通用型肖特基二极管、快速恢复型肖特基二极管、高功率肖特基二极管、汽车级肖特基二极管等等&#xff0c;其中低压降肖特基二极管和汽车级肖特基二极管是二极管厂家东沃电子的核心优势产品。关于东沃电子推出的低压降肖…

移动硬盘无法打开?别慌!这里有救星!

移动硬盘作为现代生活中重要的数据存储工具&#xff0c;承载着我们大量的文件和数据。然而&#xff0c;有时我们会遇到移动硬盘无法打开的情况&#xff0c;这往往让人焦虑不已。那么&#xff0c;当移动硬盘无法打开时&#xff0c;我们应该如何应对呢&#xff1f; 移动硬盘无法打…

量子城域网系列(五):几种典型的量子密钥分发网络组网结构

在上之前文章中&#xff0c;我们介绍了最基本的点对点量子保密通信网络形式以及组网方案&#xff0c;但是显然在实际的应用中&#xff0c;点对点的通信是比较少的&#xff0c;大多还是需要多个终端进行互联才能构成网络。本文我们就讨论一下几种基础的量子密钥分发网络组网结构…

软件测试---性能测试

1.常见的性能问题有哪些 如图所示 系统内部以及软件的代码实现 1&#xff0c;资源泄漏&#xff0c;包括内存泄漏。 2&#xff0c;CPU使用率达到100%&#xff0c;系统被锁定等。 3&#xff0c;线程死锁&#xff0c;阻塞等造成系统越来越慢。 4&#xff0c;查询速度慢&#xff0c…

算法练习第17天|104.二叉树的最大深度 、559.N叉树的最大深度

104.二叉树的最大深度 104. 二叉树的最大深度 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/maximum-depth-of-binary-tree/description/ 什么是二叉树的深度和高度&#xff1f; 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。最大深度…

C语言复习1

1.stdint.h C99库的作用是统一类型别名&#xff0c;例如要定义一个有符号的整数类型&#xff0c;即输入int32_t。 2.位操作 3.宏定义 格式&#xff1a;define 标识符 字符串 标识符&#xff1a;宏定义的名字 字符串&#xff1a;常数&#xff0c;表达式&#xff0c;格式串等 …

入侵检测数据预处理 特征工程 面临的问题

数据预处理 对于分类任务来说,由于原始数据可能存在异常、缺失值以及不同特征的取值范围差 异大等问题,对机器学习会产生影响,因此,在进行机器学习模型训练之前,需要先对数据 进行预处理。数据预处理的主要过程包括数据清洗、去量纲、离散化等。 1.数据清洗 对采集到的数据进行…

Element-Ui的Form表单:Label文本两端对齐,且必填项的*不影响布局

1. HTML 结构 首先&#xff0c;确保你的 HTML 或 Vue 模板中有一个 el-form 组件&#xff0c;类似下面这样&#xff1a; <div id"app"><el-form :model"form" label-width"100px"><el-form-item label"用户名">&l…

Mac搭建Java环境【环境搭建】

Mac搭建Java环境【环境搭建】 1 安装Java SDK 官网地址&#xff1a;https://www.oracle.com/java/technologies/downloads/archive/ 下载dmg&#xff0c;双击之后无脑安装即可。 # 进入 JDK 安装目录 cd /Library/Java/JavaVirtualMachines# 查看文件 ls# 输入 cd ~# 打开环…

别踩白块web小游戏

整体思路 1.设置一个游戏界面main&#xff08;最外面一圈方框&#xff09; 2.main内部放置一个容器container&#xff0c;容器非常长&#xff0c;且容器底部位于main的顶部 3.将容器内的黑块和白块事先处理好&#xff0c;并将黑块存储在黑块数组中 容器黑白块处理&#xf…

【开发问题记录】Nacos修改服务实例权重时报错

问题记录 一、问题描述1.1 产生原因1.2 产生问题 二、问题解决2.1 docker部署的nacos解决方案2.1.1 进入nacos容器2.1.2 查看当前目录2.1.3 进入data文件夹2.1.4 删除protocol文件2.2 本地部署的nacos 一、问题描述 1.1 产生原因 在运行项目时&#xff0c;在本地启动了一个服务…

vue3项目 使用 element-plus 中 el-collapse 折叠面板

最近接触拉了一个项目&#xff0c;使用到 element-plus 中 el-collapse 折叠面板&#xff0c;发现在使用中利用高官网多多少少的会出现问题。 &#xff08;1.直接默认一个展开值&#xff0c;发现时显时不显 2 . 数据渲染问题&#xff0c;接口请求了&#xff0c;页面数据不更新 …

大数据平台搭建2024(一)

一&#xff1a;基础配置 创建虚拟机并查出ip地址进行连接 ip a1.配置node01静态ip地址与主机名 vi /etc/sysconfig/network-scripts/ifcfg-ens33修改或添加如下内容&#xff1a; BOOTPROTO"static" ONBOOTyes #根据虚拟机网卡信息配置 IPADDR192.168.200.141 NET…

360度VR全景汽车漫游展示让爱车者能感受真实的驾驶体验

小米汽车的惊艳亮相&#xff0c;让无数爱车族心潮澎湃。然而&#xff0c;对于因时间和地理限制无法亲临现场的人来说&#xff0c;这份激动或许带有些许遗憾。如今&#xff0c;有了3D虚拟看车软件&#xff0c;这一切不再是问题。 web3D开发公司深圳华锐视点通过运用尖端的web3D开…

IntelliJ IDEA2024 安装包(亲测可用)

目录 一、软件简介 二、软件下载 一、软件简介 IDEA&#xff08;Integrated Development Environment for Apache&#xff09; 是一款专为 Apache 开发者设计的集成开发环境。该软件提供了丰富的功能和工具&#xff0c;帮助开发者更高效地创建、调试和部署 Apache 项目。 主…

hot100 -- 链表(中)

不要觉得力扣核心代码模式麻烦&#xff0c;它确实比不上ACM模式舒服&#xff0c;可以自己处理输入输出 只是你对 链表 和 return 的理解不到位 &#x1f442; ▶ 屿前世 (163.com) &#x1f442; ▶ see you tomorrow (163.com) 目录 &#x1f382;两数相加 &#x1f6a9;删…

python 绘制六种激活函数(sigmoid、tanh、relu、softmax、relu、elu)

1、效果 2、实现代码&#xff08;带注释&#xff09; import numpy as np # 导入 numpy 库, 用于数学运算 import matplotlib.pyplot as plt # 导入 matplotlib.pyplot, 用于绘图 import matplotlib as mpl # 导入 matplotlib 库, 用于图形配置plt.rcParams[font.sans-se…