第四章 4.1无向图

来源:互联网 发布:macbook装windows教程 编辑:程序博客网 时间:2024/04/30 21:17
在计算机应用中,由相连的结点所表示的模型起到了关键的作用。关键疑问:示沿着这些连接能否从一个结点到另一个结点?有多少结点和指定的结点相连??两个结点之间最短的连接是哪一条?????

图的应用
       地图(那条路线最快)、网页信息(整个互联网就是一张图,结点是网页,连接就是超链接,算法是帮助我们在网络上定位信息的搜索引擎的关键组件)、电路(各种元件的组合成一块)、任务调度(商品的生产过程包含了许多工序以及一些限制条件,这些条件决定某些任务的先后次序)、商业交易(零售商和金融机构都会跟踪市场中的买卖信息)、配对(学生可以申请加入各种机构,这里结点对应学生和机构,而连接对应递交的申请)、计算机网络(计算机网络是由能够发送、转发和接受各种信息的站点互相连接组成的。)、软件(编译器使用图来表示大型软件系统中各个模块之间的关系。图中的结点即构成整个系统的各种类和模块,连接则为类的方法之间的可能调用关系,或是系统运行时的实际调用关系(动态分析)。我们需要分析这幅图来决定如何以最优的方式为程序分配资源)、社交网络(当你使用社交网络时, 回和你的朋友之间建立明确的关系。这里结点对应人,而连接则联系着你和你的朋友或是关注者)

图模型

      无向图(简单连接)、有向图(连接有方向性)、加权图(连接带有权值)、加权有向图(连接既有方向性又带有权值)。  

4.1 无向图

定义
此图模型中,边仅仅是两个顶点之间的连接。为了和其他图模型相区别,我们将它称为无向图。 图是一组顶点和一组能够将两个顶点相连的边组成的。至于顶点叫什么名字不重要,我们使用0至V-1来表示一张含有V个顶点的图中的各个顶点。这样约定是为了方便实用数组的索引来编写能够高效访问各个顶点中信息的代码。

特殊的图
特殊的图:我们定义允许出现两种简单而特殊的情况:
  • 自环,即一条连接一个顶点和其自身的边;
  • 连接同一对顶点的两条边称为平行边
含有平行边的图称为多重图,而将没有平行边或自环的图称为简单图。


4.1.1 术语表
当两个顶点通过一条边相连时,我们称这两个顶点相邻的,并称该连接依附于这两个顶点。某个顶点的度数即为依附于它的边的总数。子图是由一幅图的所有边的一个子集(以及它们所依附的所有顶点)组成的图。许多计算问题都需要识别各种类型的子图,特别是由能够顺序连接一系列顶点的边所组成的子图。

定义: 在图中,路径是由边顺序连接的一些系列顶点。简单路径是一条没有重复顶点的路径。是一条至少含有一条边且起点和终点相同的路径。简单环是一条不含有重复顶点和边的环。路径或者环的长度为其中所包含的边数。

注意:在大多数情况下,我们研究的都是简单环和简单路径并会省略掉简单二字。当允许重复的顶点时,我们指的是一般的路径和环。当两个顶点之间存在一条连接双方的路径时,我们称一个顶点和另一个顶点时连通的。
我们用类似于u-v-w-x的记法来表示u到x的一条路径,用u-v-w-x-u表示从u到v到w到x再回到u的一条环。路径和环会帮我们从整体上考虑一幅图的性质。

定义:如果从任意一个顶点都存在一条路径到达另一个任意顶点,我们称这幅图是连通图。一条非连通图由若干个连通的部分组成,它们都是其极大连通子图。
要处理一张图就需要一个个地处理它的连通分量(子图)。

无向图就是一种不包含环的图。
定义:树是一幅无环连通图。互不相连的树组成的集合称为森林。连通图的生成树是它的一幅子图,它含有图中的所有顶点且是一棵树。图的生成树森林是它所有连通子图的生成树的集合。
树的定义非常通用,稍作更改就可以变成用来描述程序行为的(函数调用层次)模型和数据结构(二叉查找树、2-3树等)

图的密度是指已经连接的顶点对占所有可能被连接的顶点对的比例。在稀疏图中,被连接的顶点对很少;而在稠密图中,只有少部分顶点对之间没有边连接。一般来说,如果一幅图中不同的边的数量只占顶点总数V的一部分,那么我们就认为这幅图是稀疏的。否则则是稠密的。


二分图:二分图是一种能够将所有结点分为两部分的图。其中图的每条边所连接的两个顶点分别属于不同的部分。

4.1.2  表示无向图的数据类型




4.1.2.1 图的几种表示方法
  1. 表示方法的要求:
  • 它必须为可能在应用中碰到的各种类型的图预留出足够的空间;
  • Graph 的实例方法的实现一定要快----它们是开发处理图的各种用例的基础;


  1. 表示方法
  • 邻接矩阵。我们可以使用一个V乘V的布尔矩阵。当顶点v和顶点w之间有相连接的边时,定义v行w列的元素值为true,否则为false。这种表示方法不符合第一个条件-含有上百万个顶点的图是很常见的,V^2个布尔值所需的空间是不能满足的。
  • 边的数组。我们可以使用一个edge类,它含有两个int 实例变量。这种方法很简单但不满足第二个条件---要实现adj()需要检查图中的所有边。
  • 邻接表数组。我们可以使用一个以顶点为索引的列表数组。其中的每个元素都是和该顶点相邻的顶点列表。这种数据结构能够同时满足以上两个条件

4.1.2.2 邻接表的数据结构
     非稠密图的标准表示称为邻接表的数据结构,它将每个定点的所有相邻顶点都保存在该顶点对应的元素所指向的一张链表中。我们使用这个数组就是为了能够快速访问给定顶点的邻接顶点列表。链表使用的是Bag数据类型。这样我们可以使用常数时间内添加新的边或遍历任意顶点的所有相邻顶点。要添加一条连接v与w的边,我们将w添加到v的邻接表中并把v添加到w的邻接表中。因此在这个数据结构中,边会出现两次。
     Graph的实现性能有如下特点:
  • 使用的空间和V+E成正比;
  • 添加一条边所需的时间为常数;
  • 遍历顶点V的所有相邻顶点所需的时间和v的度数成正比(处理每个相邻顶点所需的时间为常数) 



4.1.2.3  图的处理算法的设计模式

我们用起点区分作为参数传递给构造函数的顶点和图中的其他顶点。在这份API中,构造函数的任务是找到图中与起点连通的其他顶点。用例可以调用marked() 和 count()方法来了解图的性质。方法名marked()指的是这种基本算法使用的一种实现方式,

用例可以调用marked()方法和count()方法来了解图的性质。方法名marked()指的是这种基本算法使用的一种实现。这种基本算法是:在图中从起始点开始沿着路径到达其他顶点并标记每个路过的顶点。后面框注中的图处理用例TestSearch接受由命令行得到的一个输入流的名称和起始结点的编号,从输入流中读取一幅图(使用Graph的第二个构造函数),用这幅图和给定的起始结点创建一个Search对象,然后用marked()打印出图中和起点连通的所有顶点。它调用了count()并打印了图是否是连通的(当且仅当搜索能够标记图中的所有顶点时,图才是连通的)。


4.1.3 深度优先搜索

    图的很多性质和路径有关,因此我们需要沿着图的边从一个顶点移动到另一个顶点。
    要探索迷宫中的所有通道,我们需要:
  • 选择一条没有标记过得通道,在你走过的路上铺一条绳子;
  • 标记所有你第一次路过的路口和通道;
  • 当来到一个标记过的路口时,回退到上一个路口;
  • 当回退到的路口已没有可走的通道时,继续回退;
     
算法理解

深度优先搜索算法是使用递归调用的方式来进行探测每个结点。而利用里深度优先递归算法可以解决许多与图有关的任务。如
  • 连通性  使用给定一幅图,回答“两个给定结点是否连通??”或者“图中有多少个连通子图?”等类似的问题。
  • 单点路径  用给给定一幅图和一个起点s,回答“从s到给定目的顶点v是否存在一个路径?如果有找出这条路径。”等类似问题


问题是否连通?等价于两个给定的结点之间是否存在于一条路径?,也可以叫做路径检测问题。


4.1.4 寻找路径

基于深度优先搜索实现了Paths,它添加了一个实例变量edgeTo[] 整形数组来起到Tremaux 搜索中绳子的作用。这个数组可以找到从每个与s连通的顶点回到s的路径。它会记住每个顶点到起点的路径,而不是记录当前顶点到起点的路径。为了做到这一点,由边v-w第一次访问任意w时,将edgeTo[w]设为v来记住这条路径。换句话说,v-w是从s到w的路径上的最后一条已知的边。这样,搜索的结果是一棵以起点为根结点的树,edgeTo[] 是一棵由父链接表示的树。 

4.1.5 广度优先搜索

深度优先搜索得到的路径不仅取决于图的结构,还取决于图的表示和递归调用的性质。而对于以下的问题则需要另外经典的方法来解决。
问题:单点最短路径。给定一幅图和一个起点s,回答“从s到给定目的顶点v是否存在一条路径?如果有,找出其中最短的那条(所含边数最少)”。
解决这个问题的经典方法叫做广度优先搜索算法。因为深度优先搜索在这个问题上没有什么作为,因为它遍历整个图的顺序和找出最短路径的目标没有任何关系。相比之下,广度优先搜索正是为了这个目标才出现的。

实现
广度优先搜索算法,它使用了一个队列来保存所有已经被标记过但其邻接表还未被检查过得顶点。先将起点加入队列中,然后重复以下步骤知道队列为空:
  • 取队列中的下一个顶点v并标记它;
  • 将与v相邻的所有未被标记过得顶点加入队列。

bfs() 方法不是递归的,不像递归中隐式使用的栈,它显示地使用了一个队列。和深度优先搜索一样,它的结果也是一个数组edgeTo[],也是一棵用父链接表示的根结点为s的树。
它表示了s到每个与s连通的顶点的最短路径。用例也可以使用基于深度优先搜索实现的相同的pathTo()方法得到这些路径。

显示了用广度邮箱搜索处理样图时,算法使用的数据结构在每次循环的迭代开始时的内容。首先,顶点0被加入队列,然后循环搜索。


4.1.6 连通分量

       深度优先搜索的下一个直接应用就是找出一幅图的所有连通分量。与........连通是一种等价关系,它能够将所有顶点分为等价类(连通分量)。(连通分量指的是图中连通的量)
      
4.1.7 符号图




在典型应用中个,在典型应用中,图都是通过文件或者网页定义的。使用的是字符串而非整数来表示和指代顶点。为了适应的这样的应用。我们定义了拥有一下性质的输入格式:
  • 顶点名为字符串;
  • 用指定的分隔符来隔开顶点名;
  • 每一行都表示一组边的集合,每一条边都连接着这一行的第一个名称表示对鄂顶点和其他名称所表示的顶点;
  • 顶点总数V和边的总数E都是隐式定义的。


原创粉丝点击