摘要

AOV 网是图的一种类型,本质是一个有向无环图。AOV 网的排序被称为拓扑排序,它的实现思路是卡恩算法。代码实现上要留意删除顶点的操作,这是一个很巧妙的处理方式。

通常一项大的工程会被拆分为多个小的子工程。子工程之间可能存在一定的顺序关系,即一个子工程会在其他子工程完成之后才会开始。

在现代化管理中,人们通常用有向图来描述和分析一项工程的计划和实施过程,子工程被称为活动(Activity)。所以以顶点表示活动,有向边表示活动之间的先后关系,这样的图被称为 AOV 网(Activity On Vertex Network)

AOV 网

标准的 AOV 网必须是一个有向无环图,即从任何一个顶点出发,无论怎么走,都无法回到这个顶点自身。如下图所示:

从图中可以梳理出每个顶点的依赖关系:

  • B 依赖于 A;

  • C 依赖于 B;

  • D 依赖于 B;

  • E 依赖于 B、C、D;

  • F 依赖于 E。

拓扑排序

将 AOV 网中所有活动排成一个序列,使得每个活动的前驱活动都排在该活动的前面,这样的序列就是拓扑排序

拓扑排序中有两个关键词,即前驱活动和后继活动,他们的定义分别是:

  • 前驱活动:有向边起点的活动被称为终点的前驱活动,即只有当这个活动的前驱活动都完成之后,才可以开始该活动;

  • 后继活动:有向边终点的活动被称为起点的后继活动。

如下图所示,它的拓扑排序是 A、B、C、D、E、F 或者 A、B、D、C、E、F(可以看出一个 AVO 网的拓扑排序不是唯一确定的)。

排序思路

拓扑排序的思路可以使用卡恩算法实现,它的大致逻辑是,假设一个存放排序结果的列表为 L,然后进行如下操作:

  1. 把所有入度为 0 的顶点放到 L 中,并在图中删除该顶点;

  2. 重复 1 步骤操作,直到图中没有度为 0 的 顶点为止。

然后可以比较 L 和图中总的顶点数量,如果 L 等于图中总的顶点数量,则拓扑排序完成,如果是小于的关系,那么就证明图中存在环,无法进行拓扑排序。

入度是什么?

一个顶点的入度为 x,是指有 x 条边以该顶点为终点;

代码实现

依据排序的思路,首先需要创建一个数组存放排序的结果。顶点入度的数量直接可以通过它的入度集合获取到。

关于删除顶点的操作,这里有一个取巧的点,就是创建一个 Map 存放入度不为 0 的顶点,和它的入度值。那么删除操作,就是将它的入度值减1处理。代码如下:

public List<V> topologiclSort() {List<V> list = new ArrayList<>();Queue<Vertex<V, E>> queue = new LinkedList<>();// 存放顶点和它的入度值Map<Vertex<V, E>, Integer> ins = new HashMap<>();vertices.forEach((v, vertex) -> {int size = vertex.inEdges.size();if (size == 0) {queue.offer(vertex);} else {ins.put(vertex, size);}});while (!queue.isEmpty()) {Vertex<V, E> vertex = queue.poll();list.add(vertex.value);for (Edge<V, E> edge : vertex.outEdges) {// 获取顶点的入度值,并 -1 达到删除顶点效果int toIn = ins.get(edge.to) - 1;if (toIn == 0) {queue.offer(edge.to);} else {ins.put(edge.to, toIn);}}}return list;
}

总结

  • AOV 网是一个有向无环图;

  • 拓扑排序实现的思路可以使用卡恩算法处理,即不断获取入度为 0 的顶点;

  • 删除顶点可以转换为保存顶点的入度值,将入度值在合适的地方减1操作。

数据结构与算法-进阶(八)AOV 网相关推荐

  1. 08_JavaScript数据结构与算法(八)集合

    JavaScript 数据结构与算法(八)集合 集合 几乎每种编程语言中,都有集合结构.集合比较常见的实现方式是哈希表,这里使用 JavaScript 的 Object 进行封装. 集合特点 集合通常 ...

  2. 数据结构与算法笔记(王卓网课+教材+大话数据结构)

    数据结构与算法笔记(王卓网课+教材+大话数据结构) ##最新整理!!! 顺序存储结构的线性表P10-P21 顺序线性表的代码实现 链式线性表笔记 串笔记 绪论.算法(P1-P9)1.4数据起源结构 数 ...

  3. 数据结构与算法(八)二分搜索树(Binary Search Tree)

    本文主要包括以下内容: 二分搜索树的基本概念 二分搜索树的基本操作 1. 插入 2. 删除 3. 查询 实现二分搜索树 二分搜索树的不足 二分搜索树的基本概念 二分搜索树(英语:Binary Sear ...

  4. 数据结构中单链表的存储c语言,单链表一 - 数据结构与算法教程 - C语言网

    1. 单链表概念&设计 单链表是一种链式存取的数据结构,,链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指 ...

  5. 数据结构与算法(八)-二叉树(斜二叉树、满二叉树、完全二叉树、线索二叉树)...

    前言:前面了解了树的概念和基本的存储结构类型及树的分类,而在树中应用最广泛的种类是二叉树 一.简介 在树型结构中,如果每个父节点只有两个子节点,那么这样的树被称为二叉树(Binary tree).其中 ...

  6. java单词匹配算法_前端学数据结构与算法(八): 单词前缀匹配神器-Trie树的实现及其应用...

    前言 继二叉树.堆之后,接下来介绍另外一种树型的数据结构-Trie树,也可以叫它前缀树.字典树.例如我们再搜索引擎里输入几个关键字之后,后续的内容会自动续上.此时我们输入的关键词也就是前缀,而后面的就 ...

  7. 【夜深人静写数据结构与算法 | 第八篇】哈希算法与哈希表

    目录 前言: 哈希: 哈希表: 哈希表组成: 哈希表实例: 哈希函数: TIPS: 总结 前言: 如果此时我要你默写一个有一百位的数字,你要如何做才能保证不会漏写呢?我们有一种方法很好用:直接数我们写 ...

  8. Java数据结构和算法(八)——递归

    记得小时候经常讲的一个故事:从前有座山,山上有座庙,庙里有一个老和尚和一个小和尚,一天,老和尚给小和尚讲了一个故事,故事内容是"从前有座山,山上有座庙,庙里有一个老和尚和一个小和尚,一天,老 ...

  9. 贪心算法设计作业调度c语言,贪心算法 - 数据结构与算法教程 - C语言网

    1.简介 贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解. 贪心算法不是对所有问题都能得到整体最优 ...

最新文章

  1. VC的MFC中重绘函数的使用总结(整理)
  2. 救命代码_救命! 如何选择功能?
  3. php mysql 执行sql文件_PHP执行SQL文件并将SQL文件导入到数据库_PHP
  4. 欢乐纪中B组周五模拟赛【2019.3.8】
  5. edp和edt哪个好_香水edp和edt是什么意思
  6. 大数据解密之你的同事都跳槽到了哪些公司
  7. 比excel更好用的免费拖拽报表—JimuReport 1.4.4新特性
  8. 【Java】反转数组元素
  9. 小米加入 AI 研究大家庭!联合西工大推出基于注意力机制的普通话语音识别算法...
  10. ENVI入门系列教程---一、数据预处理---5. 图像自动配准
  11. 全国python工程师有多少_2019年Python工程师的平均薪资是多少?
  12. hashcat软件的简单实用
  13. 天线发射功率计算公式_天线增益的定义/计算公式/发射功率
  14. 解决docker+openvpn搭建完成后客户端能连接,但是无法访问互联网或其他机器
  15. 如何将ANSYS19 Structural 图形界面背景底色更改为白色
  16. 2011年,痛并快乐着
  17. Linux下通过rdesktop连接Windows远程桌面
  18. android手机运行win10,Win10可以直接运行你手机里的安卓APP了:三星率先支持
  19. 在人一生的成长过程中,什么才是最重要的因素?
  20. @staticmethod静态方法

热门文章

  1. 漫画安全HIDS、EDR、NDR、XDR
  2. vue + echarts 之饼形图
  3. android+双卡imei,以编程方式在Android中为双SIM卡检索IMEI号码
  4. PyCharm中文版(无需汉化包,一键设置)
  5. 手机电视推广优先权让位地面国标?
  6. web前端学习26(锚点链接)
  7. Excel 2010 VBA 入门 033 批量合并相同的单元格
  8. 基于java的一款实时聊天系统,包含服务端 + 客户端 + web端
  9. 变压器绕制工艺之分布电容
  10. NLP教程笔记:BERT 双向语言模型