图表算法—有向图(Directed Graphs)

 

1. 有向图

  有向图与无向图是很像的,如果对无向图不熟悉,建议先看一下

  

  也是有两个关键点:

  a. 这个有向图有哪些点

  b. 哪些点可以通往哪些点(箭头代表可通往的方向,如此例子中,0可以去1,但1不可以去0。)

  构建有向图也是用邻接矩阵(Adjacency-matrix)或邻接列表(Adjacency-list)。

  这个矩阵和列表也和无向图的基本一样,唯一的区别在于,有向图的矩阵不是关于对角线对称的。

  有向图的邻接列表显示:(0可以去的点有5,1,即adj[0]=5,1)

  

  下面开始讨论有向图的算法:深度优先搜索(depth-first search)和广度优先搜索(breadth-first search)。

  无向图的Group在有向图中不适用,因为有些路是单方向的。稍后我们将引入强联系(Strong Components)的概念来解决Group的问题。

2. 深度优先搜索(depth-first search)

  有向图的深度优先搜索与无向图的深度优先搜索很像,像到什么程度呢?甚至可以直接把无向图的深度优先搜索代码直接复制过来用。

  看例子:

  

  

  0~12代表着图中的所有点。

  一开始所有点标记为False(F),当我们走到某个点后,此点标记为True(T)。标记过的点不需要再走一次。

  EdgeTo记录了部分路线,所有部分路线可以整合成一个完整的路线。例如从E点抵达A点,则记为EdgeTo[A]=E;

 

  从0开始,先把0标记为True(变红)。

  然后0可以去的点有5,1,这些点都还没标记为True,随便选一个:5。

  5标记为True。5从0来,故EdgeTo[5]=0;

  

  5只有一个点可以去:4。4还没标记为True,去4。

  4标记为True。4从5来,故EdgeTo[4]=5。

  

  4可以去的点有3,2,这些点都还没标记为True,随便选一个:3。

  3标记为True。3从4来,故EdgeTo[3]=4。

   

  3可以去的点有5,2,5已标记,不管。2没标记,只能去2。

  2标记为True。2从3来,故EdgeTo[2]=3。

  

  2可以去的点有0,0已标记,不管。2无路可走,返回上一个分支3。

  3无路可走,返回上一个分支4。

  4无路可走,返回上一个分支5。

  5无路可走,返回上一个分支0。

  0还有一个点可以去:1。

  1标记为True。1从0来,故EdgeTo[1]=0。

  

  1无路可走,返回上一个分支0。

  0无路可走,且无上一个分支,此部分结束。

  查找标记为F的其它点,随便选一个来走,如7。

  重复上述过程,直到所有点标记为T为止。

  通用思路也呼之欲出了,见代码:

  

 

3. 广度优先搜索(breadth-first search)

  有向图的深度优先搜索与无向图的深度优先搜索基本一样。具体详细内容可以去

  

  队列A输出一个值:1。1没有可以去的点,不管。

  队列A输出一个值:5。5可以去的点有4,4标红,4进队列A。

  队列A输出一个值:4。4可以去的点有2,3;2,3标红,2,3进队列A。

  

  队列A输出一个值:2。2可以去0,3,但它们都是已标记的,不管。

  队列A输出一个值:3。3可以去2,5,但它们都是已标记的,不管。

  队列A为空,此部分处理完成。

  其它部分也是相同处理方法,DistTo要小心处理,一般要遍历全部的时候,DistTo是不需要的。DistTo一般用于寻找两个点之间的最短距离与路线。

代码与无向图的一样:

       

 

4. 拓扑排序(Topological Sort)

  一、什么是拓扑排序?

  先从一个例子中直观地感受一下:左图是有向图,右图是这个有向图拓扑排序后形成的拓扑序列。(当然,这个拓扑序列是竖着的还是横着的都没所谓,怎么好看怎么来。)

  

  在现实生活中,很多任务是有先决条件的,例如冲一杯咖啡,我们需要先做4个前提任务:

  a.水烧开

  b.把开水倒入杯子中

  c.把咖啡冲剂倒入杯子中

  d.把杯子里面的东西搅匀

  b和c的顺序没所谓,a要在b之前完成,d要在a,b,c之后才能进行。如果把这些任务拓扑排序:

  图中e是喝咖啡。

  

  由上图可知,要完成e需先完成d;要完成d需先完成b和c;要完成b需先完成a。

  像这样,拓扑序列可以把一个大任务分成若干小任务,这是做大型项目所需要的,并且任务流程十分清晰。

  拓扑序列也可以在许多地方有所作为,这里不一一列出,有兴趣的可自行搜索。

  下面将介绍如何对一个有向图进行拓扑排序。

  

  二、如何进行拓扑排序?

  一般来说,我们只会对有向无环图(DAG, Directed Acyclic Graph)进行拓扑排序,这里的无

50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信