aoe网java如何测试,AOE网

2023-12-30 01:50
文章标签 java 测试 aoe

本文主要是介绍aoe网java如何测试,AOE网,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

AOE网实用场景

主要用在如何计算一个工程的完工时间,和优化工程方案减少工程完工时间。

辅助决策系统,工程管理、生产管理运用非常多。

也就是计算关键路径,也可以说是最长路径。

1、概念

在一个表示工程的带权有向图中,用顶点表示事件,用有向边表示活动,用边上的权值表示活动的持续时间,这种有向图的边表示活动的网,我们称之为AOE网。

2、特点

有向无环图

拓扑排序

没有入度的顶点称为始点或源点。

没有出度的顶点称为终点或汇点。

关键路径,就是求最大的路径。

一般是一个开始点,一个结束点。

2、排序算法

算法的结果就是找到关键路径

etv(Earliest Time Of Vertex) 事件最早发生时间,顶点最早发生时间。

ltv(Latest Time Of Vertex) 事件最晚发生时间,顶点最晚发生时间。

ete(Earliest Time Of Edge) 活动最早开始时间,边最早开始时间。

lte(Latest Time Of Edge) 活动最晚开始时间,边最晚开始时间。

51873c24bdfa

1.png

51873c24bdfa

2.png

51873c24bdfa

3.png

3、代码实现

import java.util.ArrayList;

import java.util.List;

/**

* author: bobo

* create time: 2019/1/11 5:36 PM

* email: jqbo84@163.com

*/

public class AOE {

//根据上面的图来定义数组的长度

int LENGHT = 9;

// etv(Earliest Time Of Vertex) 事件最早发生时间,顶点最早发生时间

int[] etv = new int[LENGHT];

// ltv(Latest Time Of Vertex) 事件最晚发生时间,顶点最晚发生时间

int[] ltv = new int[LENGHT];

// ete(Earliest Time Of Edge) 活动最早开始时间,边最早开始时间

int[] ete = new int[LENGHT];

// lte(Latest Time Of Edge) 活动最晚开始时间,边最晚开始时间

int[] lte = new int[LENGHT];

int[] stack2 = new int[LENGHT];

int top2 = 0;

/**

* 拓扑排序算法

*

* @param graphAdjList 拓扑图数组集

* @return

*/

public List topologicalSort(VertexNode[] graphAdjList) {

int top = 0; //栈顶指针, 对应索引值

int[] stack = new int[LENGHT];//用来存放入度为0的顶点,数组效率最高,存放顶点的下标索引值

//循环得到入度为0的所有顶点

for (int i = 0; i < graphAdjList.length; i++) {

VertexNode vertexNode = graphAdjList[i];

if (vertexNode.in == 0) {

stack[++top] = i;

}

}

//开始算法的逻辑

List resultList = new ArrayList<>();

while (top != 0) {

int getTop = stack[top--];

resultList.add((T) graphAdjList[getTop].data);

//保存拓扑序列顺序

stack2[top2++] = getTop;

//更新当前输出节点所有的出边(后继顶点)

for (EdgeNode e = graphAdjList[getTop].first; e != null; e = e.next) {

int index = e.index;

//入度减一

graphAdjList[index].in--;

if (graphAdjList[index].in == 0) {

stack[++top] = index;

}

// 1. 计算顶点的最早开始时间

if(etv[index] < (etv[getTop] + e.weight)){

etv[index] = etv[getTop] + e.weight;

}

}

}

return resultList;

}

/**

* 关键路径算法

*/

public void criticalPath(VertexNode[] graphAdjList){

// List topologicalSortList = topologicalSort(graphAdjList);

//初始化顶点最晚发生时间(ltv)都为汇点时间

for (int i = 0; i < LENGHT; i++) {

ltv[i] = etv[LENGHT - 1];

}

//从汇点开始倒过来计算 顶点的最晚开始时间(ltv)

while (top2 > 0) {

int getTop = stack2[--top2];//从汇点开始

for (EdgeNode e = graphAdjList[getTop].first; e != null; e = e.next) {

int index = e.index;

// 2. 计算顶点的最晚开始时间

if(ltv[index] - e.weight < ltv[getTop]){

ltv[getTop] = ltv[index] - e.weight;

}

}

}

//通过 etv 和 ltv 计算出ete 和 lte

for (int i = 0; i < LENGHT; i++) {

for (EdgeNode e = graphAdjList[i].first; e != null; e = e.next) {

int index = e.index;

ete[i] = etv[i];// 3. 边最早的时间 ete,就是顶点最早时间 etv

lte[i] = ltv[index] - e.weight; // 4. 计算边最晚发生时间,ltv[index]里面已经是选的最小的权重

// if(ete[i]==lte[i]){

// System.out.println(graphAdjList[i].data+" "+graphAdjList[index].data+" "+e.weight);

// }

}

}

}

/**

* 边表节点

*/

class EdgeNode {

int index; //用来存放顶点的下标索引值

int weight; //存放边的权重值

EdgeNode next;

public EdgeNode(int index, EdgeNode next) {

this.index = index;

this.next = next;

}

public EdgeNode(int index, int weight, EdgeNode next) {

this.index = index;

this.weight = weight;

this.next = next;

}

}

/**

* 顶点表节点

*/

class VertexNode {

int in;//入度

T data;

EdgeNode first;

public VertexNode(int in, T data, EdgeNode first) {

this.in = in;

this.data = data;

this.first = first;

}

}

}

5、测试

@Test

public void main(){

VertexNode[] graphAdjList = new VertexNode[9];

EdgeNode a = new EdgeNode(3, 5, null);

EdgeNode a2 = new EdgeNode(2, 4, a);

EdgeNode a3 = new EdgeNode(1, 6, a2);

graphAdjList[0] = new VertexNode(0, 1, a3);

EdgeNode b1 = new EdgeNode(4, 1, null);

graphAdjList[1] = new VertexNode(1, 2, b1);

EdgeNode c1 = new EdgeNode(4, 1, null);

graphAdjList[2] = new VertexNode(1, 3, c1);

EdgeNode d1 = new EdgeNode(5, 2, null);

graphAdjList[3] = new VertexNode(1, 4, d1);

EdgeNode e1 = new EdgeNode(7, 5, null);

EdgeNode e2 = new EdgeNode(6, 7, e1);

graphAdjList[4] = new VertexNode(2, 5, e2);

EdgeNode f2 = new EdgeNode(7, 4, null);

graphAdjList[5] = new VertexNode(1, 6, f2);

EdgeNode f3 = new EdgeNode(8, 2, null);

graphAdjList[6] = new VertexNode(1, 7, f3);

EdgeNode f4 = new EdgeNode(8, 4, null);

graphAdjList[7] = new VertexNode(2, 8, f4);

graphAdjList[8] = new VertexNode(2, 9, null);

List list = (List) topologicalSort(graphAdjList);

System.out.print("拓扑序列:");

for (Integer integer : list) {

System.out.print(integer + " ");

}

System.out.println();

//打印关键路径

criticalPath(graphAdjList);

System.out.print("顶点最早发生时间: ");

for (int i = 0; i < LENGHT; i++) {

System.out.print(etv[i] + " ");

}

System.out.println();

System.out.print("顶点最晚发生时间: ");

for (int i = 0; i < LENGHT; i++) {

System.out.print(ltv[i] + " ");

}

System.out.println();

System.out.print("边最早发生的时间: ");

for (int i = 0; i < LENGHT; i++) {

System.out.print(ete[i] + " ");

}

System.out.println();

System.out.print("边最晚发生的时间: ");

for (int i = 0; i < LENGHT; i++) {

System.out.print(lte[i] + " ");

}

System.out.println();

//打印关键路径

System.out.println("关键路径: ");

for (int i = 0; i < LENGHT; i++) {

for (EdgeNode e = graphAdjList[i].first; e != null; e = e.next) {

int index = e.index;

ete[i] = etv[i];

lte[i] = ltv[index] - e.weight;

if(ete[i]==lte[i]){

System.out.println("V(" + graphAdjList[i].data + ") -> V(" + graphAdjList[index].data + ") -> E(" + e.weight + ")");

}

}

}

}

6、结果

拓扑序列:1 4 6 3 2 5 8 7 9

顶点最早发生时间: 0 6 4 5 7 7 14 12 16

顶点最晚发生时间: 0 6 6 6 7 8 14 12 16

边最早发生的时间: 0 6 4 5 7 7 14 12 0

边最晚发生的时间: 1 6 6 6 7 8 14 12 0

关键路径:

V(1) -> V(2) -> E(6)

V(2) -> V(5) -> E(1)

V(5) -> V(7) -> E(7)

V(5) -> V(8) -> E(5)

V(7) -> V(9) -> E(2)

V(8) -> V(9) -> E(4)

这篇关于aoe网java如何测试,AOE网的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/551347

相关文章

java -jar命令运行 jar包时运行外部依赖jar包的场景分析

《java-jar命令运行jar包时运行外部依赖jar包的场景分析》:本文主要介绍java-jar命令运行jar包时运行外部依赖jar包的场景分析,本文给大家介绍的非常详细,对大家的学习或工作... 目录Java -jar命令运行 jar包时如何运行外部依赖jar包场景:解决:方法一、启动参数添加: -Xb

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

java中BigDecimal里面的subtract函数介绍及实现方法

《java中BigDecimal里面的subtract函数介绍及实现方法》在Java中实现减法操作需要根据数据类型选择不同方法,主要分为数值型减法和字符串减法两种场景,本文给大家介绍java中BigD... 目录Java中BigDecimal里面的subtract函数的意思?一、数值型减法(高精度计算)1.

Java空指针异常NullPointerException的原因与解决方案

《Java空指针异常NullPointerException的原因与解决方案》在Java开发中,NullPointerException(空指针异常)是最常见的运行时异常之一,通常发生在程序尝试访问或... 目录一、空指针异常产生的原因1. 变量未初始化2. 对象引用被显式置为null3. 方法返回null

一文彻底搞懂Java 中的 SPI 是什么

《一文彻底搞懂Java中的SPI是什么》:本文主要介绍Java中的SPI是什么,本篇文章将通过经典题目、实战解析和面试官视角,帮助你从容应对“SPI”相关问题,赢得技术面试的加分项,需要的朋... 目录一、面试主题概述二、高频面试题汇总三、重点题目详解✅ 面试题1:Java 的 SPI 是什么?如何实现一个

Spring中管理bean对象的方式(专业级说明)

《Spring中管理bean对象的方式(专业级说明)》在Spring框架中,Bean的管理是核心功能,主要通过IoC(控制反转)容器实现,下面给大家介绍Spring中管理bean对象的方式,感兴趣的朋... 目录1.Bean的声明与注册1.1 基于XML配置1.2 基于注解(主流方式)1.3 基于Java

SpringCloud中的@FeignClient注解使用详解

《SpringCloud中的@FeignClient注解使用详解》在SpringCloud中使用Feign进行服务间的调用时,通常会使用@FeignClient注解来标记Feign客户端接口,这篇文章... 在Spring Cloud中使用Feign进行服务间的调用时,通常会使用@FeignClient注解

Java Spring 中的监听器Listener详解与实战教程

《JavaSpring中的监听器Listener详解与实战教程》Spring提供了多种监听器机制,可以用于监听应用生命周期、会话生命周期和请求处理过程中的事件,:本文主要介绍JavaSprin... 目录一、监听器的作用1.1 应用生命周期管理1.2 会话管理1.3 请求处理监控二、创建监听器2.1 Ser

JVisualVM之Java性能监控与调优利器详解

《JVisualVM之Java性能监控与调优利器详解》本文将详细介绍JVisualVM的使用方法,并结合实际案例展示如何利用它进行性能调优,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全... 目录1. JVisualVM简介2. JVisualVM的安装与启动2.1 启动JVisualVM2

Java如何从Redis中批量读取数据

《Java如何从Redis中批量读取数据》:本文主要介绍Java如何从Redis中批量读取数据的情况,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一.背景概述二.分析与实现三.发现问题与屡次改进3.1.QPS过高而且波动很大3.2.程序中断,抛异常3.3.内存消