首页 > 其他分享 >JGraphT计算关键路径

JGraphT计算关键路径

时间:2023-08-21 18:02:16浏览次数:39  
标签:jgrapht activityGraph graph 路径 JGraphT org import addEdge 关键

简介

JGraphT 是一个Java实现的图论数据结构和算法库。本文讲介绍通过JGaphT来计算关键路径。

关键路径:用于在进度模型中估算最短工期,关键路径是项目中时间最长的活动时间。


案例

描述

下图Graph1-进度网络图表示项目的各项任务关系图以及任务的预计工期。为了采用图计算,这里将任务的预期工期转换为边的权重,如图Graph2-从后往前推,Graph3-从前往后推两种方式。

Graph2-从后往前推:边的权重表示箭头指向的任务预期工期。

Graph3-从前往后推:边的权重表示箭尾指向的任务预期工期。

JGraphT计算关键路径_JavaGraph


程序准备

通过JGraphT构建图和计算路径,引入对应的库。这里采用maven管理依赖。

<dependency>
  <groupId>org.jgrapht</groupId>
  <artifactId>jgrapht-core</artifactId>
  <version>1.5.2</version>
</dependency>

<!-- 可选,扩展能力 -->
<dependency>
  <groupId>org.jgrapht</groupId>
  <artifactId>jgrapht-ext</artifactId>
  <version>1.5.2</version>
</dependency>
<dependency>
  <groupId>org.jgrapht</groupId>
  <artifactId>jgrapht-io</artifactId>
  <version>1.5.2</version>
</dependency>


程序示例1

示例2采用JGraphT提供的具体图实现类创建图,通过对应的API实现新增顶点,边,以及边的权重设置。

package org.deeplearning.graph;

import com.mxgraph.layout.mxCircleLayout;
import com.mxgraph.layout.mxIGraphLayout;
import com.mxgraph.util.mxCellRenderer;
import org.jgrapht.Graph;
import org.jgrapht.GraphPath;
import org.jgrapht.alg.cycle.CycleDetector;
import org.jgrapht.alg.shortestpath.AllDirectedPaths;
import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
import org.jgrapht.ext.JGraphXAdapter;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.SimpleDirectedWeightedGraph;
import org.jgrapht.graph.builder.GraphTypeBuilder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class CriticalPath {

    public static void main(String[] args) {

        // 构造图
        Graph<String, DefaultEdge> activityGraph = buildStyle1();

        // 检测是否有环
        CycleDetector<String, DefaultEdge> cycleDetector = new CycleDetector<>(activityGraph);
        System.out.println("图是否有环:" + cycleDetector.detectCycles());

        // Dijkstra 最短路径
        DijkstraShortestPath<String, DefaultEdge> dijkstraShortestPath = new DijkstraShortestPath<>(activityGraph);
        GraphPath<String, DefaultEdge> dijkstraGraphPath = dijkstraShortestPath.getPath("A", "G'");
        System.out.println(dijkstraGraphPath.getVertexList());

        // C->G G' 所有路径
        AllDirectedPaths<String, DefaultEdge> allDirectedPaths = new AllDirectedPaths<>(activityGraph);
        allDirectedPaths.getAllPaths("A", "G'", true, null).forEach(it -> {
            System.out.println(it.getVertexList() + " weight=" + it.getWeight());
        });
    }

    private static SimpleDirectedWeightedGraph<String, DefaultEdge> buildStyle1() {

        SimpleDirectedWeightedGraph<String, DefaultEdge> activityGraph = new SimpleDirectedWeightedGraph<>(DefaultEdge.class);

        //添加顶点
        activityGraph.addVertex("A");
        activityGraph.addVertex("B");
        activityGraph.addVertex("C");
        activityGraph.addVertex("D");
        activityGraph.addVertex("E");
        activityGraph.addVertex("F");
        activityGraph.addVertex("G");
        activityGraph.addVertex("G'");

        //添加边
        activityGraph.addEdge("A", "B");
        activityGraph.addEdge("A", "C");
        activityGraph.addEdge("A", "D");

        activityGraph.addEdge("B", "E");
        activityGraph.addEdge("B", "F");
        activityGraph.addEdge("C", "F");

        activityGraph.addEdge("E", "G");
        activityGraph.addEdge("F", "G");
        activityGraph.addEdge("D", "G");

        activityGraph.addEdge("G", "G'");

        //设置边权重
        activityGraph.setEdgeWeight("A", "B", 4.0D);
        activityGraph.setEdgeWeight("A", "C", 4.0D);
        activityGraph.setEdgeWeight("A", "D", 4.0D);

        activityGraph.setEdgeWeight("B", "E", 5.0D);
        activityGraph.setEdgeWeight("B", "F", 5.0D);
        activityGraph.setEdgeWeight("C", "F", 4.0D);

        activityGraph.setEdgeWeight("E", "G", 4.0D);
        activityGraph.setEdgeWeight("F", "G", 1.0D);
        activityGraph.setEdgeWeight("D", "G", 7.0D);

        activityGraph.setEdgeWeight("G", "G'", 2.0D);

        return activityGraph;
    }
}

程序示例2

示例2采用JGraphT提供的Builder模式来生成不同类型的图,以及图的构建。比如:有向图,有权重,不存在自身环,不存在多边,通过新增边来完成顶点,边,权重的设置。

package org.deeplearning.graph;

import com.mxgraph.layout.mxCircleLayout;
import com.mxgraph.layout.mxIGraphLayout;
import com.mxgraph.util.mxCellRenderer;
import org.jgrapht.Graph;
import org.jgrapht.GraphPath;
import org.jgrapht.alg.cycle.CycleDetector;
import org.jgrapht.alg.shortestpath.AllDirectedPaths;
import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
import org.jgrapht.ext.JGraphXAdapter;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.SimpleDirectedWeightedGraph;
import org.jgrapht.graph.builder.GraphTypeBuilder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class CriticalPath {

    public static void main(String[] args) {

        // 构造图
        Graph<String, DefaultEdge> activityGraph = buildStyle2();

        // 检测是否有环
        CycleDetector<String, DefaultEdge> cycleDetector = new CycleDetector<>(activityGraph);
        System.out.println("图是否有环:" + cycleDetector.detectCycles());

        // Dijkstra 最短路径
        DijkstraShortestPath<String, DefaultEdge> dijkstraShortestPath = new DijkstraShortestPath<>(activityGraph);
        GraphPath<String, DefaultEdge> dijkstraGraphPath = dijkstraShortestPath.getPath("A", "G'");
        System.out.println(dijkstraGraphPath.getVertexList());

        // C->G G' 所有路径
        AllDirectedPaths<String, DefaultEdge> allDirectedPaths = new AllDirectedPaths<>(activityGraph);
        allDirectedPaths.getAllPaths("A", "G'", true, null).forEach(it -> {
            System.out.println(it.getVertexList() + " weight=" + it.getWeight());
        });
    }


    //构造图
    private static Graph<String, DefaultEdge> buildStyle2() {
        return GraphTypeBuilder.<String, DefaultEdge>directed()
                .vertexClass(String.class)
                .edgeClass(DefaultEdge.class)
                .weighted(true)
                .allowingSelfLoops(false)
                .allowingMultipleEdges(false)
                .buildGraphBuilder()
                .addEdge("A", "B", 4.0D)
                .addEdge("A", "C", 4.0D)
                .addEdge("A", "D", 4.0D)
                .addEdge("B", "E", 5.0D)
                .addEdge("B", "F", 5.0D)
                .addEdge("C", "F", 4.0D)
                .addEdge("E", "G", 4.0D)
                .addEdge("F", "G", 1.0D)
                .addEdge("D", "G", 7.0D)
                .addEdge("G", "G'", 2.0D)
                .build();
    }
}

输出结果

图是否有环:false
[A, C, F, G, G']
[A, B, F, G, G'] weight=12.0
[A, B, E, G, G'] weight=15.0
[A, C, F, G, G'] weight=11.0
[A, D, G, G'] weight=13.0

结果分析

上述程序示例1和程序示例2的代码基于Graph3-从前往后推构建图,区别在于构建图采用的JGraphT API不同,其它是相同的。从输出结果分析:

  • 图不存在环,符合我们创建图的参数设置
  • 最短路径 A-C-F-G-G' 符合人工计算的结果
  • 所有从A到G‘的路径以及权重和符合人工计算的结果
  • 根据关键路径的定义,那么图Graph1-进度网络图中关键路径则是A到G'的最长路径(权重最大)即:A->B->E->G (注意不含G' 因为G'是我们为了采用图的路径计算引入的)

图相关资料


标签:jgrapht,activityGraph,graph,路径,JGraphT,org,import,addEdge,关键
From: https://blog.51cto.com/aiilive/7178098

相关文章

  • 如何找到 Java安装目录的路径以及如何重新安装java
    要找到Java安装目录的路径,可以按照以下步骤进行:1.打开文件资源管理器(Windows资源管理器)。2.导航到你的计算机的C盘或系统盘。3.在C盘或系统盘上查找一个名为"ProgramFiles"或"程序文件"的文件夹。如果你的计算机是64位操作系统,可能会有两个类似的文件夹,一个是"ProgramFile......
  • 路径规划算法:基于指数分布优化的机器人路径规划算法- 附matlab代码
     ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • Visual Studio 修改NuGet 包路径
    目的:通过NuGet安装包时,NuGet先将包下载至一个统一的目录,默认路径是:C:\Users\{用户名}\.nuget\packages。现在需要将其迁移到目录E:\nuget\packages步骤1、在C:\ProgramFiles(x86)\NuGet\Config目录中找到Microsoft.VisualStudio.Offline.config。在文件末尾添加......
  • 沃通资讯| 关键技术领域频遭制裁,国产化替代刻不容缓
    美再次发布9项制裁措施,规定芯片企业需要获得许可证才能对中国出售用在人工智能、超级电脑的先进芯片产品或技术服务,制裁目的是阻止中国芯片技术发展。进入信息全球化时代,高性能计算机、超级电脑、自动驾驶汽车、人工智能等设备的核心就是高端芯片。而我国芯片供给市场长期依靠国外......
  • 视频直播点播平台EasyDSS排查WebRTC搭建TURN服务时openssl路径问题。
    我们曾经介绍了WebRTC所必需的STUN/TURN服务,并尝试了在Windows上搭建TURN服务的过程。为了在Windows上编译并使用TURN服务,我们需要安装Cygwin64环境,并进行相应的配置和编译工作。然而,在我们下载、编译和安装coturn时,遇到了一个报错:“ERROR:OpenSSLCrypto开发库未在所需位置正确安......
  • mysql 关键字 保留字
     MySQL::MySQL8.0ReferenceManual::9.3KeywordsandReservedWordshttps://dev.mysql.com/doc/refman/8.0/en/keywords.html9.3 KeywordsandReservedWordsKeywordsarewordsthathavesignificanceinSQL.Certainkeywords,suchas SELECT, DELET......
  • 路径相关
    下载的软件存放位置/var/cache/apt/archives安装后软件默认位置/usr/share可执行文件位置/usr/bin配置文件位置/etclib文件位置/usr/lib......
  • 高效试错,敏捷迭代——火山引擎AB测试帮助这个企业掌握「关键能力」
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 最近,乐刻的“百城万店”战略在行业激起了许多讨论。在传统健身馆经营承压、服务业难标准化的语境里,这家创业公司的实践值得被一再研究。乐刻创立至今已有8年,目前拥有乐刻健身、FEELINGM......
  • python生成相对于入口文件所在目录的绝对路径
    在VSCODE中,如果打开多个python文件夹,则在执行python文件时,有时候当前工作目录会切换到其他文件夹,导致保存和读取文件报错.这时候可以生成文件的绝对路径,就可以避归这个问题.下面是生成绝对路径的代码:importosimport__main__defAbsPath(fileName:str)->str:......
  • C++ 隐式转换与explicit关键字
    隐式转换与explicit关键字隐式转换函数构造的隐式转换,直接上代码:#include<bits/stdc++.h>classEntity{private: std::stringm_Name; intm_Age;public: Entity(conststd::string&name) :m_Name(name),m_Age(-1){} Entity(intage) :m_Name("Unknown"),m_A......