小程序的按工作输入,延隔时间功能在12月8日就完成,后来想完成每日的资源统计功能,但一直没有idea。现在先把代码放上来啦。
数据输入方式:
在bin文件目录下一个叫“WorkTable.txt”中输入
格式为:
工作序号;工作名称;工作持续时间;前续工作的序号(用“,”隔开,即使只有一项也加上“,”);延隔时间;占用资源
运行效果:
在bin文件目录下一个叫“WorkTable.txt”中输入:
1;A;10;0,;0;12
2;B;10;1,;0;23
3;C;20;1,;0;44
4;D;30;1,;0;66
5;E;20;2,;0;7
6;F;20;3,;0;4
7;G;30;4,;0;56
8;H;30;5,;0;12
9;I;50;7,;0;33
9;I;50;6,;15;55
10;J;10;8,9,;0;23
8;H;30;6,;10;12
运行结果(控制台输出)
工作编号 |
工作名称 |
最早开始时间 |
最晚开始时间 |
持续时间 |
1 |
A |
0 |
0 |
10 |
2 |
B |
10 |
60 |
10 |
3 |
C |
10 |
15 |
20 |
4 |
D |
10 |
10 |
30 |
5 |
E |
20 |
70 |
20 |
6 |
F |
30 |
35 |
20 |
7 |
G |
40 |
40 |
30 |
8 |
H |
60 |
90 |
30 |
对象结构:(成员变量皆为private,而由相应的属性进行操作)
Program.cs:含有main方法,读取用户输入,调用处理,输出
Vertex.cs:顶点类,储存工作信息。
class Vertex
{
//顶点的结构变量
private Hashtable _preVerIdSet;//用HashTable结构记录前工作,key为工作的id,value为延隔时间
private ArrayList _nextVerIdArr;
//顶点的信息变量
private int _verId;
private string _workName;
private int _esTime;
private int _lfTime;
private int _duration;
private int _resource;
private int _freeF;
private int _totalF;
}
Network:网络图类,定义图相关的基本操作
class Network
{
private Hashtable _vertexSet;
private ArrayList _dailyResourceArr;
public Network()
public Vertex GetVertex(object vertexId)
public int[] CountInDegree(Network network)
public bool IsExistVertex(Vertex v)
public void AddVertex(Vertex v)
public void DeleteVertex(Vertex v)
}
NetworkOperator:定义对网络图的复杂操作,包括拓扑排序,时间计算等
class NetworkOperator
{
//初始化网络,建立网络图的储存结构
public Network InitializeNetwork(ArrayList workList,int totalWork)
//给网络图的所有顶点的最早时间赋值,并找出关键路径
public Stack CalculateVerEarTime(Network network)
//给网络图的所有顶点,边的最晚时间赋值
public void CalculateVerLatTime(Network network)
//给网络图的所有边的时间差赋值
public void CalculateTimeDiff(Network network)
//显示各工作相关信息
public void GetResult(Network network)
}
完整的代码:
Program.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.IO;
5 using System.Collections;
6
7 namespace NetworkCalculater
8 {
9 class Program
10 {
11 static void Main(string[] args)
12 {
13 //从文件中读取项目信息,储存到workList(ArrayList)中
14 ArrayList workList = new ArrayList();
15 FileStream fs = new FileStream("WorkTable.txt", FileMode.Open);
16 int totalWork = 0;
17 StreamReader sr = new StreamReader(fs);
18 string line;
19 string[] workInfo = new string[5];
20 while ((line = sr.ReadLine()) != null)
21 {
22 workInfo = line.Split(';');
23 int id = Int32.Parse(workInfo[0]);
24 string name = workInfo[1];
25 int time = Int32.Parse(workInfo[2]);
26 ArrayList preWorkList = new ArrayList();
27 string[] preWork = workInfo[3].Split(',');
28 for (int i = 0; i < (preWork.Length - 1); i++)
29 {
30 preWorkList.Add(Int32.Parse(preWork[i]));
31 }
32 int interval = Int32.Parse(workInfo[4]);
33 int resource = Int32.Parse(workInfo[5]);
34 ArrayList work = new ArrayList();
35 work.Add(id);
36 work.Add(name);
37 work.Add(time);
38 work.Add(preWorkList);
39 work.Add(interval);
40 work.Add(resource);
41 workList.Add(work);
42 totalWork++;
43 if (totalWork > id)
44 totalWork--;
45 }
46
47 //调用网络的各种类,对网络进行相关操作
48 NetworkOperator netOpe = new NetworkOperator();
49 Network network = netOpe.InitializeNetwork(workList,totalWork);
50 netOpe.CalculateVerLatTime(network);
51 netOpe.CalculateTimeDiff(network);
52
53 //把结果输出到txt文件中
54 netOpe.GetResult(network);
55 }
56 }
57 }
Vertex.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Collections;
5
6 namespace NetworkCalculater
7 {
8 /// <summary>
9 /// 节点类 储存工作相关的信息
10 /// </summary>
11 class Vertex
12 {
13 //顶点的结构变量
14 private Hashtable _preVerIdSet;//用HashTable结构记录前工作,key为工作的id,value为延隔时间
15 private ArrayList _nextVerIdArr;
16
17 //顶点的信息变量
18 private int _verId;
19 private string _workName;
20 private int _esTime;
21 private int _lfTime;
22 private int _duration;
23 private int _resource;
24 private int _freeF;
25 private int _totalF;
26
27 public Vertex()
28 {
29 _preVerIdSet = new Hashtable();
30 _nextVerIdArr = new ArrayList();
31 _esTime = 0;
32 _lfTime = Int32.MaxValue;
33 _duration = 0;
34 _totalF = Int32.MaxValue;
35 _freeF = Int32.MaxValue;
36 _resource = 0;
37 }
38
39 public Vertex(int i)
40 : this()
41 {
42 _verId = i;
43 }
44
45 //顶点的结构属性
46 public Hashtable PreVerIdSet
47 {
Network.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Collections;
5
6 namespace NetworkCalculater
7 {
8 /// <summary>
9 /// 定义网络图相关的基本操作
10 /// 单代号网络的形式储存数据,节点vertex为工作
11 /// </summary>
12 class Network
13 {
14 private Hashtable _vertexSet;
15 private ArrayList _dailyResourceArr;
16
17 public Network()
18 {
19 _vertexSet = new Hashtable();
20 }
21
22 public Hashtable VertexSet
23 {
24 get
25 {
26 return _vertexSet;
27 }
28 }
29
30 public ArrayList DailyResourceArr
31 {
32 get
33 {
34 return _dailyResourceArr;
35 }
36 set
37 {
38 _dailyResourceArr = value;
39 }
40 }
41
42 public Vertex GetVertex(object vertexId)
43 {
44 int verId = (int)vertexId;
45 if (_vertexSet.ContainsKey(verId))
46 return (Vertex)_vertexSet[verId];
47 return null;
48 }
49
50 public int[] CountInDegree(Network network)
51 {
52 int[] inDegreeCount = new int[(_vertexSet.Count - 2)];
53 for (int i = 0; i < inDegreeCount.Length;i++ )
54 {
55 Vertex v = this.GetVertex(i + 1);
56 inDegreeCount[i] = v.PreVerIdSet.Count;
57 }
58 return inDegreeCount;
59 }
60
61 public bool IsExistVertex(Vertex v)
62 {
63 return _vertexSet.ContainsValue(v);
64 }
65
66 public void AddVertex(Vertex v)
67 {
68 this._vertexSet.Add(v.VerId,v);
69 }
70
71 public void DeleteVertex(Vertex v)
72 {
73 this._vertexSet.Remove(v.VerId);
74 v = null;
75 }
76 }
77 }
NetworkOperator.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Collections;
5
6 namespace NetworkCalculater
7 {
8 /// <summary>
9 /// 调用Network中的基本操作,完成复杂的任务,如初始化,计算时差
10 /// </summary>
11 class NetworkOperator
12 {
13 public NetworkOperator()
14 {
15 }
16
17 //初始化网络,建立网络图的储存结构
18 public Network InitializeNetwork(ArrayList workList,int totalWork)
19 {
20 //初始化network
21 Network network = new Network();
22
23 //把所有的顶点加入网络
24 for (int i = -1; i <= totalWork; i++)
25 {
26 Vertex v = new Vertex(i);
27 network.AddVertex(v);
28 }
29
30 //设置首尾结点
31 Vertex begin = network.GetVertex(0);
32 begin.WorkName = "开始";
33 begin.LFTime = 0;
34 begin.TotalDiff = 0;
35 begin.FreeDiff = 0;
36 begin.PreVerIdSet = null;
37 Vertex end = network.GetVertex(-1);
38 end.WorkName = "结束";
39 end.TotalDiff = 0;
40 end.FreeDiff = 0;
41
42 //加入顶点的信息并联系起各顶点
43 foreach (ArrayList w in workList)
44 {
45 Vertex v = network.GetVertex(((int)w[0]));
46 v.VerId = (int)w[0];
47 v.WorkName = (string)w[1];
48 v.Duration = (int)w[2];
49 v.Resource = (int)w[5];
50 foreach (int preVerId in (ArrayList)w[3])
51 {
52 v.PreVerIdSet.Add(preVerId, w[4]);
53 Vertex preVer = network.GetVertex(preVerId);
54 preVer.NextVerIdArr.Add(v.VerId);
55 }
56 }
57 //处理尾结点
58 foreach (Vertex v in network.VertexSet.Values)
59 {
60 if (v.NextVerIdArr.Count == 0)
61 {
62 v.NextVerIdArr.Add(-1);
63 }
64 }
65 return network;
66 }
67
68 //给网络图的所有顶点的最早时间赋值,并找出关键路径
69 public Stack CalculateVerEarTime(Network network)
70 {
71 int[] vertexInDegree = network.CountInDegree(network);
72 Stack topOrder = new Stack();
73 Stack zeroInDegree = new Stack();
74 zeroInDegree.Push(network.GetVertex(1));
75 while (zeroInDegree.Count != 0)
76 {
77 Vertex v = (Vertex)zeroInDegree.Pop();
78 topOrder.Push(v);
79 for (int i=0; i<v.NextVerIdArr.Count; i++)
80 {
81 Vertex next = network.GetVertex(v.NextVerIdArr[i]);
82 if (next.VerId < 0)
83 continue;
84 if (--vertexInDegree[next.VerId - 1] == 0)
85 zeroInDegree.Push(next);
86 int startTime = v.ESTime + v.Duration + (int)next.PreVerIdSet[v.VerId];
87 if (startTime > next.ESTime)
88 next.ESTime = startTime;
89 }
90 }
91 Vertex tail = (Vertex)topOrder.Peek();
92 Vertex end = (Vertex)network.GetVertex(-1);
93 end.PreVerIdSet.Add(tail.VerId, (object)0);
94 end.NextVerIdArr = null;
95 end.ESTime = tail.ESTime + tail.Duration;
96 end.LFTime = tail.ESTime + tail.Duration;
97 return topOrder;
98 }
99
100 //给网络图的所有顶点,边的最晚时间赋值
101 public void CalculateVerLatTime(Network network)
102 {
103 Stack topOrder = this.CalculateVerEarTime(network);
104 Vertex tail = (Vertex)topOrder.Peek();
105 tail.LFTime = tail.ESTime + tail.Duration;
106 while (topOrder.Count != 0)
107 {
108 Vertex v = (Vertex)topOrder.Pop();
109 foreach (object preVerId in v.PreVerIdSet.Keys)
110 {
111 Vertex head = network.GetVertex(preVerId);
112 int finishTime = v.LFTime - v.Duration - (int)v.PreVerIdSet[head.VerId];
113 if (finishTime < head.LFTime)
114 head.LFTime = finishTime;
115 }
116 }
117 }
118
119 //给网络图的所有边的时间差赋值
120 public void CalculateTimeDiff(Network network)
121 {
122 for (int j = 1; j <= network.VertexSet.Values.Count - 2;j++ )
123 {
124 Vertex v = (Vertex)network.GetVertex(j);
125 foreach (object preVerId in v.PreVerIdSet.Keys)
126 {
127 Vertex preVer = network.GetVertex(preVerId);
128 if (v.FreeDiff > v.ESTime - preVer.EFTime)
129 v.FreeDiff = v.ESTime - preVer.EFTime;
130 }
131 }
132 }
133
134 //显示各工作相关信息
135 public void GetResult(Network network)
136 {
137 Console.WriteLine("工作编号\t工作名称\t最早开始时间\t最晚开始时间\t持续时间");
138 for (int i = 1; i <= network.VertexSet.Values.Count - 2;i++ )
139 {
140 Vertex v = network.GetVertex(i);
141 Console.WriteLine(v.VerId + "\t" + v.WorkName + "\t" + v.ESTime + "\t" + v.LSTime + "\t" + v.Duration);
142 }
143 Console.WriteLine("最短的工期为:" + ((Vertex) network.GetVertex(-1)).ESTime);
144 }
145 }
146 }
147
148