算法设计学习笔记(三)


前言

本文是对于算法设计的学习笔记,如有错误,请不吝赐教。


一、图

1.1 基本定义与应用

图G由结点集合V和边集合E构成,其中每条边与两个结点相交。
有向图(为了表达不对称关系):一个有向图G’由结点集合V和有向边集合E‘构成,其中每条边e是一个有序对即两个端点不可交换。(头尾概念)

相关图的使用案例:
1.运输网络:一架航空飞机的服务路线图自然的构成了一个图
2.通信网络:把一组由通信网络连接的计算机自然的建模城一个图(将每台计算机或者每个计算机集群作为结点)
3.信息网络:万维网。结点对应web网页。如果u-v中有超链接,则从u-v中有一条边。
4.社会网络:给定任意一组相互影响的人,即可定义一个网络,结点就是人,不同形式的边可以代表不同的关系。
5.依赖网络:通过有向图来刻画一组个体之间的依赖关系。


1.2 路径与连通性

简单路径:没有重复的节点。
连通性:
对于无向图而言:如果每对节点间都存在一条相应的路径则认为改无向图是连通的。
对于有向图而言:如果对于每对节点u,v之间都有从u-v和从v-u的路径,则认为改有向图是强联通的。

最短路径:u-v路径中最少的边数。

如果一个图是连通的,且不包含一个圈,则称为树。
(树即是最简单的连通图,删除任意一边则不再连通。)

在这里插入图片描述


二、图的连通性与图的遍历

s-t连通性:即在图中是否存在一条从s到t的路径.(迷宫求解问题)
相关自然算法:宽度有限搜索,深度优先搜索

2.1 宽度有限搜索(BFS)

从s向外在所有的可能的方向上探查,每次增加一层的节点,直到不再遇到新的节点为止。
可以直到每一层都是到s距离相同的点的集合。所以BFS不仅仅计算了连通性,还计算了最短距离。

宽度优先搜索树:通过BFS算法将定点和边加到以起始点V为根节点的树上,这样构造的树称为宽度优先搜索树。

在这里插入图片描述
从更一般来说,我们可以按照以下算法来检查相关的连通性。

R={S}
while 存在一条边(u,v)是u属于R,而v不属于R
  将v加入R中
endWhile

此时,算法结束所产生的集合R刚好是包含s的连通分支。
同时也可以复原从s到t的实际路径,秩序记录在v加到R中所考虑的边即可。


2.2 深度优先搜索(DFS)

深度优先搜索:尽可能深的前进并且只有必要的时候才撤退。

DFS(u)
将u标记为已访问,然后加入到R中
for 每条u的边(u,v)
if v 未被标记过
  DFS(v)
endif
endfor

同样通过DFS得到的数叫做分支R的深度优先搜索树
在这里插入图片描述
在这里插入图片描述


2.3 所有连通分支的集合

在这里插入图片描述
这里提供了一种思路来获取一个图中的所以连通分量。


三、用优先队列和栈来实现图的遍历

3.1 图的表示

图有着两种基本的表示方法:邻接矩阵和邻接表。

1.邻接矩阵
如果图是无向图,则矩阵是对称的。
邻接矩阵表示能使得我们用O1的时间检查给定的边是否出现在图中。
但同样,他需要占用n2的空间。

2.邻接表
对于稀疏图比邻接矩阵更有效。
在邻接表中,每个结点v都有一个记录,这个记录包括一个结点表,表示从v到其中的每个结点都有相应的边。

补充 一个图的节点度数总和是变得两倍。

邻接表和邻接矩阵的对比:
在这里插入图片描述
但同样对于邻接表而言,判断一条边是否出现需要用于度数O(nu)成正比的时间。


3.2 队列与栈

队列:按照先进先出的次序从中取出元素。(按照与加入元素相同的次序来取出元素)
栈:按照后进先出的次序从中取出元素。
一般而言栈和队列可以采用双链表实现。


3.3 宽度优先搜索的实现

BFS(s)
Discovered[s]=true 且对其他所有的v置Discovered[v]=false
初始化L[0]=s
层数计数i=0
BFS树H=NULL
while L[i]!=null
初始化空表L[i+1]
for u in L[i]
考虑每条关联到u的边(u,v)
iF(discovered[v]=false)
   discovered[v]=true,(u,v)加入到树H上,将点v加入到表L[i+1]
endiF
endfor
i+1
endwhile

如果图是由邻接表给出的则上述算法将以O(m+n)执行

分析:对与n个节点的图而言,最多需要建立n个表L,同时还要初始化数组dicovered n次。同样for循环迭代n次,每次都要遍历边,由图的度的总和是2*边数可得循环遍历为O(m)。加上先前的n次创建L表和管理discovered,故总和为O(m+n)


3.4 深度优先搜索的实现

采用栈来存储探索过程中发现的新的节点。
除此之外,类似于BFS,创建一个Explred数组,表示是否被访问。

DFS(s)
初始化栈S,只有一个元素s
while S非空
u=s.top
    if(explred[u]=false then
          explored[u]=true
          for 每条与u关联的边(u,v)
              将v加入到S中
              将parent[v]=u
          endfor
    endif
endwhile

如果为邻接表给出的图,则为O(m+n)(只需统计多少次在S中加入节点和删除节点)
类似于BFS


3.5 找出所有连通分支的集合

通过DFS或者BFS来生成他的连通分支。此时认为O(m+n)


四、二分性测试:宽度优先搜索的一个应用

二部图:节点及V可以采用以下方式划分为X和Y两个集合。其中每条边的一段在X,另一端在Y
在这里插入图片描述
算法设计:采用BFS思想,进行泛色操作。(加一个color数组表示点的颜色)
过程结束后扫描是否存在一条边的两个端点是同色的。时间依旧是O(m+n)

在这里插入图片描述
如下图所示:
在这里插入图片描述
此时圈的长度为2(j-i)+1为奇数


五、有向图的连通性

5.1 有向图的表示

类似于无向图,由邻接表和邻接矩阵表示。此时的邻接矩阵不在具有对称性。

5.2 图搜索算法

类似于无向图,BFS和DFS几乎一样。 这个算法对于每个边和节点至多执行常量级工作所以O(m+n)

补充:如果我们想要得到由路径到s的点的集合,则可以将原图的方向翻转,然后采用DFS或者BFS,一个节点G‘中由从s到他的路径,则G中有着从他到s的路径。

5.3 强连通性

在这里插入图片描述
简单的算法判断是否强联通:图和翻转图同时采用BFS看是否都访问到所有节点。
类似于无向图:
在这里插入图片描述


六、有向无圈图和拓扑排序

对于无向图而言,如果无向图没有圈,则它的每个连通分支都是一颗树。
有向无圈图(DAG)
DAG是一种自然的对于优先关系或依赖性的描述。(比如任务的依赖关系)

拓扑排序:对于有向图G,它的一个拓扑排序是他的节点作为v1,v2的一种排序,使得对于每条边而言都按照次序前进。(任务的安全执行次序)
在这里插入图片描述
拓扑排序算法设计:
在这里插入图片描述

计算G的拓扑排序
找到一个没有进入变得节点v,排在第一个
从G中删除v和v的边
从G-v中递归计算拓扑排序,并排在v的后面

如何降低算法的运行时间:
可以通过设置两个监控量来完成:
1.对于每个节点W从活跃节点中进入的边数
2.从其他活跃节点没有便进入的G中的活跃节点的集合
其中活跃节点就是未被删除的节点。
即每次迭代都从s中选出节点删除,然后更新S

课后练习2 定义开始布局和结束布局(a,b)和(c,d)将所谓的一步变为构造的图H中的一个点。对于冲突则将H中点距离小于等于r的点。再在H中进行连通性的判断。
练习2

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值