电梯模拟调度程序
经过将近两个星期的结对开发,这个程序将要告一段落了,下面说说这个程序的整体思路与实现:
1、设计思路:
2014年3月12日 20:00--22:00 赵天&&李金吉 讨论设计思路与界面设计
2014年3月13日 20:00--22:00 赵天&&李金吉 初步代码编写——实现电梯类
2014年3月14日--2014年3月18日 赵天&&李金吉 核心代码——调度算法的实现
2014年3月19日 20:00--22:00 赵天&&李金吉 美化界面与代码优化
2014年3月20日 20:00--22:00 赵天&&李金吉 测试程序整体性 首先考虑到要实现电梯调度,主要就是实现调度。
要实现电梯调度,首先要有一个电梯类,里面包括常量:
电梯有运行的方法:向上运行,向下运行,到达指定楼层停止,开门,关门;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
static public class information //静态数据 { public enum state { Run, Ready }; //状态:运行,准备 public enum direction { Up, Down, Stay }; //运行方向 } ... ... public bool Running = true ; //电梯运行状况 public int Count = 0; //此电梯剩下的请求数 public information.state dtstate = information.state.Ready; //电梯运动状态 public information.direction dtdirection = information.direction.Stay; //电梯运动的方向 public information.direction dtnextdir = information.direction.Stay; //电梯被请求的下一个运动方向 public int floor_now = 0; //电梯当前楼层数 public int [] out_request = new int [21]; //内部请求 |
然后就是run();函数了
如果要让4部电梯同时运行,首先要建4个线程,将4部电梯的run()都加入到其中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public elevator_work[] elevatorProcess = new elevator_work[4]; public Form1() { InitializeComponent(); elevatorProcess[0] = new elevator_work(); elevatorProcess[1] = new elevator_work(); elevatorProcess[2] = new elevator_work(); elevatorProcess[3]= new elevator_work(); Thread t1 = new Thread( new ParameterizedThreadStart(elevatorProcess[0].run)); Thread t2 = new Thread( new ParameterizedThreadStart(elevatorProcess[1].run)); Thread t3 = new Thread( new ParameterizedThreadStart(elevatorProcess[2].run)); Thread t4 = new Thread( new ParameterizedThreadStart(elevatorProcess[3].run)); } |
run():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
public void run(object t) { while (ele_con.Running) { int i = 0; if (ele_con.Count != 0) { ele_con.dtstate = information.state.Run; if (ele_con.dtdirection == information.direction.Down) { for (i = ele_con.floor_now; i >= 0; i--) { if (ele_con.out_request[i] == 1) { break ; } } if (i == -1) { return ; //err; } for (; ele_con.floor_now > i; ) { //电梯下行 ele_con.floor_now--; if (ele_con.out_request[ele_con.floor_now] == 1) { Thread.Sleep(3000); ele_con.out_request[ele_con.floor_now] = 0; } } } else if (ele_con.dtdirection == information.direction.Up) { for (i = ele_con.floor_now; i <= 20; i++) { if (ele_con.out_request[i] == 1) { break ; } } if (i == 20) { return ; //err; } for (; ele_con.floor_now < i; ) { //电梯上行 ele_con.floor_now++; if (ele_con.out_request[ele_con.floor_now] == 1) { Thread.Sleep(3000); ele_con.out_request[ele_con.floor_now] = 0; } } } } ele_con.dtstate = information.state.Ready; } //死循环 do { Thread.Sleep(3000); } while (!ele_con.Running); run(t); } } |
2、调度算法:
将外部的请求也就是每层的上行下行两个按钮,一个42个传到某一部电梯中去。
思路:扫描记录上行请求的数组,如果有请求判断是哪一层楼,然后寻找一部最适合的电梯将请求赋给内部,然后外部请求撤销。
然后是扫描下行请求的数组,方法同上。
怎样寻找这部最适合的电梯呢:首先电梯的运行方向,位置与请求的楼层及请求的方向之间有16中关系,其中上行请求8中下行请求8中。以上行请求来说,如果电梯在请求楼层之下,且运行方向向上,则满足基本条件,如果电梯没有运行,处于ready状态也满足基本条件,如果电梯运行方向向下或者在请求楼层之上都不满足条件。然后判断满足条件的电梯所在楼层与请求楼层之差,差值最小者就是最适合的电梯。下行请求类似。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
//这段代码有问题,还需改进 public void diaodu() { int i,up_re=0,down_re=0; int [] a = new int [4]; int [] b = new int [4]; for (i=0;i<21;i++) { up_re = i; if (outOrder.upgoing[i]==1) { outOrder.upgoing[i] = 0; break ; } } for (i = 0; i < 21; i++) { down_re = i; if (outOrder.downgoing[i] == 1) { outOrder.downgoing[i] = 0; break ; } } for (i = 0; i < 4; i++) { a[i] = up_re - elevatorProcess[i].ele_con.floor_now; } for (i = 0; i < 4; i++) { b[i] = down_re - elevatorProcess[i].ele_con.floor_now; } int minsubup=a[0]; int whicheleup=0; for (i = 1; i < 4; i++) { if (a[i]<minsubup&&a[i]>=0) { minsubup=a[i]; whicheleup = i; } } for (i = 0; i < 4; i++) { if (elevatorProcess[whicheleup].ele_con.dtstate == information.state.Ready || elevatorProcess[whicheleup].ele_con.dtdirection == information.direction.Up) { if (elevatorProcess[whicheleup].ele_con.dtstate == information.state.Ready) { elevatorProcess[whicheleup].ele_con.dtstate = information.state.Run; elevatorProcess[whicheleup].ele_con.dtdirection=information.direction.Up; elevatorProcess[whicheleup].ele_con.out_request[up_re]=1; break ; } elevatorProcess[whicheleup].ele_con.out_request[up_re] = 1; } } } |
3、界面设计: