♻️ 资源
大小: 903KB
➡️ 资源下载: https://download.csdn.net/download/s1t16/87425385
利用工程活动图 AOE 网设计一个算法
题目
★★ 已知假想的工程活动图 AOE 网,试设计一个算法,要求:
判断工程是否可行;
- 求出工程中每个活动的最早开始时间 e(i),最迟开始时间 l(i)和全工程可以完成的最早时间;
- 确定工程中关键路径和可使整个工程的工期缩短的关键活动。
说明: 可以给出一个假想的工程活动图 AOE 网,如下图所示(仅为示例),也可以给出工程的活动情况,画出 AOE 网。

软件功能

本软件有如下功能:
用户可以点击"开始创建"自行建立 AOE 工程网络,鼠标点击创建面板生成一个事件,依次有序点击两个事件可以创建活动,创建的活动上会显示活动的权重。AOE 活动网络建成之后,点击"执行计算",程序自动完成关键路径的计算,若构建的网络不满足条件,比如有多个源点、汇点、环路,或者事件已经创建,程序均会进行相应报错。当完成关键路径的计算后,会在创建面板以红色加粗显示关键路径,并且在左侧活动信息面板详细显示各个活动的信息,关键活动路径同样给予突出显示,在程序窗口右下角,会给出整个工程最早的完成时间,即关键路径活动时间之和。用户可以重复创建和计算关键路径的过程。
用到的主要控件是 panel 面板和 tableLayoutPanel 面板,用于在程序内 GroupBox 划分空间的基础上划分面板,事件的生成是生成一个按钮,连线的生成通过调用System.Drawing.Drawing2D 的画图功能,活动信息的展现是增添表格。关键路径的计算采用的是课本上的计算方法,在此之间需要先进行 AOV 的拓扑排序,确定没有环路方可继续程序运行。
设计思想
本软件仍然是利用 C#的.Net Framework 来写的图形界面。主要目的是能够生成或者创建一个 AOE 活动网络,并对这个网络进行求解关键路径。在 C++ 里用指针表示的邻接表很容易实现活动网络图结构的存储,然而 C#虽然构建图形界面比较方便,但是由于没有指针这一特性,很多方面会受到限制,只能用静态的数组来模拟指针构建邻接链表。主要采用三个类来表示 AOE 活动网络:活动类、事件类和 AOE 网络结构类,活动类包括活动的始终,活动的权重,活动的最早和最晚开始时间以及活动的起点终点坐标;事件类包含以该事件为起点的所有的活动的变长数组,相当于邻接表的某一行;AOE 网络类中包含各种求解过程中要用到的方法。难点在于打破 C++ 的指针思维方式,以变长数组构建邻接表。
主要算法思想:
求活动最早开始时间:活动出发顶点(时间)的最早开始时间
求活动的最晚开始时间:从要求最晚截止时间开始,反向推导,最晚工程技术时间依次
减去路径上各活动的时间
求关键路径和关键活:根据各顶点的 ve 和 vl 值,求每个活动的最早开始时间 e(s)和最迟开始时间 l(s),若某条弧(活动)满足条件 e(s)=l(s),则该活动为关键活动,关键活动连接起来就是关键路径。值得注意的是:关键路径可能有多条。
容错性考虑:
判断工程中是否创建事件和活动遍历所有事件节点,检查以该节点开始的活动的可变长数组是否是空的,相当于检查邻接表是否为空,若是空的,则工程中不存在活动,需要重新创建。

检查工程中是否有多个源点:
遍历所有事件节点,统计所有入度为 0 的节点的数量总和,如果数量大于 1,则说明不止一个源点,工程不符合条件,不能求解。

检查工程中是否有多个汇点:
遍历所有事件节点,统计以该事件节点开始的活动的可变长数组为空的事件个数,如果统计出的个数大于 1,则说明有多个事件为截止事件,工程中存在多个汇点,无法求解关键活动。

检查工程中是否有环路:
AOE 活动网络中是不存在环路的,为检查活动网络中是否有环路,需要对所有事件节点进行拓扑排序,如果排序后的离散节点数与之前的节点数相同,则 AOE 活动网络中不存在环路,否则,需要重新创建工程。

逻辑结构与物理结构
程序主要构成:


Activity 类: public class Activity
{ public int start;
// 活动起始事件序号
public int end;
// 活动结束事件序号
public int weight;
// 活动持续时间,权重
public int e;
// 活动最早开始时间
public int l;
// 活动最迟开始时间
public bool critical;
// 是否为关键活动
public Point p_start = new Point();
// 活动起点坐标(画图用)
public Point p_end = new Point(); // 活动终点坐标(画图用)
}

Event 类:
public class Event
{
public bool critical;
// 是否为关键路径上的事件
public List<Activity> next = new List<Activity>(); // 以该事件为开始的
活动
public int ins;
// 入度
public int e;
// 事件最早发生时间
public int l;
// 事件最迟发生时间
}

NetWork 类:
public class Network
{
Graphics g;
public List<Event> net = new List<Event>();
// AOE网邻接表
public int start;
// 工程起始事件序号
public int end;
// 工程结束事件序号
List<int> topology = new List<int>();
// 拓扑排序结果
}
主要的数据结构是 List形式的动态变长数组,该数组在计算机中占据连续的内存,属于物理结构。
程序计算的主要方法(函数)
private void button1_Click(object sender, EventArgs e)
//开始创建
private void panel1_MouseClick(object sender, MouseEventArgs e)
//画AOE网络
private void eventClick(object sender, MouseEventArgs e)
//点击事件
private void button2_Click(object sender, EventArgs e)
//执行计算
protected override void OnPaint(PaintEventArgs e)
//重新设置控件的形状,绘制圆形
按钮
public String Is_Able_Continue()
// 求解工程是否可行,可继续
public void eventsTime()
// 求各事件的最早和最迟开始时间
public void activitiesTime(AOE main)
// 求各活动的最早和最迟开始时间
开发平台
CPU:AMD Ryzen 7 4800H with Radeon Graphics 2.90GHz
系统类型:Windows10 64 位,基于 X64
开发环境:Visual Studio 2019 professional
Visual C#
.Net Framework
调用的系统命名空间:
using System;using System.Collections.Generic;using System.Drawing;using System.Drawing.Drawing2D;using System.Windows.Forms;
系统的运行结果分析说明
利用 Visual Studio C# .Net Framework 集成开发环境,先设计好整体页面,将各组件布置到位,主要部件为 panel 控件和 tabelLayoutPanel 控件,主要调用的绘图函数为System.Drawing.Drawing2D 下的 DrawLine(pen, start, end)。题目要求算出 AOE 工程网络中的关键路径。本软件已达到基本要求,并且可以自己灵活创建 AOE 网络,网络中标出活动标号,和活动权重,当计算完毕后,会对关键路径加粗加红显示,关键活动的信息也会加红显示。经过验证,正确性良好,稳定性良好,已经充分考虑各种错误情况并且给予相应的处理,容错能力良好。并且给予相应的提示,比较人性化。
操作说明
打开可执行程序

程序初始界面:

点击"开始创建"按钮,开始创建工程

创建活动
鼠标在面板上点击,生成事件

鼠标依次按照顺序点击活动上的两个事件,开始创建活动



创建完活动,点击"执行计算"

计算前

计算后:关键路径加粗加红显示

活动信息:关键活动加红突出显示

显示工程最早完成时间:

错误提示





部分 实践总结
所做的工作
复习数据结构课程中所学的知识点,重点复习哈夫曼树构造算法、关键活动计算方法以及树和图的存储形式
- 学习 C#基本语法
- 学习 C# winform 窗体基本构建,各个控件的特性,使用方法
- 设计程序用到的数据结构及选择相应合适的.Net Framework 窗体控件
- 构建窗体,完善各个部件的具体功能
- 通过参考书籍和网络资料解决问题,不断改进,提高容错性和用户体验
- 总结复盘,回顾反思
总结与收获
《数据结构》课程设计是对《数据结构》课程的加强和巩固,通过实践做图新界面软件的形式强化对数据结构的理解以及加强对各种开发环境的掌握应用,通过完成《数据结构》课程设计,个人受益匪浅。着手之初,不知道该从何下手,数据结构知识还好,学期内已经有大量练习了,对堆、栈、树、图等已经有了比较清晰的理解,难点在于图形界面的制作,这点在课程中是没有接触到的。所以只好先查阅资料,经过检索,发现图形化界面可以用 Qt、easyX、MFC、C#等来做,这些与比较熟悉的 C++ 比较接近,有些是在 C++ 上的直接扩展,其他的包括 Java、Python 等都有很成熟的库可以调用生成图形界面,但是对这些语言还不是很熟,所以果断放弃。后面经过大致的浏览,发现 C# .Net Framework 窗体程序构建比较容易操作,而且目前 C#在很多开发的地方均有应用,所以想趁着这个暑假完成课设的机会把 C#及其开发知识顺便给学了。首先是通过官网和书籍进行基本的 C#语法学习,然后在官网上进行.Net Framework 窗体组件的学习,对 C#工具箱里的大部分组件都已经了解了一二。
以上准备工作做完,应该是可以开动做课设了,但发现没那么简单,因为一些数据结构在 C++ 里面可以很简单表示出来,但在 C#里面就不太好表示,一方面有自己不太熟的原因,另一方面,C#的许多机制与 C++ 不相同,比如 C++ 里的指针 C#就没有,树和图在 C++ 里用指针很容易表示,C#语法却比较难表示。最后通过不断查阅资料完善知识框架,可以通过.Net 里面的一些已有组件,比如 treeView 和 DataGridView 等, 这些组件里面已经内嵌了树结构或者数组结构,不用为没法用指针表示而烦恼,不过深入学习这些组件的框架和使用方式也是花费了不少时间和精力。在学习 C#基础的时候,知道了 C#的委托机制和 C++ 的指针类似,也可以利用静态数组来模拟指针,C#的委托机制是高级用法,具体实现起来比较麻烦,相对对静态数组来模拟链表之类的操作可能比较容易上手,所以在 AOE 网络中用 List变长数组来表示邻接链表。
做完课程设计,收获很大,感觉到了平时做的练习题与这种实际的软件还是有比较大的差距,但是课程里学的数据结构知识都是这些程序的内在骨架和灵魂,把程序比作前端的话,数据结构和算法知识就是后端,支撑着程序运行的逻辑。难点在于对开发环境和知识的掌握和理解,要求短时间内掌握窗体设计方法并融合学习过的数据结构知识。整体做下来发现其实课程设计不是很难,当熟悉了各组件的应用方式和与数据结构的结合,剩下的就是实现一些简单的逻辑了,C#与 C++ 大部分相似,类和方法的概念都差不多,但没有指针表示,不同的语言和环境之间得做出取舍和相应的改变。其实无论是采用什么开发环境,万变不离其宗,数据结构和算法知识是不会改变的,只要掌握根本就好。
参考文献
严蔚敏 吴伟民.数据结构(C 语言版).北京:清华大学出版社,2007Matthew MacDonald.WPF编程宝典------C# 2010版.北京:清华大学出版社,2011
Daniel M.Solis.图灵程序设计丛书:C#图解教程(第4版).北京:人民邮电出版社,2012
菜鸟教程.C#教程.
语言中文网.C# WinForm 界面设计教程(C# Windows 窗体应用程序).
Microsoft 官网.使用 .NET Framework 开发自定义 Windows 窗体控件.
孙学琛,李新洁.哈夫曼树的图形化算法设计[J].山东理工大学学报(自然科学版),2008,22(06):108-110.
简书.关键路径算法演示(AOE 网).