基于 Java 语言双代号网络图自动绘制系统

基于Java语言双代号网络图自动绘制系统研究与实现

一、摘要

网络计划技术已被广泛应用于工业、农业、国防、科学研究等多个领域中的项目计划与管理,以缩短项目周期,提高资源的利用效率。在网络计划技术中,绘制网络图是网络计划技术的基础工作,但在国内,长期以来双代号网络图的绘制一直依靠手工,手工绘制效率低、调整困难,严重阻碍网络计划技术的应用与发展。本文试图基于网络计划技术及相关开发技术,构建一个双代号网络图自动绘制系统,以解决双代号网络图绘制效率低、调整困难等突出问题。

本文首先对网络计划技术进行了分析、讨论,依据网络计划技术,剥离出双代号网络图自动绘制中的关键问题,并对其进行了分析、探讨。在上述分析研究的基础上,结合煤矿企业井巷与安装工程项目的特点及适当的开发技术,设计并实现双代号网络图绘制中的关键算法------对工序编号和对节点的布置的算法,并依据软件工程的理论,分析、设计出双代号网络图自动绘制系统,最终实现了一个 B/S(浏览器/服务器)结构的双代号网络图自动绘制系统。在系统开发完成之后,使用平煤五矿某井巷与安装工程的实际数据对系统的可用性及可靠性进行了验证。

关键词:双代号网络图;自动绘制;B/S;UML;

二、绪论

2.1、研究目的及意义

2.1.1、研究背景

本选题中国地质大学(武汉)经济管理学院与的合作项目------。工程历时 2 年半,耗资人民币 3 亿,工序繁多且复杂。对各项工序进行科学合理的安排,对时间和资金的投放进行优化、统筹安排,将极大程度的提高工程的进度及资金的使用效率,节约大量的人力、物力、财力。

在网络计划技术中,科学合理安排工序的前提是绘制出工程项目的网络计划图,并计算出工程的关键路径。在工序繁多、工序之间关系复杂的工程项目中,人工绘制网络计划图是一件繁杂且耗时低效的工作,严重制约着网络计划技术在实际项目中的应用。如果计算机能根据工程项目的基础数据,绘制出网络计划图,将极大的提高网络计划图的绘制效率,促进网络计划技术在实际项目中的应用与发展,本选题正是针对问题进行分析、研究的。

2.1.2、研究意义

本研究的意义表现在:(1) 结合井巷与安装工程的实际,就 PERT 理论中网络计划图的绘制,提出一套切实可行的自动绘图算法,丰富和完善双代号网络图的自动绘制技术;设计并实现一个网络计划图自动绘制系统,利用该系统可以根据工程项目的基础数据自动绘制出工程项目的网络计划图,弥补人工绘制网络图的弊端,提高绘图效率,促进网络计划评审技术在实际工程项目中的应用及网络计划技术的发展。

根据双代号网络图绘制的基本原则,双代号网络图的自动绘制可定义为:根据工程项目的工序及工序之间的关系,确定工序的开始节点、结束节点,即为工序编号;再将节点与工序以适当的方式(主要是确定节点之间的相对位置)放置于画布上,即布点;最终形成双代号网络图。

双代号网络图的自动绘制必须遵循双代号网络图的绘制原则,那么在自动绘制双代号网络图时,就必须解决这两个关键的核心问题:

为每一个工序或活动设置开始节点及结束节点,也就是为工序编号;

按照一定的规则,为上一步中得到的节点设置坐标,将节点置于合适的位置。

目前的研究也主要集中在这两个核心问题上,此外,在编号过程中虚工序的判断与添加也是整个绘图过程中的难点与重点。

根据目前的研究资料,编号可采用以下两种思路:

使用邻接矩阵来存储工序之间的逻辑关系,基于邻接矩阵,同时结合双代号网络图的绘图原则对工序进行编号,在编号的过程中完成虚工序的检测与添加[2];

首先设置一个最初的起始节点,由此起始节点开始,将所有无紧前工序的工序的起始节点设置为该节点,同时为其添加结束节点,然后采用广度优先添加各工序的紧后工序编号,在此过程中完成虚工序的检测和处理,当所有工序都编号完毕时,将网络图汇集到一个汇点[3]。

对于布点,目前主要采用对节点进行分级、分层的方法来对节点进行布置[4],具体做法如下:

节点分级。第一个节点的级为 1,遍历所有节点,根据相关规则,确定遍历中当前节点的级数。

节点分层。第一个节点的层为 1,在对节点分级的基础上,依次对各级进行以下操作:对于当前级中的节点,当前节点的层等于其前驱节点中最小的层;完成对当前级中所有节点的分层之后,按照当前级中各节点层的大小,从小到大依次完成各节点的后续节点的分层操作。

完成节点的发级、分层之后,节点在画布上的位置也就已经确定,即完成了布点工作。

采用邻接矩阵或启发式的算法来对工序进行编号,在理论上都可以解决网络图自动绘制中的编号问题,虽然算法的入口并不复杂,但在编号的过程中需要考虑的情况过于繁多与复杂。

分级、分层的算法中,每一次分级,每一次分层,都需要通过比较大量的数据来为节点选择合适的级和层,这样就造成算法的时间复杂度较高,严重影响算法的执行效率!

2.2、选题目标及主要研究内容

2.2.1、选题目标

本选题以网络计划技术中的双代号网络图自动绘制作为出发点,通过设计网络图自动绘制中的编号、布点等算法自动绘制双代号网络图的应用系统,通过系统的自动绘制出可供实际使用的双代号网络图,为管理者和决策者提供切实有效的管理工具及决策辅助数据,促进工程项目高效、有序的完成。

针对双代号网络图自动绘制中的核心问题------编号、布点,及系统的设计问题,本选题拟从以下几个方面着手:

对双代号网络图进行分析、解剖,在此基础上设计编号、布点算法;

分析相关工程项目的需求、数据,建立数据库,为系统设计及开发准备数据基础;

根据对需求的分类、整理,结合当前可利用的技术手段,设计系统原型;

使用 Java,实现编号、布点等核心算法

与前台的数据交互接口;

通过 HTML、CSS、JavaScript、AJAX 等技术,完善系统用户界面及绘图功能

完成整个整个系统的设计与开发。

2.2.2、研究方法技术路线

采用先核心再逐步完善的研究方法,类似于软件开发中的原型法

2.2.3、设计核心算法

为实现双代号网络图的自动绘制,对工序的编号和对节点的布置是首先需要研究的两个核心问题,只有在解决了这两个核心问题的基础上,系统的设计与开发才有可能继续。

2.2.4、建立 MySQL 数据库

数据是网络图自动绘制的基础来源,为得到工序之间的逻辑关系、开工时间、完工时间、工期、资金预算等信息,首先需要对工程数据进行整理、分析、提炼出自动绘制网络图所需要的数据,设计数据结构,建立数据库,为后续绘图、数据管理提供数据支持。

设计双代号网络图自动绘制系统,即建立系统模型

本文提出的双代号网络图自动绘制系统采用 UML 进行建模。UML 作为一种定义良好、易于表达、功能强大且普遍适用的建模语言,UML 可以溶入到软件开发的生命周期中的不同阶段,使用 UML 对双代号网络图自动绘制系统进行建模,为系统的设计及开发提供了有力的支持与报障。在建模的过程中,结合考虑了使用的开发技术,以使设计的系统具备较高的可用性。这些技术包括:AJAX、JavaScript 等,为系统提供了良好的人机交互体验;XML,为系统的跨平台特性提供了更加完善的支持;MVC 模式, Java 的 MVC 模式已经相当成熟,并拥有相当多的开源 MVC 框架,为系统的快速构建提供支持。

  • 完善系统功能
  • 在关键算法及系统原型已经确立之后,根据系统的需求,在原型的基础上对系统功能进行扩充完善,增强系统功能,例如:添加打印,导出为图片等功能。
  • 重视系统分析与建模

本文以系统的思想为指导,进行自动绘制系统的设计及实现,根据 UML 的标准为自动绘制系统建模。根据系统的需求及相关理论的要求,分析设计系统中的核心算法,使最终绘制出的网络图既符合双代号网络图绘制的原则,又具有实际的使用价值。

2.2.5、理论与实践相结合

为工程项目的管理及跟踪提供依据是双代号网络图的实际意义,同时,双代号网络图自动绘制系统中的数据必须能够被实时更新及查询,因此,双代号网络图自动绘制系统必须符合双代号网络图理论的要求,同时又要满足工程项目的实际应用的需求,即理论与实践相互结合、协作。

2.3、论文框架

本文共有六章,其中第三、四、五章为本文的重点章节,主要阐述了本文所做的研究内容、研究方法、系统实现过程及本文的成果。

第一章介绍了研究的目的及意义,通过相关文献,对网络计划技术、双代号网络图、双代号网络图的自动绘制等做了简要的阐述说明,概述了本课题的研究内容及方法。

第二章中,由于系统开发中所选用的技术手段会对系统的设计及实现产生巨大的影响,故在本章中对双代号网络图自动绘制采用的多种技术手段进行了介绍、讨论。

第三章,使用 UML 语言,讨论了系统的需求,之后结合所选用的技术手段的特性,使用 UML 语言建立系统的设计方案。

第四章,讨论了双代号网络图自动绘制系统中的两个核心算法的设计思路及实现步骤等,为系统的后续开发铺垫基础。

第五章,以第三章的设计图为蓝本,使用 AJAX、JavaScript、XML、Java 等技术实现双代号网络图自动绘制系统,同时通过平煤五矿的实际工程项目中的数据对系统进行检验测试。

第六章为结束语,总结本文以及完成的研究内容及系统实现,指出当前系统中存在的不足及可以完善增强的部分,同时讨论了下一步的研究及改进方向。

2.3、方法

2.3.1、面向对象方法

面向对象方法即面向对象软件开发方法(Object-Oriented Software Development),又称 OOSD,它的组成和开发过程类似于结构化方法。OOSD 由面向对象分析(OOA)、面向对象设计(OOD)和面向对象程序设计(OOP)组成。

面向对象的系统分析与设计方法与其他方法的不同之处在于,它使人们分析、设计一个系统的方法尽可能的接近人们认识一个系统的方法。

2.3.2、UML

统一建模语言(UML 是 Unified Modeling Language 的缩写)是用来对软件密集系统进行可视化建模的一种语言,可用于为面向对象开发系统的产品进行说明、可视化、和编制文档[10]。

UML 可以贯穿软件开发周期中的每一个阶段,适于数据建模,业务建模,对象建模,组件建模。UML 作为一种模型语言,它使开发人员专注于建立产品的模型和结构,而不必纠缠于选用什么程序语言和算法实现。

2.3.3、B/S 结构

B/S(Browser/Server)结构,即浏览器/服务器结构。它是随着 Internet 技术的兴起,对 C/S 结构的一种变化或者改进的结构。

在 B/S 结构下,用户工作界面是通过 WWW 浏览器来实现,极少部分事务逻辑在前端(Browser)实现,主要事务逻辑被置于服务器端(Server)实现。这样可大大简化客户端电脑载荷,减轻系统维护与升级的成本和工作量,降低用户的总体成本(TCO)。

B/S 结构是一次性到位的开发,能实现不同的人员,从不同的地点,以不同的接入方式(比如 LAN, WAN, Internet/Intranet 等)访问和操作共同的数据。

使用 B/S 结构可以使工程项目的不同人员,在不同的地点,通过不同的接入方式,实时的查看工程项目的双代号网络图、查询工程项目的数据、对工程项目的数据进行实时的更新等,而不局限于地点、时间的限制。

2.3.4、Java

基于 Java 语言的跨平台性、安全性,在 B/S 结构中,服务器端可选用 Java 语言实现系统的业务逻辑需求。

Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言(以下简称 Java 语言)和 Java 平台的总称。用 Java 实现的 HotJava 浏览器(支持 Java applet)显示了 Java 的魅力:跨平台、动态的 Web、Internet 计算。

Java 平台由 Java 虚拟机(Java Virtual Machine)和 Java 应用编程接口(Application Programming Interface、简称 API)构成。Java 应用编程接口为 Java 应用提供了一个独立于操作系统的标准接口,可分为基本部分和扩展部分。在硬件或操作系统平台上安装一个 Java 平台之后,Java 应用程序就可运行。现在 Java 平台已经嵌入了几乎所有的操作系统。这样 Java 程序可以只编译一次,就可以在各种系统中运行。Java 应用编程接口已经从 1.1x 版发展到 1.2 版。目前常用的 Java 平台基于 Java1.4,最新版本为 Java1.7。

值得注意的是,从 Java 5 开始,Java 引入了一种称为 Annotation 的技术。简单的说,Annotation 是一种与一个程序元素相关联信息或者元数据的标注,它从不影响 Java 程序的执行,但是对例如编译器警告或者像文档生成器等辅助工具产生影响。

2.3.5、MVC 模式及 Stripes

本文中所提出的网络图自动绘制系统,采用 B/S 结构,在这样的结构之下,使用 MVC 模式进行系统的开发即成为首选,此外,MVC 模式的相关特性也可融入到系统的设计当中,使的系统结构清晰、简洁。

2.3.6、MVC 模式

MVC 英文即 Model-View-Controller,即把一个应用的输入、处理、输出流程按照 Model、View、Controller 的方式进行分离,这样一个应用被分成三个层------模型层、视图层、控制层。

视图(View)代表用户交互界面,对于 Web 应用来说,可以概括为 HTML 界面,但有可能为 XHTML、XML 和 Applet。一个应用可能有很多不同的视图,MVC 设计模式对于视图的处理仅限于视图上数据的采集和处理,以及用户的请求,而不包括在视图上的业务流程的处理,业务流程的处理交予模型(Model)处理。

模型(Model):就是业务流程/状态的处理以及业务规则的制定。业务流程的处理过程对其它层来说是黑箱操作,模型接受视图请求的数据,并返回最终的处理结果。业务模型的设计可以说是 MVC 最主要的核心。

业务模型有一个很重要的模型那就是数据模型。数据模型主要指实体对象的数据保存(持续化)。比如将一张订单保存到数据库,从数据库获取订单。我们可以将这个模型单独列出,所有有关数据库的操作只限制在该模型中。

控制(Controller)可以理解为从用户接收请求, 将模型与视图匹配在一起,共同完成用户的请求。划分控制层的作用也很明显,控制层就是一个分发器,选择什么样的模型,选择什么样的视图,可以完成什么样的用户请求。控制层并不做任何的数据处理。

模型、视图与控制器的分离,使得一个模型可以具有多个显示视图。如果用户通过某个视图的控制器改变了模型的数据,所有其它依赖于这些数据的视图都应反映到这些变化。因此,无论何时发生了何种数据变化,控制器都会将变化通知所有的视图,导致显示的更新。这实际上是一种模型的变化-传播机制。模型、视图、控制器三者之间的关系和各自的主要功能,如图 2.2-1 所示:

图 2.2-1 MVC 模式示意图

2.3.7、Stripes

和 Struts 1 和 Struts 2 类似,Stripes 同样是一种展示层 MVC 框架,用于快速构建 Web 程序。

在使用 Struts 1,Web Work 和 Struts 2 等框架的时候,通常需要大量额外的 XML 配置,当一个项目达到一定规模的时候,编写 Java 代码的同时还要维护大量的 XML 配置是件费神的事。Stripes 完全抛弃了这些框架的弊病,使用了最新的 Java 5 带来的技术,遵循"Convention over Configuration" 理念,只需要在 Java 代码中加入少量的 Annotation(参看 2.1 节),就可以完成配置,大量减少了代码的维护工作。Stripes 提供的特性如下:

零配置,不需要外部配置文件,这是 Stripes 最引人注目的特性。

强大的 binding 引擎,足以应对复杂的对象。

验证和类型转换机制非常容易使用和本地化。

良好的本地化支持,甚至在 JSP 页面之间跳转时仍然生效。

能够复用 Action Bean,将它作 View helper 使用。

简易的 indexed property 支持。

内置支持同一个 form 触发多个事件。

具备透明的文件上传能力。

支持增量开发。

相当灵活,易于扩展。

2.3.8、CSS

Cascading Style Sheets 即层叠样式表,用于为 HTML 文档定义样式及布局。例如,字体、颜色、边距、高度、宽度、背景图像、高级定位等。

在双代号网络图自动绘制系统中使用 CSS,可获得良好的用户界面布局、页面效果,提高系统的用户体验。

采用 CSS 有以下几个优点:

通过单个样式表控制多个文档的布局;

更精确的布局控制;

为不同的媒体类型(屏幕、打印等)采取不同的布局;

无数高级、先进的技巧。

2.3.9、JavaScript

JavaScript 是由 Netscape 公司开发的一种脚本语言(scripting language),或者称为描述语言。在 HTML 基础上,使用 JavaScript 可以开发交互式 Web 网页。JavaScript 的出现使得网页和用户之间实现了一种实时性的、动态的、交互性的关系,使网页包含更多活跃的元素和更加精彩的内容。

JavaScript 短小精悍,又是在客户机上执行的,大大提高了网页的浏览速度和交互能力,使有规律地重复的 HTML 文段简化,减少下载时间。JavaScript 能及时响应用户的操作,对提交表单做即时的检查,无需浪费时间交由 CGI 验证。

术语 AJAX 用来描述一组技术,它使浏览器可以为用户提供更为自然的浏览体验,将 AJAX 应用到双代号网络图自动绘制系统中,可以使用户获得与桌面应用系统相媲美的操作体验。

AJAX 包含:

基于 XHTML 和 CSS 标准的表示;

使用 Document Object Model 进行动态显示和交互;

使用 XMLHttpRequest 与服务器进行异步通信;

使用 JavaScript 绑定一切。

传统的 Web 应用采用同步交互过程,用户向 HTTP 服务器触发一个请求,反过来,服务器执行某些业务逻辑,再向发出请求的用户返回一个 HTML 页面。这是一种不连贯的用户体验,服务器在处理请求的时候,用户多数时间处于等待中,屏幕内容也是一片空白[10]。如图 2.2-2:

图 2.2-2 传统 Web 应用交互图

AJAX 在用户与服务器之间引入一个中间媒介------AJAX 引擎,从而允许用户与应用软件之间的交互过程异步进行,用户不要等到页面的刷新,而浏览器也不需要重新载入整个页面[10],如图 2.2-3 所示。

图 2.2-3 基于 AJAX 的 Web 应用交互图

2.4、数据交格式

2.4.1、XML

XML(Extensible Markup Language)即可扩展标记语言,它与 HTML 一样,都是 SGML(Standard Generalized Markup Language,标准通用标记语言)。XML 是 Internet 环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具。扩展标记语言 XML 是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立。

2.4.2、JSON

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于 JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999 的一个子集。

JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。

JSON 建构于两种结构:

"名称/值"对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。

值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。

三、面向对象方法的系统分析

3.1、需求分析

3.1.1、功能需求

双代号网络图自动绘制系统,顾名思义,核心功能为网络图的自动绘制,但,自动绘制的基础数据的管理也是系统必须具备的功能,具体功能需求如下所示:

工程项目管理,包括新建工程项目,即录入工程项目的基本信息;修改工程项目的基本信息、删除工程项目、查看工程项目基本信息等,如图 3.1-1 所示;

工序管理,包括新建工序;通过 Excel 文件导入工序数据;修改工序的基本信息,如图 3.1-2 所示;

图 3.1-1 工程项目管理的需求

图 3.1-2 工序信息管理的需求

双代号网络图相关,包括双代号网络图自动绘制;自定义双代号网络图样式,如图颜色、字体;缩放网络图;显示网络图的 XML 格式的数据;调整双代号网络图中的节点位置及保存调整后的结果,避免重复调整;打印网络图;打印预览,将网络图导出为图片,如图 3.1-3 所示;

图 3.1-3 与双代号网络图相关的需求

3.1.2、非功能需求

系统须采用 B/S 结构;

数据精确度:系统输入数据必须按照规定的格式输入,否则系统提示错误;

用户界面需求:用户界面应清晰,直观,友好,采用简单界面驱动方式,使用户具有持续的用户体验;

浏览器兼容性:系统应兼容各大主流浏览器,包括:IE6、IE7、Firefox3.0 及以上、Chromium(谷歌浏览器)、Safari、Opera 等;

故障异常处理:保证系统容错性和稳定性,运行时若出现不可修复的错误,也应保证数据安全。

3.2、系统静态模型

根据对系统的功能需求,自动绘制系统的用例图如图 3.2-1 所示。

图 3.2-1 双代号网络图自动绘制系统用例图

用户与系统的交互,主要就是与工程项目管理、工序信息管理、网络图管理三个主要功能进行交互,那么系统的功能模块可根据这三个主要功能相应的设计为:工程项目管理模块、工序信息管理模块、网络图模块,此外,系统的非功能性需求中,要求系统采用 B/S 结构,根据以上需求,可建立系统的总体模型,如图 3.2-3 所示。从图中,我们可以看到,客户端及服务器均采用了多种技术或组件,这样设计的优点包括:

在客户端,使用 JavaScript 配合 CSS 及 HTML 能够对用户的非数据请求(即用户的操作不需要从服务器端请求数据)进行快速响应,使用户的操作不会被打断,给用户良好的持续的用户体验;使用 AJAX 可以对用户的数据请求进行响应,通过异步的方式将用户的请求发送到服务器,用户无需等待服务器对请求的处理便可进行其他的操作,同时,用户的浏览器不会出现空白这样的等待体验,客户端界面设计如图 3.2-2 所示。

在服务器端,使用 Stripes 框架对用户的请求进行分发、预处理,然后将用户的请求交予适当的 Action 类进行处理,Action 根据需要与数据库、服务器端文件系统进行交互,将处理的结果以 JSON 及 XML 的格式发送到客户端的 JavaScript,再由 JavaScript,辅助 CSS 完成对数据的展现。

服务器端结构如图 3.2-4 所示。action 包中的类主要用于处理来自于客户端的请求,通过与数据库、其他类进行交互,形成对用户请求的响应;dao 包中的类是与数据库进行交互的主要入口,通过 dao 包中的类,可以执行对数据的增删改查等操作;diagram 包则是自动绘制网络图算法的实现包;系统中传递的工程项目对象、工序对象、节点对象等基础对象均来自 pojo 包;security 包则是系统安全的保证,防止系统被未授权的访问破坏;系统中的一些公共功能则处于 util 包中。

图 3.2-2 双代号网络图自动绘制系统客户端设计图

图 3.2-3 双代号网络图自动绘制系统之系统结构图

图 3.2-4 双代号网络图自动绘制系统服务器端包图

3.3、系统动态模型

在建立了系统的总体模型之后,根据需求,可以建立起系统的动态模型,通过系统的动态模型,可以清楚的描述双代号网络图自动绘制系统的工作流程,及各个功能模块之间的逻辑关系,如图 3.3-1 所示。

双代号网络图的自动绘制是基于工程项目的实际数据,故在绘制网络图之前,工程项目的数据必须存在于数据库中,并且数据的格式及之间的逻辑关系必须正确。

为保证绘图的原始数据的正确性,在进行绘图操作之前,必须对数据进行数据格式及逻辑关系合法性的验证,如合法性无法通过验证,则要求用户检查其输入,修改输入,直至数据满足合法性需求为止。

当自动绘制网络图所需要的数据都准备好之后,那么就可以根据数据及绘图算法,对工序进行编号、布点等处理,最终绘制出双代号网络图。

图 3.3-1 双代号网络图自动绘制系统活动图

3.4、数据库模型

数据库技术作为一种现代化的数据管理手段,已经被广泛应用于各个领域。在双代号网络图自动绘制系统中,同样需要对工程项目、工序信息等数据进行管理,借助数据库技术来管理这些数据,将很大程度上提高系统的可靠性及使用效率。

根据系统需求及对系统的分析设计,数据库可设计为如图 3.4-1 所示的结构。

数据库共有工程项目表(Project 表)、工序表(Process 表)、工序之间的关系表(PreRelation 表)、节点表(Node 表)。

工程项目表,包括以下字段:工程名称、工程前缀(用于为工程的工序生成标识时使用)、工程项目总计划工期、资金预算、计划开工时间、计划完工时间、施工单位、实际工期、实际消耗资金、实际开工时间、实际完工时间、XML 文件路径、工程项目最后一次修改的日期、最后一次绘图的日期。

工序表,包括以下字段:工序标识、工序名称、计划工期、实际工期、计划开工时间、实际开工时间、计划完工时间、实际完工时间、资金预算、实际消耗资金、年产出、开始节点、结束节点、是否是虚工序、是否是关键工序、是否已经开工、是否已经完工、所属工程项目、排序标识。

工序关系表,包括:当前工序,当前工序的紧前工序,排序标识。

节点表,包括:节点标签、X 坐标、Y 坐标、出度、入度、所属工程项目。

注意到,在工序表,及工序关系表中,有排序标识这样的字段,这是因为在绘制网络图之前需要对工序及工序的紧前工序进行排序预处理,排序操作会占用较多的系统运行时间,为提高系统的运行效率,设置此字段来避免不必要的重复排序。

各个表之间的关系,可参看图中的描述。

图 3.4-1 双代号网络图自动绘制系统数据库模型图

sql 复制代码
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for node
-- ----------------------------
DROP TABLE IF EXISTS `node`;
CREATE TABLE `node`  (
  `id` int(11) NOT NULL,
  `label` int(255) NULL DEFAULT NULL,
  `x` int(255) NULL DEFAULT NULL,
  `y` int(255) NULL DEFAULT NULL,
  `outDegree` int(255) NULL DEFAULT NULL,
  `inDegree` int(255) NULL DEFAULT NULL,
  ` projectld` int(255) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for prerelation
-- ----------------------------
DROP TABLE IF EXISTS `prerelation`;
CREATE TABLE `prerelation`  (
  `id` int(11) NOT NULL,
  `process` int(255) NULL DEFAULT NULL,
  `preProcess` int(255) NULL DEFAULT NULL,
  `ordering` int(255) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for process
-- ----------------------------
DROP TABLE IF EXISTS `process`;
CREATE TABLE `process`  (
  `id` int(11) NOT NULL,
  `sourceNode` int(255) NULL DEFAULT NULL,
  `targetNode` int(255) NULL DEFAULT NULL,
  `projectId` int(11) NULL DEFAULT NULL,
  `symbol` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  `name` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  `planPeriod` int(255) NULL DEFAULT NULL,
  `actualPeriod` int(255) NULL DEFAULT NULL,
  `planStartDate` datetime(0) NULL DEFAULT NULL,
  `planEndDate` datetime(0) NULL DEFAULT NULL,
  `actualStartDate` datetime(0) NULL DEFAULT NULL,
  `actualEndDate` datetime(0) NULL DEFAULT NULL,
  `planCost` double(10, 2) NULL DEFAULT NULL,
  `actualCost` double(10, 2) NULL DEFAULT NULL,
  `output` double(10, 2) NULL DEFAULT NULL,
  `isVirtual` enum('true','false') CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  `isCriticl` enum('true','false') CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  `isStarted` enum('true','false') CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  `isFinished` enum('true','false') CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  `ordering` int(255) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for project
-- ----------------------------
DROP TABLE IF EXISTS `project`;
CREATE TABLE `project`  (
  `id` int(11) NOT NULL,
  `name` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  `preSymbol` varchar(4) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  `planPeriod` int(255) NULL DEFAULT NULL,
  `planCost` double(10, 2) NULL DEFAULT NULL,
  `planStartDate` datetime(0) NULL DEFAULT NULL,
  `planEndDate` datetime(0) NULL DEFAULT NULL,
  `contractor` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  `actualPeriod` int(255) NULL DEFAULT NULL,
  `actualCost` double(10, 2) NULL DEFAULT NULL,
  `actualStartDate` datetime(0) NULL DEFAULT NULL,
  `actualEndDate` datetime(0) NULL DEFAULT NULL,
  `xmlPath` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  `lastModifyDate` bigint(20) NULL DEFAULT NULL,
  `xmlGenerateDate` bigint(20) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(11) NOT NULL,
  `username` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  `password` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  `email` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  `power` int(255) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

3.5、核心算法时序图

双代号网络图的自动绘制是双代号网络图自动绘制系统的实现前提、核心部分,在此,需要对绘图中所设计到的对象及对象之间的交互进行初步设计,以便对系统进行动态扩展及调整,绘图算法的时序图如图 3.5-1 所示。

在图 3.5-1 中,展现了网络图绘制所涉及到基本对象,包括:

Action 对象:当浏览器端的绘制网络的请求到达服务器端时,请求会被 Stripes(参看 2.2)中的控制器转发到相应的 action 对象,对用户的请求进行处理;

绘图入口对象,即 Draw PERT Diagram 对象。在 action 对象中,完全可以实现 Draw PERT Diagram 对象所实现的功能,但并没有这样设计,是因为考虑到框架的移植性,如果要将网络图自动绘制系统移植到其他的 MVC 框架中,这样的设计使得移植的过程无需考虑 MVC 框架之间的差异。

Data Access 对象。绘制网络图的第一步,就是从数据库中将工程项目的工序信息读取出来,供编号及布点算法使用,除此之外,该对象还负责将编号及布点等处理的结果保存到数据库中,即对数据进行持久化。

Number 对象。顾名思义,编号算法的实现对象,对工程项目的工序进行编号。

Lay Node 对象。当编号完成之后,Draw PERT Diagram 对象得到反馈,此时,Draw PERT Diagram 对象发送消息给 Lay Node 对象,通知其对工程项目的工序的节点继续布置,也就是设定其 X、Y 坐标。

当编号及布点都完成之后,Draw PERT Diagram 对象发送消息给 Generate XML 对象,通知其根据编号、布点的结果,生成网络图的 XML 格式的数据文件,防止对一个工程项目进行重复编号、布点等操作,同时也提高系统的响应效率。

这里需要指出的是,Number 类及 Lay Node 类的设计,使用了面向接口的设计方法,使得对编号和布点算法的扩充并不会影响其他部分的重构。

图中对象的职责清晰、明确、单一,是面向对象设计中单一职责原则的体现,也使得对象具有较高的可重用性。

图 3.5-1 双代号网络图自动绘制系统核心算法时序

四、系统关键算法设计

4.1、工序排序算法

编号算法

在对工序的节点进行编号之前,需要对工序按照一定的规则进行排序,保证编号时不会出现以下情况:

重复或遗漏编号;

一个工序的所有紧前工序还未全部完成编号,就对其进行编号,这样会出现某紧前工序的编号比该工序的编号还要大,这样就违反了双代号网络图绘制的基本原则。

具体的排序规则如下:

按照工序的开工时间升序排序,如果开工时间相同,则按照工序紧前工序集合的大小升序排序;

在上一步排序的基础上,根据工序的紧前工序集合的包含关系对上一步的排序结果进行调整。例如:A 工序的紧前工序集合被 B 工序的紧前工序集合包含,那么 A 工序应该位于 B 工序之前。

排序的核心程序代码片段如图 4.1-1 下:

图 4.1-1 编号前对工序进行排序的代码片段

4.2、工序编号算法分析与设计

编号算法分析

当工序没有紧前,那么当前工序的开始节点即可编号为 1,而结束节点的编号即为当前的最大编号加 1。

当工序只有一个紧前工序,那么当前工序的开始节点即为其紧前工序的结束节点的编号,其结束节点的编号则为其开始节点编号加 1。

当工序(记为 C)有多个紧前工序的时候,我们可以将工序的紧前工序分为以下 3 中情况:

当前工序 C 的紧前工序只有 C 一个紧后工序,没有其他的紧后工序;

当前工序 C 的紧前工序都有不同的开始节点,记为;

当前工序 C 的紧前工序都是从一个开始节点引出的,记为 1b;

当前工序 C 的紧前工序中,有的工序的开始节点相同,有的不相同,记为。

当前工序 C 的紧前工序中,有的紧前工序有除 C 以为的紧后工序,有的工序只有 C 一个紧后工序;

当前工序 C 的紧前工序都有不同的开始节点,记为;

当前工序 C 的紧前工序都是从一个开始节点引出的,记为 2b;

当前工序 C 的紧前工序中,有的工序的开始节点相同,有的不相同,记为。

当前工序 C 的紧前工序都有除 C 以外的其他的紧后工序。

交叉,即工序 C 的紧前工序的紧后工序的紧前工序与 C 有不同的交叉集,记为;

包含,即工序 C 的紧前工序的紧后工序的紧前包含 C 的紧前,记为 3b;

包含和交叉,即与 3b 的混合,记为;

对于、、、这几种情况,我们都需要对可以合并的工序的结束节点进行合并,1b、2b、、3b、等情况,均不需要进行合并。

同时,当我们对、、、等情况进行合并之后,情形就会变的和 1b、2b、、3b、是一样的,我们只需要考虑在对当前工序 C 进行编号的时候是否需要添加虚工序:

如果不需要添加虚工序,那么就可以直接对 C 进行编号;

如果需要添加虚工序,那么就要确定虚工序的开始节点和结束节点,然后就可以直接对 C 进行编号。

根据上述的分析,具体编号算法设计如下:

将当前工序 C 的紧前工序分离,分离为需要合并和不需要合并两类,需要合并的部分是一个数组的形式,因为一个工序的紧前工序,可能需要合并成多个组;分组的参数有两个:A、开始节点是否是同一个;B、紧前是否有其他的紧后工序。只有开始节点不同且没有其他紧后的工序才能进行合并。

分组的步骤:

根据有无其他紧后,将紧前工序分为合并和非合并;分离方法:根据有无其他的紧后先将紧前工序分为 A、B 两组,然后再在 B 组中,分离出开始节点不重复的紧前工序 C、D,那么 A+C 为不需要进行合并的组,B+D 为需要进行合并的组。

在合并类中,根据开始节点统计,从每一个开始节点引出的工序的个数,如果从一个开始节点引出的工序大于等于 2 个,那么以此开始节点引出的工序均不需要进行合并。

分组算法代码片段如图 4.2-1 所示:

图 4.2-1 分组算法代码片段

将需要合并的组进行合并,并将其放入不需要合并的分类中;

根据不需要合并的分类中,紧前工序的结束节点的个数就可以确定是否需要添加虚工序。如果紧前工序的结束节点只有一个,那么是不需要添加虚工序的,如果有 2 个或 2 个以上的结束节点,那么就需要添加虚工序;

添加需要添加的虚工序,将紧前工序的结束节点个数统一为一个;

从紧前工序的唯一结束节点开始,对当前工序 C 进行编号。

4.3、汇点算法

双代号网络图绘制原则要求一个网络图只能有一个开始节点及一个结束节点,而编号算法会使得网络图中存在多个结束节点,此时需要设计适当的算法将多个结束节点进行合并,使网络图的只有一个结束节点。

汇点算法描述如下:

  • 查询出所有没有紧后的工工序,并放入集合 A 中;
  • 找到集合 A 中,最大的结束节点 N;
  • 将结合 A 进行分离,从每一个开始节点取出一个工序来构成集合 B,剩余的工序构成集合 C;
  • 将集合 B 中的所有工序的结束节点设置为 N;
  • 从集合 C 中的每个工序的结束节点引虚工序到 N;
  • 保存汇点结果。

汇点算法的程序代码片段如图 4.3-1 所示:

图 4.3-1 汇点算法代码片段

4.4、布点算法

在布点算法中,主要目的就是要确定节点在画布上的相对位置,即节点 X、Y 坐标。

节点的 X 坐标可以根据与节点有关的工序的工期来确定,具体步骤为:

设置所有节点的初始坐标为 0,建立栈,栈结构为 < 节点 ID,Flag>;

设置第一个节点的坐标为 1,将该节点入栈;

采用深度优先原则,出栈,得到栈顶元素 C,如果 C 的 X 坐标小于 Flag,那么设置 C 的坐标为 Flag,否则保持 C 的 X 坐标不变。接下来,将以 C 为开始节点的工序的结束节点及(Flag+1)依次入栈;

循环第 3 步,直至栈为空。

算法代码片段如图 4.4-1 所示:

图 4.4-1 X 坐标计算算法代码片段

网络图中的一个节点,至少属于网络图中的一条路线,也就是说一个节点在网络图中的所有路线中,至少会出现一次,那么我们可以根据这个特点对节点的 Y 坐标进行计算:

根据深度优先原则,得出网络图中的所有路线,同时记录下路线中的节点个数,并计算路线的总时间,以便得出关键路线;

设置一个标识变量,保存当前的最大的 Y 坐标,分别记为:MY;

从节点数最多的路线开始,依次为路线上的节点设置 Y 坐标,具体计算方法如下:如果节点的 Y 坐标没有被设置,那么设置节点的 Y 坐标设置为 MY,但一条路线的 Y 坐标计算完成之后,MY++,进入下一条路线进行 Y 坐标的计算。

算法代码片段如图 4.4-2 所示:

图 4.4-2 Y 坐标计算算法代码片段

双代号网络图自动绘制系统采用 B/S 结构,故自动绘制系统的实现可分为服务器端的实现及浏览器端的实现两个部分。

4.5、服务器端的实现

在服务器端,采用 MVC 模式进行构架,采用 Java 语言 1.6 版本进行开发,使用了 stripes1.6 作为 MVC 框架,在 Stripes1.6 的支持下,通过 Hibernate3.2 与数据库持久层进行数据交互。

在使用 stripes 及 hibernate 之前必须对它们进行配置。下面的代码片段展示了 Stripes 在服务器端的配置:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  version="2.5">
  <filter>
    <display-name>Stripes Security Filter</display-name>
    <filter-name>StripesSecurityFilter</filter-name>
    <filter-class>net.sourceforge.stripes.security.controller.StripesSecurityFilter</filter-class>
    <init-param>
      <param-name>SecurityManager.Class</param-name>
      <param-value>com.autopertdiagram.security.SecurityManager</param-value>
    </init-param>
    <init-param>
      <param-name>UnauthorizedResolutionURL</param-name>
      <param-value>/index.jsp</param-value>
    </init-param>
    <init-param>
      <param-name>Interceptor.Classes</param-name>
      <param-value>
        net.sourceforge.stripes.security.controller.SecurityInterceptor,
        net.sourceforge.stripes.controller.BeforeAfterMethodInterceptor
      </param-value>
    </init-param>
    <init-param>
      <param-name>ActionResolver.Packages</param-name>
      <param-value>com.autopertdiagram.action</param-value>
    </init-param>
    <init-param>
      <param-name>ActionBeanContext.Class</param-name>
                                                                     <param-value>com.autopertdiagram.action.DefaultActionBeanContext</param-value>
                                                                     </init-param>
                                                                     <init-param>
                                                                     <param-name>LocalePicker.Locales</param-name>
                                                                     <param-value>zh_CN:UTF-8</param-value>
                                                                     </init-param>
                                                                     <init-param>
                                                                     <param-name>DebugMode</param-name>
                                                                     <param-value>true</param-value>
                                                                     </init-param>
                                                                     <init-param>
                                                                     <param-name>ExceptionHandler.Class</param-name>
                                                                     <param-value>com.autopertdiagram.util.DefaultExceptionHandler</param-value>
                                                                     </init-param>
                                                                     </filter>
                                                                     <filter-mapping>
                                                                     <filter-name>StripesSecurityFilter</filter-name>
                                                                     <url-pattern>*.jsp</url-pattern>
                                                                     <dispatcher>REQUEST</dispatcher>
                                                                     <dispatcher>ERROR</dispatcher>
                                                                     </filter-mapping>
                                                                     <filter-mapping>
                                                                     <filter-name>StripesSecurityFilter</filter-name>
                                                                     <servlet-name>StripesDispatcher</servlet-name>
                                                                     <dispatcher>REQUEST</dispatcher>
                                                                     </filter-mapping>

下面的代码片段展现了 hibernate 在系统中的配置:

xml 复制代码
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="dialect">
      org.hibernate.dialect.MySQLDialect
    </property>
    <property name="connection.url">
      jdbc:mysql://localhost:3306/autopertdiagram
    </property>
    <property name="connection.username">root</property>
    <property name="connection.password">123</property>
    <property name="show_sql">true</property>
    <property name="connection.driver_class">
      com.mysql.jdbc.Driver
    </property>
    <mapping class="com.autopertdiagram.pojo.User"/>
    <mapping class="com.autopertdiagram.pojo.Process"/>
    <mapping class="com.autopertdiagram.pojo.Project"/>
    <mapping class="com.autopertdiagram.pojo.Node"/>
    <mapping class="com.autopertdiagram.pojo.Prerelation" />
    </session-factory>
  </hibernate-configuration>

在配置完成之后,就可以在系统中使用 stripes、hibernate 了,图 5.1-1 中的 action 包就是 stripes 的支持下,系统中用于处理客户端请求的 action 类;图 5.1-2 展示了新建工程项目的业务逻辑处理 action 的代码片段,从图中,我们可以看到,通过 Java 提供的 annotation 技术,可以非常优雅、简洁的对来自客户端的数据进行校验。

图 5.1-1 与 stripes 有关的 action 包

图 5.1-2 action 类

在图 5.1-3 中的 pojo 包则是系统数据库表在系统中所对应的对象,dao 包的类则是完成与数据库的通信任务的,简单的说就是提供数据库的增删改查等功能的类。图 5.1-4 展现了与工程项目相关的 DAO 类中的 save 方法及 delete 方法,这两个方法分别用于保存新的工程项目到数据库和将工程项目从数据库中删除。

图 5.1-3 与 hibernate 有关的包

图 5.1-4 ProjectDAO 部分代码

4.6、客户端的实现

在客户端,主要采用 Javascript+Ajax 技术实现,JavaScript 主要提供客户端的用户交互支持,比如网络图缩放、打印、导出、调整节点位置等交互行为的支持;此外 Javascript+css 提供了具有良好用户体验的 GUI,提高系统的可用性、可操作性。根据 AJAX 技术的特点,AJAX 主要用于从后台服务器端请求数据,返回给前端浏览器,JavaScript 将获取到的数据以适当的格式将数据展现给用户。

如图 5.2-1 中所示,在系统的中使用了大量的 JavaScript 代码、CSS 样式文件。

图 5.2-1 客户端初始化文件

当图 5.2-1 中所列举的文件都加载到客户端之后,系统将通过 AJAX 的方式从后台服务器端请求数据,JavaScript 代码及 AJAX 代码如下图所示。图中的 dataUrl 属性的值被设置为一个相对路线的 URL 地址,AJAX 正是使用这个地址异步的向服务器端请求数据的,当然 AJAX 在系统中的应用并不仅局限于图中的样式。当数据从 dataUrl 所指向的服务器端 action 返回时,图中的 projectTree 对象(JavaScript 对象)将数据以树形结构展现给用户。

图 5.2-2 部分 JavaScript 及 AJAX 代码

在上图中,root 节点的 iconCls 属性设置的是 root 节点的图标样式,new-project-icon 样式可在 AutoPERTDiagramEditor.css 中找到其相应的定义,如下图所示。图中展示了使用 CSS 的方式为一个元素设置背景图片,同时是用 CSS 中的 important 语法,提升了该样式的重要性,当一个元素有多个背景样式时,important 语法使得浏览器优先选用该样式作为元素的样式。

图 5.2-3 部分 CSS 代码

4.7、客户端与服务器端的数据交互

服务器与浏览器端的数据交互采用 JSON 数据格式及 XML。工程项目及工序数据均采用 JSON 数据格式,而网络图的图形数据则采用 XML 格式。

下图为服务器端生成 JSON 格式的数据的代码片段:

图 5.3-1 服务器端生成 JSON 格式的数据

通过上图中的代码片段生产的 JSON 格式的数据如下所示:

json 复制代码
{"工程ID(只读)":2,"项目名称":"第二组","工序编号前缀(只读)":"B","计划工期":234,"实际工期":"未知","预算资金":3078,"实际资金":"未知","计划开工时间":"","实际开工时间":"未知","计划完工时间(只读)":"","实际完工时间(只读)":"未知","施工单位":"测试施工单位"}。

图 5.3-2 则是客户端向服务器端请求 JSON 格式的数据的代码片段,请求通过 AJAX 进行异步请求,当数据从服务器端返回到客户端时,系统是 JavaScript 对 JSON 格式的数据进行解析,然后交由相应的 JavaScript 对象进行数据的展现,即图中的语句:

javascript 复制代码
propertyGrid.setSource(Ext.util.JSON.decode(info));

图 5.3-2 客户端向服务器端请求 JSON 格式的数据

客户端与服务器端的 XML 格式的数据交换与上述机制类似,再此就不做详细阐述。

4.8、系统

待系统服务器 Tomcat6.0 启动后,用户在浏览器地址栏中输入 http://localhost:8080/AutoPERTDiagramEditor.html 即可打开系统的初始界面,如图 5.4-1 所示。可以注意到系统地址栏请求的只是一个 HTML 文件,并不是 JSP 或者是服务器端的动态脚本,因为系统采用 JavaScript 和 AJAX 来完成向服务器的请求。当请求到达服务器端时,系统会将 JavaScript 文件、CSS 文件、图片等资源发送给浏览器,此时浏览器需要加载的资源几乎是系统的全部资源,所以在第一次打开系统的时候,页面呈现出来的等待时间相对来说会稍微长一些,但一次加载便不需要重复的进行相同资源的请求与传输[12]。

图 5.4-1 系统初始界面

在图 5.4-1 中,系统的侧边栏已经列举出系统所管理的工程项目,在系统的所有静态数据加载完之后,系统会自动向服务器请求工程项目的数据,如图 5.4-2 所示,在系统请求数据的时候,用户得到系统正在请求数据的信息,提高用户的用户体验。当 JSON 格式的数据从服务器端传输回来时,即可看到图 5.4-1 中展示的数据。

图 5.4-2 请求工程项目数据

此时,用户可以双击工程项目列表中的工程项目,系统通过 JavaScript 将会对用户的双击事件做出反馈------从后台服务器请求工程项目的基础数据,同时,请求工程项目的网络图,如图 5.4-3、5.4-4 所示:

图 5.4-3 请求工程项目的网络图

图 5.4-4 请求工程项目的基本信息

当数据由服务器端返回到客户端时,系统将服务器端反馈的 JSON 格式的数据、XML 格式的数据分别进行解析之后展示给用户,如图 5.4-5、5.4-6 所示,数据如下所示:

工程项目的基本信息(JSON 格式):{"工程 ID(只读)":2,"项目名称":"第二组","工序编号前缀(只读)":"B","计划工期":234,"实际工期":"未知","预算资金":3078,"实际资金":"未知","计划开工时间":"","实际开工时间":"未知","计划完工时间(只读)":"","实际完工时间(只读)":"未知","施工单位":"测试施工单位"}。

网络图的部分数据(XML 格式):

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<mxGraphModel>
  <root>
    <mxCell id="0"/>
    <mxCell id="1" parent="0"/>
    <mxCell id="n21" value="1" style="ellipse;strokeColor=#CDEB8B;fillColor=#CDEB8B;shadow=1;fontStyle=1;fontSize=14" parent="1" vertex="1">
      <mxGeometry x="200" y="50" width="30" height="30" as="geometry"/>
    </mxCell>
    <mxCell>......

-5 工程项目的网络图

图 5.4-6 工程项目的基本信息

当工程项目的网络图打开之后,我们可以在左下角的缩略图窗口中,看到工程项目网络图的缩略图。当工程项目的网络图较大时,可通过缩略图来调整用户的视角,选择用户希望查看的网络图的局部,如图 5.4-7 所示:

图 5.4-7 网络图的缩略图

当用户单击网络图中的工序时,系统会对用户的这个单击事件进行响应,即从后台服务器请求该工序的数据,数据格式为 JSON,如下所示:

json 复制代码
{"工序ID(只读)":21,"工序编号(只读)":"B21","工序名称":"10.0","计划工期":1,"实际工期":"未知","预算资金":11,"实际资金":"未知","年产出":12,"计划开工时间":"","实际开工时间":"未知","计划完工时间(只读)":"","实际完工时间(只读)":"未知","虚工序(只读)":"否","关键工序(只读)":"否"}

请求时的界面如图 5.4-8 所示:

图 5.4-8 请求工序的基本数据

如果用户需要新建工程项目,那么用户可以单击工具栏(如图 5.4-9)中的新建工程项目的按钮,系统将弹出新建工程项目的窗口,帮助用户新建工程项目,如图 5.4-10 所示:

图 5.4-9 工具栏

图 5.4-10 新建工程项目窗口

当用户在工程项目列表中选中了工程项目之后,就可以为此工程项目建立工序,单击工具栏上的新建工序按钮,系统弹出新建工序窗口,如图 5.4-11 所示。

图 5.4-11 新建工序窗口

如图中所展示,系统会对用户的输入进行校验,并以友好的方式提示用户的输入错误,帮助用户修正输入,完成工程项目、工序的新建。

为工程项目新建工序,除使用上述方法之外,还可以通过导入 Excel 文件的方式来新建工序,导入 Excel 文件的窗口如图 5.4-12 所示,而 Excel 文件的格式,则如表-1 所示:

图 5.4-12 通过 Excel 文件导入工序信息

完成了工程项目、工序的查看、新建等,如用户需要对工程项目、工序的信息进行修改,用户可以双击属性窗口中相应选项卡中的相应字段进行修改,如果 5.4-13 所示:

图 5.4-13 修改工程项目的信息

此外网络图的打印、打印预览、及缩放、调整节点位置等辅助功能,在此就不一一论述了。

五、平煤

平煤集团某工程项目工序数据如表-1 所示,通过对工序的排序、编号、布点、虚工序添加、计算关键路线。测试结果如图所示。从图中可以看到,系统根据表-1 数据,自动绘制了双代号网络图,并根据工序之间的逻辑关系生成了必要的虚工序,完成了结尾的汇点,如图-2 所示。通过系统自动绘制出来的网络图,可能会存在一些交叉,有的不可避免的,有的则可以通过人工调整清除工序之间的交叉。通过多个实际工程项目的测试,由系统自动绘制的网络图可以满足一般工程项目的需求。

表 -1 某工程项目工序数据

ID 工序名称 紧前工序;工序 ID 间;用英文逗号;相分割 计划工期;(单位:日) 计划开工时间
1 回风井改装 2
2 总回风石门 1 3
3 专回下山 2 9
4 皮下山下车;场联络巷 3 10
5 掘进准备 4 1
6 -400 运输石门 9
7 皮带下山及煤仓 6 15
8 进风井及马头门 6
9 -400 进风井;井底车场 8 2
10 火药库 9 4
11 电机车充电室;修理室 10 2
12 注氮室及己;15-24090 机车场 11 2
13 己 15-24070 机车场 12 2
14 中部变电所 13 3
15 回风井井底车;场及上部变电所 4
16 -400 轨道石门 15 3
17 轨下山 16 5
18 轨下山下车;场及联络巷 17 1
19 水仓 18 3
20 辅助回风石门 1
21 辅助回风下山 20 1
22 招标及设备加工 3
23 设备验收到位 22 2
24 提升系统 23 12
25 设备验收到位 22 1
26 排水系统泵房;变电所 25 8
27 设备验收到位 22 2
28 消防洒水系统 27 7
29 设备验收到位 22 1
30 上部变电所 29 8
31 设备验收到位 22 2
32 瓦斯排放系统 31 13
33 己 15-24090;瓦斯排放巷 5,7,14,19,21,;24,26,28,30,32 4
34 己 15-24090 机巷 6,7,14,19,21,;24,26,28,30,32 2
35 己 15-24090 切眼 34 2
36 己 15-24090 风巷 8,7,14,19,21,;24,26,28,30,32 2
37 风巷矿务工程 36 2
38 中部变电所 8,7,14,19,21,;24,26,28,30,32 1

图 -2 某工程项目工序双代号网络图

六、结束语

本课题以煤矿企业井巷与安装工程作为出发点,以双代号网络图的自动化绘制为目标,通过对网络计划技术及相关开发技术的分析讨论,研究了如何通过计算机技术完成双代号网络图的自动绘制,同时实现工程项目数据的管理。

本课题的主要成果如下:

  • 设计并实现了双代号网络图自动绘制系统中的核心算法
  • 双代号网络图自动绘制中的核心算法,即编号、布点算法的实现,为网络图自动绘制系统的实现提供了基础,在此基础上才能建立起双代号网络图自动绘制系统。
  • 算法使用分类的思想进行设计,同时结合了 Java 语言的特性,使得算法的思想及实现清晰、简洁。
  • 设计开发了"双代号网络图自动绘制系统"

首先、整个系统采用 B/S 结构,使用 MVC 模式,AJAX 等多种技术手段,使整个系统具备桌面应用系统所具有的良好的持续的用户体验。系统除能自动绘制双代号网络图之外,还为用户提供了对网络图的一些基本操作,例如:改变网络图中节点的位置,自定义网络图中箭线、节点的样式、打印网络图等;

其次、系统还为工程项目数据的管理提供了支持,用户通过系统,可以创建工程项目,修改工程项目信息,查询工程项目的数据等,同时,工序数据的录入除传统的表单方式录入,系统还提供 Excel 文件直接导入功能,使得工序数据的录入更加方便、快捷。

最后、系统的可用性及可靠性在系统测试部分(参看节)实际工程项目的数据检验中得到了验证;系统具有的良好的交互设计及持续的用户体验在系统实现部分,也作了详细的阐述。

笔者在本课题的研究过程中,不断发现更多值得进一步深入研究的问题,但限于笔者知识水平及研究时间,仅在下文列出,以期下一步的深入研究:

网络图的打印

本课题中完成的双代号网络图自动绘制系统,虽然提供了网络图的打印功能,但仅适用与网络图规模及普通打印设备,此打印功能无法使用与规模较大的网络图,同时,也不使用于特殊的打印设备,目前的系统并不为特殊设备提供打印接口,且市场上的打印设备型号繁多,笔者目前还为对该领域做深入的研究讨论。

工序逻辑关系调整

在实际的工程项目中,由于采用新的技术或设备、或由于一些外在因素,需要工程项目中的工序之间的逻辑关系进行调整,具体情况可能包括:增加工序、修改工序之间的逻辑关系、删除工序。

增加工序对原有数据的影响相比较修改和删除来说要小很多,只需要对工程项目进行重新编号及布点即可绘制出新的双代号网络图。而修改工序之间的逻辑关系,则会对原有数据有较大的影响,需要先解除工序之间原有的逻辑关系,然后再建立工序之间新的逻辑关系;删除工序,则首先要解除工序之间的逻辑关系,然后根据用户指定或一定的规则将影响到的工序之间的逻辑关系重新建立起来。

在调整工序之间的逻辑关系时,需要调动的数据较大,如果中间出现纰漏,则会影响到整个工程项目工序之间的逻辑结构。

同时,这种逻辑关系的调整,通过对数据的调整,和可以通过可视化的方式来进行调整也是一个非常有意义的研究方向。

参考文献

张 卓.项目管理.北京:科学出版社,2005,107~110.

甘 焕,赵嵩正.双代号网络图虚工序的自动添加方法研究.计算机工程与设计.2007.28(16):4016~4018.

王 刚,孙济洲,李 文. 一种启发式双代号网络图自动生成算法. 计算机应用.2007.27(3):762~771.

强茂山,高少和.双代号分级网络图的优化布置和自动绘图.清华大学学报(自然 科学版).1998.38(1):10~14.

宋车梅.PERT 网络图绘制的研究:[硕士学位论文].四川: 西南交通大学,2003.

陈志华.双代号网络图计算机自动绘制研究.武汉理工大学学报(信息与管理工程版).2006.28(2):25~28.

黎 杰,李 力,邓 林.网络计划编制系统中网络图的自动生成.运筹与管理.1997.6(2):60~64.

张向东.双代号网络图中虚工作的判断方法.石家庄铁路职业技术学院学报.2005.4(3):49~52.

余平祥,张丽红,刘伟张等.双代号网络图自动生成系统研究与实现.杨广林. 农业系统工程理论与实践研究------全国农业系统工程学术研讨会论文集. 黑龙江中国农业工程学会,2006,74~80.Fowler Martin.UML Distilled A brief guide to the standard object modeling language. third edition.Addison-Wesley Professional,2003,35~130.

王 沛,冯曼菲.Web 2.0 开发技术详解.北京:人民邮电出版社,2006,10~11.Crane Dave,Pascarello Eric,James Darren.Ajax in action. Manning Publications,2005,211~277.

COOPER ALAN.交互设计之路------让高科技产品回归人性.第二版.北京:电子工业出版社,2006,115~188.

Horstmann Cay,Cornell Gary.Java 核心技术卷 2.第七版.北京:机械工业出版社,2007,74~121.Erich Gamma,Richard Helm, Ralph Johnson,etal.Design Patterns Elements of Reusable Object-Oriented Software. Pearson Education,2002,114~207

Shari Pfleeger,Joanne M. Atlee.Soft Engineering:

Theory and Practice. Third Edition.Pearson Education,2007,98~196

Vaswani Vikram.MySQL 完全手册.北京:电子工业出版社,2004,136~166.Alan Bowman.Developing activity duration specification limits for effective project control.European Journal of Operational Research,2006, 1191~1204.

相关推荐
ygl61503731 分钟前
Vue3+SpringBoot3+Sa-Token+Redis+mysql8通用权限系统
java·spring boot·vue
Code哈哈笑4 分钟前
【Java 学习】构造器、static静态变量、static静态方法、static构造器、
java·开发语言·学习
是老余5 分钟前
Java三大特性:封装、继承、多态【详解】
java·开发语言
鸽鸽程序猿6 分钟前
【JavaEE】Maven的介绍及配置
java·java-ee·maven
小馒头学python7 分钟前
【Python爬虫五十个小案例】爬取豆瓣电影Top250
开发语言·爬虫·python
尘浮生1 小时前
Java项目实战II基于微信小程序的南宁周边乡村游平台(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·微信小程序·小程序·maven
wangjing_05223 小时前
C语言练习.if.else语句.strstr
c语言·开发语言
Tony_long74833 小时前
Python学习——字符串操作方法
开发语言·c#
SoraLuna4 小时前
「Mac玩转仓颉内测版26」基础篇6 - 字符类型详解
开发语言·算法·macos·cangjie
出逃日志4 小时前
JS的DOM操作和事件监听综合练习 (具备三种功能的轮播图案例)
开发语言·前端·javascript