关键路径法和最小生成树

news2024/10/2 1:31:37

1、关键路径法概述

关键路径的服务对象是“AOE网”(Activity on edge netword)。不同的是AOV网只考虑顶点事件,而AOE网除了顶点事件(如v[0])外,重点还有就是有向边还表示了活动(如e[0][1] = a0)。其中顶点事件也可以标记是若干个活动的结束,也可以标记是若干个活动的开始。

名词的定义:

首先是“源点”,指的是AOE网中,入度为0的顶点。然后是“终点”,指的是AOE网中,出度为0的顶点。

AOE网相关性质:

性质1:只有在进入某顶点的活动都已经结束后,该顶点所代表的事件才发生;

性质2:只有在某顶点所代表的事件发生后,从该顶点出发的各活动才开始。

在AOE网中,所有活动都完成才能到达“终点”,因此完成整个工程所必须花费的时间(即最短工期)应该为源点到终点的最大路径长度。具有最大路径长度的路径称为关键路径。关键路径上的活动成为关键活动

2、图解

关键路径的确定需要用到的各活动的“最早开始时间”、“最早结束时间”、“最迟开始时间”、“最迟结束时间”,然后当“最迟开始时间”-“最早开始时间”或“最迟结束时间”-“最早结束时间”的结果为0,则对应的这个活动就是关键活动,由这些活动构成的“起点”到“终点”的路径就是关键路径。

先从“起点”出发到“终点”,将最早开始时间和最早结束时间先确定如下图(最早开始时间是对应活动之前的顶点事件前的所有活动刚结束的最大时间,比如对活动a4的最早开始时间,应该是活动a1和a2的最早结束时间的最大值即ES[4] = max(9,10) = 10):

所以,整个工程的最快完结时间是15。接着,从“终点”回溯回“起点”,确定每个活动的最迟结束时间和最迟开始时间。我们从a5和a4分别确定最迟结束时间都是15,LF[4] = LF[5] = 15,对应LS[4] =LF[4] - 5 = 10, LS[5] = LF[5] - 2 = 13...LF[0] = min(LS[2],LS[3]) = 7。

按照关键路径的定义,下图橘黄色圆圈圈出来的即为关键路径。

3、实现

在进行关键路径判断时,首先要确定给出的AOE网是有向无环图。所以,就需要用到上一讲中的“拓扑排序”了。具体的求关键路径和关键活动的算法步骤如下:

1)、利用拓扑排序求出AOE网的一个拓扑序列(同时也就判断了是否是有向无环图,若是,则执行接下来的操作);

2)、从拓扑序列的第一个顶点开始,按拓扑顺序依次计算每个事件的最早开始时间ES[i]和最早结束时间EF[i]。

3)、从拓扑序列的最后一个顶点开始,按逆拓扑顺序依次计算每个事件的最迟结束时间LF[i]和最迟开始时间LS[i]。

4)、对每个活动,若LF[i]-ES[i]=0,则对应第i个活动为关键活动,输出的关键活动的序列就是关键路径。

注:为方便编码,这里将开始时间存到对应的顶点中,即只计算顶点对应时间的最早开始时间,即下图中对应存储的方式为:

ES[0] = 0,ES[1] = 7,ES[2] = 10,ES[3] = 11,ES[4]=15。

逆序后存对应顶点的最迟开始时间为:

LS[4]=15,LS[3]=13,LS[2]=10,LS[1]=7,LS[0]=0。

因此,判断关键路径的时候要做如下遍历边来处理,即找到最短路径。

ES[u]是否等于LS[u->v]-w[u->v]。比如<0,1>是不是关键路径,这个时候,ES[0] = 0, LS[V]-W[u,v]=7-7=0,所以<0,1>是关键路径。对<0,2>,遍历中发现LS[2]-W[0,2] = 10-9 = 1≠ES[0],因此<0,2>不是关键路径。

1、最小生成树概述

图的最小生成树里有两个关键词,一个是“树”,一个是“最小”。首先,对“树”而言,必须无环,并且要连接图中的所有顶点(否则就成了森林了),即任意顶点可以连通,因此对n个顶点的图来说,它的最小生成树有(n-1)条边。其次,对“最小”而言,同样一个图可能有若干不同的生成树,把对应生成树边上的权值相加,得到权值和最小的那棵树就是该图的最小生成树。如下面一幅图:

生成树1:权值和=10+9+2+3 = 24。

生成树2:权值和=4+9+6+7 = 26。

最小生成树:权值和=4+2+3+7 = 16。

最小生成树在现实中有很多的应用,典型的有,比如上述节点代表的是城市,边是城市间铺设管道,对应边上的权值是铺设管道的成本,要让各个城市间管道能够连通,并且从经济上考虑铺设的管道成本和最小,这个时候权值和最小的生成树就能够满足这种需求。

接下来我们介绍两种构建最小生成树的方法——Kruskal算法和Prim算法,这两种算法都用到了贪心的思想,即构建的时候每一步都选择权值最小的边,不同点是Kruskal用了每次直接选择不构成环的待选的权值最小的边,而Prime则是每次选择跟当前生成树连通边权值最小的顶点。

2、Kruskal算法

Kruskal算法也称为“加边法”,理解起来相对比较简单一些,我们来看具体步骤:

1). 把图中的所有的边取出,放到列表中,并按权值从小到大排序;

2). 把图中的n个顶点打散(亦可看成是5棵树构成的森林);

3). 按权值从小到大选边,所选的边连接的两个顶点(u,v),应属于两棵不同的树,即当前边是否可选,取决于加入进来后会不会形成环,如果会,那么这条边要舍弃。这里,我们可以用上一讲中的并查集的思想来判断。若新加边不构成环,则选中为最小生成树的一条边,即将这两棵树合并为一棵树。

4). 重复(3),直到生成树中有(n-1)条边为止。

执行过程如下:

出现回路,(2,5)这条边放弃。

已生成(n-1)条边,图中也可以看出来每个结点都已连通。最小生成树已构建完毕。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/348161.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

重生之我是赏金猎人-SRC漏洞挖掘(二)-逆向app破解数据包sign值实现任意数据重放添加

0x00前言 本期登场的目标虽不是SRC&#xff0c;但是整个漏洞的利用手法很有学习意义。目前在很多大厂的http数据包中都会添加sign值对数据包是否被篡改进行校验&#xff0c;而sign算法的破解往往是我们漏洞测试的关键所在~ 本人在一些漏洞挖掘实战中经常发现在破解sign值后&a…

【电商】订单拆单的流程中,系统需要做哪些工作?

什么是拆单&#xff1f; 在网上购买商品下单成功后&#xff0c;过一段时间再次浏览时&#xff0c;有时会发现你的订单会变成两个或多个&#xff0c;这就是系统做了拆单而导致的。 拆单&#xff0c;就是将一个大的订单依据某些规则的集合&#xff0c;将其分解成两个或多个子订…

内核模块(编译方法)

目录 一、向内核添加新功能 1.1 静态加载法&#xff1a; 1.2 动态加载法&#xff1a; a、新功能源码与Linux内核源码在同一目录结构下时 b、新功能源码与Linux内核源码不在同一目录结构下时 c、主机ubuntu下使用ko文件 d、开发板Linux下使用ko文件 二、内核模块基础代码…

链表题目总结 -- 回文链表

目录一. 从中心开始找最大的回文字符串1. 思路简述2. 代码3. 总结二. 判断是否为回文字符串1. 思路简述2. 代码3.总结三. 判断是否是回文链表1. 思路简述2. 代码3. 总结4. 优化解法一. 从中心开始找最大的回文字符串 题目链接&#xff1a;没有。给定一个字符串s&#xff0c;从…

平面电路和非平面电路

主要区别 参考&#xff1a;https://www.eda365.com/article-192836-1.html 平面电路&#xff1a;在平面上的每个元件的两端都可以不用交叉而连接到电路&#xff1b; 非平面电路&#xff1a;在平面上存在元件两端无法不交叉线路连接到电路。 例子&#xff08;上面参考连接中&a…

继企业级信息系统开发学习1.1 —— Spring配置文件管理Bean

骑士救美计划采用构造方法注入属性值1、创建救美任务类2、创建救美骑士类2、创建救美骑士类3、创建旧救美骑士测试类3、配置救美骑士Bean5、创建新救美骑士测试类采用构造方法注入属性值 1、创建救美任务类 在net.huawei.spring.day01包里创建RescueDamselQuest类 Rescue Da…

【重点】Selenium + Nightwatch 自动化测试环境搭建

开始搭建 1. 创建项目 我们来找个地方新建一个目录&#xff0c;起名为 "my-test-toolkit"&#xff0c;然后在目录内使用终端运行 npm init -y 生成项目配置文件package.json。 2. 安装工具 然后我们将安装 Selenium 与 Nightwatch。 安装 selenium-standalone&…

在哔站黑马程序员学习Spring—Spring Framework—(五)spring的第二特征AOP面向切面编程

一、AOP概念、作用AOP和OOP一样都是一种编程思想&#xff0c;用来指导我们做程序的。OOP面向对象编程指导我们做类、对象、继承、封装、多态等。AOP面向切面编程作用&#xff1a;在不惊动原始设计&#xff08;不改变源代码&#xff09;的基础上为其进行功能增强。核心&#xff…

2022年全国职业院校技能大赛网络空间安全A模块(1)

目录 模块A 基础设施设置与安全加固 一、项目和任务描述&#xff1a; 二、服务器环境说明 三、具体任务&#xff08;每个任务得分以电子答题卡为准&#xff09; A-1任务一 登录安全加固 1.密码策略&#xff08;Windows&#xff0c;Linux&#xff09; a.设置最短密码长度为…

AC/DC 基础

一、概念&#xff1a; AC转换成DC的基本方法有变压器方式和开关方式&#xff0c;如下图1、2所示&#xff1b;整流的基本方法有全波整流和半波整流&#xff0c;如下图3所示。 图1 变压器方式 图2 开关方式 图3 整流方式 二、转换方式 1、变压器方式 变压器方式首先需要通过变压…

< 算法基础 之 二分查找 >

算法基础 之 二分查找前言&#x1f449; “ 二分查找 ” 原理及实现&#x1f449; 实际案例&#xff1a;> 基础案例 - 搜索下标示例 1示例 2解决方案> 进阶案例 - 搜索二维矩阵示例 1示例 2解决方案往期内容 &#x1f4a8;前言 在开发中&#xff0c;我们常常会需要查找某…

java无重复字符的最长子串

给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”&#xff0c;所以其长度为 3。 示例 2: 输入: s “bbbbb” 输出: 1 解释: 因为无重复字符的最长子串是 “…

GEE学习笔记九十二:Sentinel-2 最新去云方法总结

下面使用例子的原始影像截图如下&#xff1a; 第一种方法&#xff1a;使用QA波段去云 这是我们最常用的方法&#xff0c;具体原理就是利用QA60波段标记实现去云&#xff0c;具体代码如下&#xff1a; var s2 ee.ImageCollection("COPERNICUS/S2"), point /* …

B树与B+树

B树 B树的定义 1970年&#xff0c;R.Bayer和E.mccreight提出了一种适用于外查找的树&#xff0c;它是一种平衡的多叉树&#xff0c;称为B树&#xff08;或B-树、B_树&#xff09;。我们描述一颗B树时需要指定它的阶数&#xff0c;阶数表示了一个结点最多有多少个孩子结点&…

[Android Studio]Android 数据存储--SQLite数据库存储

&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; Android Debug&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; Topic 发布安卓学习过程中遇到问题解决过程&#xff0c;希望我的解决方案可以对小伙伴们有帮助。 &#x1f4cb;笔记目…

Leetcode_part2

文章目录[406. 根据身高重建队列](https://leetcode.com/problems/queue-reconstruction-by-height/)Solution1 先排序 再插队[409. 最长回文串](https://leetcode.com/problems/longest-palindrome/)Solution1[415. 字符串相加](https://leetcode.com/problems/add-strings/)S…

上采样学习

最近邻 简单来说就是x方向和y方向分别复制 #!/usr/bin/env python # _*_ coding:utf-8 _*_ import numpy as np import torch from cv2 import cv2 from torch import nndef numpy2tensor(x: np.ndarray) -> torch.Tensor:"""(H,W) -> (1, 1, H, W)(H,W…

ShardingSphere-Proxy5按月分表

0、软件版本 ShardingSphere-Proxy&#xff1a; 5.2.0 MySQL&#xff1a; 8.0.30 系统&#xff1a; win10 1、ShardingSphere-Proxy下载 我们可以在 官网 找到最新版ShardingSphere-Proxy下载&#xff0c;也可以在ShardingSphere仓库中下载 2、ShardingSphere-Proxy配置 …

shell编程经典案例,建议收藏

1、编写hello world脚本 #!/bin/bash# 编写hello world脚本echo "Hello World!"2、通过位置变量创建 Linux 系统账户及密码 #!/bin/bash# 通过位置变量创建 Linux 系统账户及密码#$1 是执行脚本的第一个参数,$2 是执行脚本的第二个参数 useradd "$1" …

Linux C++ 200行完成线程池类

文章目录1、atomic使用2、volatile关键字3、条件变量4、成员函数指针使用5、线程池6、主线程先退出对子线程影响7、return、exit、pthread_exit区别8、进程和线程的区别1、atomic使用 原子操作&#xff0c;不可分割的操作&#xff0c;要么完整&#xff0c;要么不完整。 #includ…