搜索

深度优先与广度优先遍历在树与图中的应用
本文介绍了树与图的深度优先遍历和广度优先遍历,阐述了邻接表的存储方式。深度优先遍历通过递归沿着一条边走下去,而广度优先遍历则利用队列进行。此外,文章还提及了时间戳的概念,树的深度计算,树的重心定义,以及双端队列在寻找最短路径问题中的应用,强调了双端队列保持的‘两端性’和‘单调性’确保找到最短路径。

树与图的深度优先遍历

深度优先遍历,就是把每个顶点的x上面对每个分支时,任意 选一条边走下去,执行递归,直至回溯之后,在考虑其他边的走向
通常在图与树中使用邻接表来存储
那么head为表头数组,ver edge就是用来存储权值和终点
自己理解的邻接表靠的是存储边的编号来存图,比较抽象,但是以此遍历编号,head存编号,头节点在e的编号,每个e再存上一条边,以此循环直至为0(有人喜欢设置为-1)。next存储的上一条边的编号,head存储以这个点开始的最后一个边编号

void dfs(int x)//遍历边
{
	v[x]=1;
	for(int i=head[x];i;i=next)//从最后一个开始知道第一个,每次向前一个获取编号
	{
		int y=edge[i].ver;//获取权值
		dfs(y);
	}
}
void add(int x,int y,int z)//存储边
{
	tot++;//编号
	e[tot].to=y;
	edge[tot].ver=z;
	edge[tot].next=head[x];//上一条边
	head[x]=tot;//最后一条边
}

树与图的广度优先遍历

这种遍历我们已经很了解了,这种实现需要一种队列进行实现,在BFS中不断从队列中取队首x,对x的多条分支,沿着每条分支到达的下一个节点(也就是连边)插入队尾,重复执行过程直至队列为空
这个知识点我们早就了解,这里就不再详细介绍
BFS满足两端性和单调性

void bfs()
{
	msmset(d,0,sizeof(d));
	queue<int> q;
	q.push(1);
	d[1]=1;//记录层数
	while(q.empty()==0)
	{
		int x=q.front();q.pop();
		for(int i=head[x];i;i=next[i])
		{
			int y=edge[i].ver;
			if(d[y]) continue;
			d[y]=d[x]+1;//记录层数
			q.push(y);//继续入队
		}
	}
}

时间戳

按照深搜的过程,按照每个节点第一次被访问的顺序,以此给n个节点进行标记,这个标记就叫做时间戳,记作dfn。怎么说是第一次,因为我们知道一个点不可能只会被访问1次,肯定会被回溯,所有我们留第一次的顺序

树的深度

树当然是有深度的,如果用手算直接使用log来求就好了
树中的个节点深度是一种自顶向下的统计信息,一开始我们知道根节点深度0,每个节点x的深度为d[x],那么他的子节点y的深度d[y]=d[x]+1,结合自顶向下这一条件就能求出来了

void dfs(int x)
{
	v[x]=1;//标记已经访问
	for(int i=head[x];i;i=next[i])
	{
		int y=edge[i].ver;
		if(v[y]) continue;
		d[y]=d[x]+1;//计算层数
		dfs(y);
	}
}

树的重心

也有许多的信息是自底向上进行统计的,比如每个节点x为根的子树大小
对于一个节点x,如果我们把它从树中删除,那么原来的一棵树可能会分成若干个不相连的部分,其中每一部分都是子树,设maxpart函数表示在删除节点x后产生的子树中,最大的一颗的大小,那么x就是重心

void dfs(int x)
{
	v[x]=1;
	size[x]=1;//假设子树的大小
	int maxpart=0;//假设,预处理
	for(int i=head[x];i;i=next[i])
	{
		int y=edge[i].ver;
		if(v[y]) continue;
		dfs(y);
		size[x]+=size[y];
		maxpart=max(maxpart,size[y]);//获取最大的子树
	}
	maxpart=max(maxpart,n-size[x]);//删除这个点最大值
	if(maxpart<ans)//这里为什么记录小一点的?
	//
	{
		ans=maxpart;//记录对应长度
		pos=x;//记录重点
	}
}
2021.5.9修改

双端队列BFS

在一张图中,边权可能是1或0,现在我们想从某个节点到另一个节点,怎么样才能使路径边权值和最大?

这只是一个例题,大部分题就是一个抽象形式,很多抽象问题都可以转成这个模型
双端队列(STL dequeue),就是说这种结构可以从队首入队可以从队尾出队
这道题让谁想都知道最短路径,但是我们要用的并不是它
那么使用双端队列怎么完成?
由于这是一张边权要么是0要么是1的图,我们可以通过双端队列广搜来计算,算法的整体框架与一般广搜类似,只是要在每个节点沿分支拓展的时候稍稍作改变,如果 这条分支边权为0,那么就在队首入队,否则是0的话就在队尾入队。这样我们就可以保证,任意时刻的双端队列中节点对应的距离值都有“两端性”和“单调性”,每个节点第一次访问,就能得到最短距离
其实我个人理解的就是说这个跟动态规划很像,在分支前面有两条路可选,然后用判断走哪一条
实际上在权值中并不一定全部都是0或1,只是分了两种情况,一种模型
就是说用优先队列(优先堆)+BFS,也就说当一个搜索图存在两种不同的代价,那么我们把小的代价存在优先队列的队首,那么大一点的就放在后面,那么不断地取当前最小代价进行拓展,这样最后就去到了最小代价
可是这种做法有点类似于贪心,我们只是保存了当前的局部最优解,这样显然不完美,当前的代价最优不是说全局最优;当前的代价最差不一定说全局最差。

六自由度机械臂ANN人工神经网络设计:正向逆向运动学求解、正向动力学控制、拉格朗日-欧拉法推导逆向动力学方程(Matlab代码实现)内容概要:本文档围绕六自由度机械臂的ANN人工神经网络设计展开,详细介绍了正向与逆向运动学求解、正向动力学控制以及基于拉格朗日-欧拉法推导逆向动力学方程的理论与Matlab代码实现过程。文档还涵盖了PINN物理信息神经网络在微分方程求解、主动噪声控制、天线分析、电动汽车调度、储能优化等多个工程与科研领域的应用案例,并提供了丰富的Matlab/Simulink仿真资源和技术支持方向,体现了其在多学科交叉仿真与优化中的综合性价值。; 适合人群:具备一定Matlab编程基础,从事机器人控制、自动化、智能制造、电力系统或相关工程领域研究的科研人员、研究生及工程师。; 使用场景及目标:①掌握六自由度机械臂的运动学与动力学建模方法;②学习人工神经网络在复杂非线性系统控制中的应用;③借助Matlab实现动力学方程推导与仿真验证;④拓展至路径规划、优化调度、信号处理等相关课题的研究与复现。; 阅读建议:建议按目录顺序系统学习,重点关注机械臂建模与神经网络控制部分的代码实现,结合提供的网盘资源进行实践操作,并参考文中列举的优化算法与仿真方法拓展自身研究思路。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值