当前位置: 首页 > news >正文

数据结构-关键路径

介绍

  • 在AOV网的基础上,如果用对应边来表示活动持续时间,这种有向图被称为AOE网
  • 在AOE网中,入度为0的为源点,出度为0的为汇点,整张网看做是一件事情完成的过程,那么这两个点就是事情的开始和结束。每个活动持续的时间之和称为路径长度,从源点到汇点具有的最大长度的路径就成称为关键路径,关键路径上的活动称为关键活动。

关键路径用来计算整个活动总耗时最短的情况。假如有这样一张AOE网,在完成从1到3的过程中,每件事情需要的时间为边上的权值,那么从开头到结束,由于完成4时2,3也可以同时完成,那么需要的最短时间就是4+1=5

那么,1-4-3就是一条关键路径

不难发现,这条路径是把空余时间“塞满”的路径。假设有一件事持续时间为1h,在12点-15点都可以做,那么这件事的最早开始时间为12点,最晚开始时间为14点,这中间还有两个小时的空隙,时间没有“塞满”,那么就不会构成关键路径

所以,判断关键事件的标准就是其最早开始时间与最晚开始时间是否相等

如何求关键路径

  1. 绘制计划图,标注其持续时间
  2. 根据各活动的依赖关系,计算其最早开始时间和最晚开始时间
  3. 计算每个活动的最早完成时间和最晚完成时间(由2结果可以推导出)
  4. 找到最早开始时间与最晚开始时间相等的事件,这些活动构成了关键路径

具体实现

由于计算关键路径之前需要先理清事件的先后关系,所以在找关键路径之前需要先对网图进行拓扑排序,不同的是,我们需要在邻接表中加入代表边权值的值域。

typedef struct edge{int adjvex;//邻接点域,用于储存该顶点对应下标int info;//储存权值int weight;//储存边的权值struct edge* next;//链域,指向下一个邻接点
}edge;
typedef struct vex{int v;//储存顶点int in;//记录入度;edge* first;//边表头指针
}vex,adjlist[MAX];
//储存邻接链表构成的网图信息
typedef struct{adjlist al;int numE,numN;
}graphAL;

拓扑排序过程中也需要加入对时间的判断处理,并额外记录拓扑排序的结果

int et[MAX],lt[MAX];//记录最早时间和最晚时间
bool topo(graphAL g){int n=0;//记录输出的顶点值,判断是否为AOV网deque <int>q;//创建队列for (int i=0;i<g.numN;i++){if (g.al[i].in==0){//入度为0q.push_back(i);//入队}}deque <int>q2;//用于储存拓扑序列for (int i=0;i<g.numN;i++){et[i]=0;//初始化}while(!q.empty()){cout<<q.front()<<" ";//将入度为0的顶点输出n++;//输出的顶点数加1edge* e=g.al[q.front()].first;q2.push_front(q.front());//记录弹出的顶点int top=q.front();q.pop_front();//此顶点出队while(e){//处理其相邻顶点int temp=e->adjvex;//记录相邻顶点if (g.al[temp].in==1)//入度为1,说明去掉与原顶点相连的边后入度为0q.push_back(temp);e=e->next;//继续处理下一个相邻顶点if (et[top]+e->weight>et[temp]) et[temp]=et[top]+e->weight;}}if (n!=g.numN) return false;else return true;
}

关键路径的求取(队列2与最早发生时间数组需要定义在全局或者传入函数中)

void CriticaPath(graphAL g){int e,l;//最早和最晚发生时间topo(g);//首先进行拓扑排序int ltv[g.numN];//最晚发生时间数组for (int i=0;i<g.numN;i++){ltv[i]=et[g.numN-1];//初始化}while (q2.empty()){int top=q.front();//将拓扑排序好的顶点出队q.pop_front();edge* e=g.al[top].first;while(e){int temp=e->adjvex;//判断是否需要更新最晚发生时间//(活动的最晚发生时间取决于其后继活动的最晚发生时间减去活动持续时间)if (ltv[temp]<ltv[top]+e->weight) ltv[top]=ltv[temp]+e->weight;e=e->next;}}for (int i=0;i<g.numN;i++){edge* e=g.al[i].first;while(e){int temp=e->adjvex;e=et[i];//活动最早时间l=ltv[temp]-e->weight;//最晚开始时间if (e==l)//判断是否为关键事件......//如果是,进行题目要求的打印或求路径之和操作e=e->next;}}
}

相关文章:

数据结构-关键路径

介绍 在AOV网的基础上&#xff0c;如果用对应边来表示活动持续时间&#xff0c;这种有向图被称为AOE网在AOE网中&#xff0c;入度为0的为源点&#xff0c;出度为0的为汇点&#xff0c;整张网看做是一件事情完成的过程&#xff0c;那么这两个点就是事情的开始和结束。每个活动持…...

进程间通信学习笔记(共享内存)

内存映射概念&#xff1a; 共享内存可以通过mmap()映射普通文件使一个磁盘文件与内存中的一个缓冲区相映射&#xff0c;进程可以像访问普通文件一样对文件进行访问&#xff0c;不必再强调read,write。 mmap的优点&#xff1a; 实现了用户空间和内核空间的高效交互方式 mmap的…...

ChatGPT学习第三周

&#x1f4d6; 学习目标 ChatGPT在各行各业的应用 探索ChatGPT在不同领域&#xff08;如教育、客户服务等&#xff09;的实际应用案例。 ChatGPT的局限性和挑战 讨论ChatGPT面临的挑战&#xff0c;包括偏见、误解及其限制。 ✍️ 学习活动 学习资料 《人工智能通用大模型(…...

R语言混合效应(多水平/层次/嵌套)模型及贝叶斯实现技术应用

回归分析是科学研究中十分重要的数据分析工具。随着现代统计技术发展&#xff0c;回归分析方法得到了极大改进。混合效应模型&#xff08;Mixed effect model&#xff09;&#xff0c;即多水平模&#xff08;Multilevel model&#xff09;/分层模型(Hierarchical Model)/嵌套模…...

[C++]使用C++部署yolov9的tensorrt模型进行目标检测

部署YOLOv9的TensorRT模型进行目标检测是一个涉及多个步骤的过程&#xff0c;主要包括准备环境、模型转换、编写代码和模型推理。 首先&#xff0c;确保你的开发环境已安装了NVIDIA的TensorRT。TensorRT是一个用于高效推理的SDK&#xff0c;它能对TensorFlow、PyTorch等框架训…...

eureka注册中心做了哪些事情/原理?

1.服务注册&#xff1a; 将eureka client发送过来的元数据存储到注册表中 2.服务续约&#xff1a; eureka client默认会每30秒向eureka server发送一次心跳来进行服务续约&#xff0c;通过这一行动来表示自己没有出现故障&#xff1b; 3.服务…...

c语言经典测试题4

1.题1 #include <stdio.h>//没有break的话&#xff0c;输入什么都会往下一直执行下去&#xff0c;而且default在最后就会全都执行 int main() {char c;int v0 0, v1 0, v2 0;do{switch (c getchar())// 输入ADescriptor{casea:caseA:casee:caseE:casei:caseI:caseo:…...

设计模式(五)-观察者模式

前言 实际业务开发过程中&#xff0c;业务逻辑可能非常复杂&#xff0c;核心业务 N 个子业务。如果都放到一块儿去做&#xff0c;代码可能会很长&#xff0c;耦合度不断攀升&#xff0c;维护起来也麻烦&#xff0c;甚至头疼。还有一些业务场景不需要在一次请求中同步完成&…...

MySQL-七种SQL优化

一、插入数据 普通插入&#xff1a; 采用批量插入&#xff08;一次插入的数据不建议超过1000条&#xff09; insert into tb_test values(1,Tom),(3, Cat),(3, Jerry)....手动提交事务 start transaction; insert into tb_test values(1,Tom),(3, Cat),(3, Jerry); insert …...

针对Umi、React中遇到的 “xxxx”不能用作 JSX 组件 问题解决方案

一、处理方案 这是因为"types/react"、"types/react-dom"在子依赖中使用的版本不一致导致&#xff0c;一般情况npm会自动帮我们处理版本不一致的问题。如果npm处理不了&#xff0c;就需要我们自己手动处理在package.json中添加一项配置 {name:"test&…...

蓝桥杯备战刷题one(自用)

1.被污染的支票 #include <iostream> #include <vector> #include <map> #include <algorithm> using namespace std; int main() {int n;cin>>n;vector<int>L;map<int,int>mp;bool ok0;int num;for(int i1;i<n;i){cin>>nu…...

设计模式(十) - 工厂方式模式

前言 在此前的设计模式&#xff08;四&#xff09;简单工厂模式中我们介绍了简单工厂模式&#xff0c;在这篇文章中我们来介绍下工厂方法模式&#xff0c;它同样是创建型设计模式&#xff0c;而且又有些类似&#xff0c;文章的末尾会介绍他们之间的不同。 1.工厂方法模式简介 …...

http协议基础与Apache的简单介绍

一、相关介绍&#xff1a; 互联网&#xff1a;是网络的网络&#xff0c;是所有类型网络的母集因特网&#xff1a;世界上最大的互联网网络。即因特网概念从属于互联网概念。习惯上&#xff0c;大家把连接在因特网上的计算机都成为主机。万维网&#xff1a;WWW&#xff08;world…...

RabbitMQ的死信队列和延迟队列

文章目录 死信队列如何配置死信队列死信队列的应用场景Spring Boot实现RabbitMQ的死信队列 延迟队列方案优劣&#xff1a;延迟队列的实现有两种方式&#xff1a; 死信队列 1&#xff09;“死信”是RabbitMQ中的一种消息机制。 2&#xff09;消息变成死信&#xff0c;可能是由于…...

PyQt 逻辑与界面分离

将逻辑与界面分离是一种良好的软件设计实践&#xff0c;可以提高代码的可维护性和可扩展性。在使用 pyuic 工具转换 Qt Designer 的 .ui 文件时&#xff0c;你可以通过以下方式实现逻辑与界面的分离&#xff1a; 创建一个单独的 Python 模块&#xff0c;用于编写主窗口的逻辑代…...

opengl播放3d pose 原地舞蹈脚来回飘动

目录 opengl播放3d pose 原地舞蹈脚来回飘动 设置相机视角 opengl播放3d pose 原地舞蹈脚来回飘动 opengl播放3d pose 原地舞蹈时,脚来回飘动,正常状态是脚应该不动的。 经过反复分析实验验证,找到原因是,渲染计算3d坐标时,都要减去一个offset,这个offset是髋关节的坐…...

Linux环境基础开发工具使用篇(三) git 与 gdb

一、版本控制器-git 1.简单理解: ①git既是服务端&#xff0c;又是客户端 ②git会记录版本的变化 ③git是一个去中心化的分布式软件 git/gitee 是基于git仓库搭建的网站&#xff0c;让版本管理可视化 2.git 三板斧提交代码 查看安装的git版本 git--version 命令行提交代…...

mybatis---->tx中weekend类

&#x1f64c;首先weekend可不是mybatis中的类呦~~&#x1f64c; 它是来自于mybatis的一个扩展库&#xff01; 如果你要在springboot中使用&#xff0c;需要引入以下依赖~~ <dependency><groupId>tk.mybatis</groupId><artifactId>mapper-spring-boot…...

Shell echo、printf、test命令

目录 Shell echo命令 打印文本消息 显示变量值 输出特殊字符 输出到文件 追加到文件 Shell printf 命令 打印简单文本 Shell test 命令 文件测试 字符串比较 整数比较 逻辑运算 Shell echo命令 打印文本消息 echo "Hello, World!" 显示变量值 name&q…...

腾讯云主机Ubuntu22.04安装Odoo17

一、安装PostgreSQL16 参见之前的文章 Ubuntu22.04安装PostgreSQL-CSDN博客 二、安装Odoo17 本方案使用的nightly版的odoo&#xff0c;安装的都是最新版odoo wget -O - https://nightly.odoo.com/odoo.key | apt-key add - echo "deb http://nightly.odoo.com/17.0/n…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...