结对编程作业---电梯调度程序

  这次的作业和以往不同,按照老师的要求,我们要进行结对编程的练习。所谓结对编程相信各位都不会陌生,这里不在赘述。

  首先介绍下我的小伙伴,很幸运的是我的队友也是我的室友---樊西江,这为我们合作提供了很大的便利。

  其次说下项目的描述与实现的办法,问题如下

  

电梯调度

      现有一新建办公大厦,共有21层,共有四部电梯,所有电梯基本参数如下表所示:

电梯编号

可服务楼层

最大乘客数量

 

最大载重量

 1

全部楼层

10

800 kg

2

单层

10

800 kg

3

双层

20

1600 kg

4

全部楼层

20

2000 kg

      其使用规定如下:

      1、楼层号为0~20,其中0号为地下一层;

      2、有楼层限制的电梯不在响应楼层停靠,如单双层;

      3、所有电梯采用统一按钮控制

  对于这个项目,我俩决定采用java语言编写,原因如下:我们对C/C++的掌握程度不够精深,和现学现卖的JAVA差不了太多,而且我们想要做出一个拥有图形化界面的程序,仅靠我们所有的C以及C++是无法满足的,时间所限现学其他的语言变得很困难。

  接下来简单介绍下软件开发中遇到的问题以及整体思路实现。

  有了C++面向对象的基础,使我们在面对java语言的面向对象用的更加得心应手,当然,问题也是大大的有。首先是类的设计,类的属性和方法随着需求一点点变化越加越多,代码也一度出过问题,我俩经过多次分析才最终化繁为简,将代码优化到可以容易看懂的地步。面对这个电梯调度问题,电梯类必不可少,其次是控制类,以及主函数,当然还有我们最想实现的,图形化界面。

  首先说下界面的布置,这里我们将界面布置的和现实中的电梯类似,一个输入框用来键入人所在楼层,以及用来获取目标楼层的输入框,两个按钮,分别向上和向下,四个显示框用来输出电梯的信息。整体布局如下:

  

   实现代码如下:

 1 // 定义图形化界面引用
 2     private Frame f;
 3     private Button butUp;//上升按钮
 4     private Button butDown;//下降按钮
 5     private Label lab1;//当前楼层说明
 6     private Label lab2;//目的楼层说明
 7     private TextField personFloor;//人所在楼层
 8     private TextField personToFloor; //人的目标楼层
 9     private TextArea screen1;//显示信息
10     private TextArea screen2;//显示信息
11     private TextArea screen3;//显示信息
12     private TextArea screen4;//显示信息
界面声明部分
 1 public void init()//图形界面初始化
 2     {
 3         f = new Frame("Elevator dispatching");
 4         f.setSize(400,400);
 5         f.setLayout(new FlowLayout());
 6         f.setResizable(false);//窗体固定
 7         f.setLocationRelativeTo(null);//窗体居中
 8         
 9         lab1 = new Label("当前楼层");
10         lab2 = new Label("目的楼层");
11         
12         personFloor = new TextField("",10);
13         personToFloor = new TextField("",10);
14         
15         butUp = new Button("↑");
16         butDown = new Button("↓");
17 
18         
19         screen1 = new TextArea("显示屏",5,10,TextArea.SCROLLBARS_NONE);
20         screen2 = new TextArea("显示屏",5,10,TextArea.SCROLLBARS_NONE);
21         screen3 = new TextArea("显示屏",5,10,TextArea.SCROLLBARS_NONE);
22         screen4 = new TextArea("显示屏",5,10,TextArea.SCROLLBARS_NONE);
23         
24         screen1.setEditable(false);
25         screen2.setEditable(false);
26         screen3.setEditable(false);
27         screen4.setEditable(false);
28         
29         f.add(lab1);
30         f.add(personFloor);
31         f.add(butUp);
32         f.add(butDown);
33         f.add(lab2);
34         f.add(personToFloor);
35         f.add(screen1);
36         f.add(screen2);
37         f.add(screen3);
38         f.add(screen4);
39         
40         myEvent();//添加事件
41         
42         f.setVisible(true);
43     }
图形界面初始化

  其次是类的设计与实现

  1、Elevator类

    电梯类用以描述电梯的属性以及方法,用以实体化电梯以供使用。

    电梯的主要属性:编号、种类(单双层)、所在楼层、目标楼层等等。

    电梯类的方法:

      构造函数对属性值进行初始化

      void add()方法,根据指令将人所在的楼层和人要去的楼层加入Elevator的目标队列中。其中Elevator类的toFloors[]为数组,用来存储电梯的目的楼层,start和end为其指针。判断逻辑如下:如当前目标楼层数目为1或者0时,无需判断,直接将二者加入电梯目标队列中;否则,判断人和电梯的方向异同,若相同,则判断具体方向,最后判断人与电梯目标段的位置,在目标段之外(之上或之下)以及在目标段之内,根据判断将人所在的楼层和人要去的楼层加入Evelator类toFloors[]中的相应位置,并移动指针end。如果电梯和人的方向不同,无需判断,直接将二者顺序加入Elevator类toFloors[]中即可;

      void run()方法,电梯动起来的方法,判断目标队列的元素数,如果start!=end 表明电梯仍需运行,这时根据目标队列的start楼层和电梯当前楼层,将电梯的运行状态改变,并将电梯的当前楼层++或者--,当电梯的当前楼层 == 电梯的start楼层时,输出提醒,将电梯运行状态置为0,并将start后移。

      int countDistance() 方法,后加入的方法,主要用来计算电梯相应按钮指令所需要的时间(这里用距离来表示),返回值为距离的具体值,首先判断特殊情况,即单层电梯响应双层按钮或双层电梯相应单层按钮的距离,无需判断,返回一个最大值(100)即可。否则的话根据具体情况判断,首先电梯的情况有三,目标楼层为空,电梯静止。目标楼层数为大于2,这时根据最后的情况判断距离,这种情况和目标楼层数为1时相同。判断距离的判断方法和电梯的run方法雷同,将情况分为可见的几种情况,逐步实现,这里刚开始为难了我俩好久。后来我们逐步分析,将情况分为了可以解决的小情况。

      void show()方法,展示函数,将电梯的信息输出,输出电梯的当前楼层和运行状态,直接将电梯类的属性值输出即可。

  1 class Elevator
  2 {
  3     private int id;//电梯编号
  4     private int maxLoadWeight;//最大载重
  5     private int loadWeight;//当前重量
  6     private int state;//0:全层 1:单层 2:双层
  7     private int floor; //电梯当前楼层
  8     private int runState;//电梯运行状态 0--不动       1--向上    -1--向下
  9     private int[] toFloors;//电梯目标楼层
 10     private int start,end;
 11     private String info;//电梯信息
 12     
 13     Elevator(int id, int maxLoadWeight, int state){
 14         this.id = id;
 15         this.maxLoadWeight = maxLoadWeight;
 16         this.loadWeight = 0;
 17         this.state = state;
 18         this.setFloor(1);
 19         this.setRunState(0);
 20         toFloors = new int[20];
 21         this.start = 0;
 22         this.end = 0;
 23     }
 24     
 25     public int countDistance(int personFloor, int runDirection)//判断电梯->人的距离
 26     {
 27         if(state ==1 && (personFloor%2)==0)
 28             return 100;
 29         if(state ==2 && (personFloor%2)==1)
 30             return 100;
 31         if(end == start)
 32             return Math.abs(personFloor - floor);
 33         else if(end-start ==1){//电梯目标值为1个
 34             if(toFloors[end-1] > floor){//电梯上升
 35                 if(1 == runDirection){//人上升    三种情况
 36                     if(personFloor < floor){
 37                         return (toFloors[end-1]-floor)*2+(floor-personFloor);
 38                     }else{
 39                         return personFloor-floor;
 40                     }
 41                 }else{//人下降  三种情况
 42                     if(personFloor>toFloors[end-1]){
 43                         return personFloor-floor;
 44                     }else if(personFloor < floor){
 45                         return (toFloors[end-1]-floor)*2+(floor-personFloor);
 46                     }else{
 47                         return (toFloors[end-1]-floor)+(personFloor-floor);
 48                     }
 49                 }
 50             }else{//电梯下降
 51                 if(1 == runDirection){//人上升
 52                     if(personFloor>floor){
 53                         return (floor-toFloors[end-1])*2+(personFloor-floor);        
 54                     }else if(personFloor < toFloors[end-1]){
 55                         return floor-personFloor;
 56                     }else{
 57                         return (floor-toFloors[end-1])+(personFloor-toFloors[end-1]);
 58                     }
 59                 }else{//人下降
 60                     if(personFloor>floor){
 61                         return (floor-toFloors[end-1])*2+(personFloor-floor);        
 62                     }else if(personFloor < toFloors[end-1]){
 63                         return floor-personFloor;
 64                     }
 65                 }
 66             }
 67         }else{//电梯目标值为两个以上
 68             if(toFloors[end-1] >toFloors[end-2]){//电梯最终状态为上升
 69                 if(1 == runDirection){//人上升    三种情况
 70                     if(personFloor < toFloors[end-2]){
 71                         return (toFloors[end-1]-toFloors[end-2])*2+(toFloors[end-2]-personFloor);
 72                     }else{
 73                         return personFloor-toFloors[end-2];
 74                     }
 75                 }else{//人下降  三种情况
 76                     if(personFloor>toFloors[end-1]){
 77                         return personFloor-toFloors[end-2];
 78                     }else if(personFloor < toFloors[end-2]){
 79                         return (toFloors[end-1]-toFloors[end-2])*2+(toFloors[end-2]-personFloor);
 80                     }else{
 81                         return (toFloors[end-1]-toFloors[end-2])+(personFloor-toFloors[end-2]);
 82                     }
 83                 }
 84             }else{//电梯最终状态为下降
 85                 if(1 == runDirection){//人上升
 86                     if(personFloor>toFloors[end-2]){
 87                         return (toFloors[end-2]-toFloors[end-1])*2+(personFloor-toFloors[end-2]);        
 88                     }else if(personFloor < toFloors[end-1]){
 89                         return toFloors[end-2]-personFloor;
 90                     }else{
 91                         return (toFloors[end-2]-toFloors[end-1])+(personFloor-toFloors[end-1]);
 92                     }
 93                 }else{//人下降
 94                     if(personFloor>toFloors[end-2]){
 95                         return (floor-toFloors[end-1])*2+(personFloor-toFloors[end-2]);        
 96                     }else if(personFloor < toFloors[end-1]){
 97                         return toFloors[end-2]-personFloor;
 98                     }
 99                 }
100             }
101         }
102         return -100;//防止出错判断        
103     }
104     
105     
106     public void add(int personFloor, int runDirection,int toFloor)
107     {
108         if (end - start > 0)//电梯目标楼层大于0个
109         {
110             if ((toFloors[end-1] - toFloors[end - 2])*runDirection > 0) {//人和电梯同方向
111                 if (1 == runDirection)//同向上
112                 {
113                     if (personFloor > toFloors[end - 1])//人所在楼层 高于 电梯去的最高楼层
114                     {
115                         toFloors[(end++) % 20] = personFloor;
116                         toFloors[(end++) % 20] = toFloor;
117                     }else {//人所在楼层 低于 电梯去的最高楼层
118                         toFloors[end] = toFloors[(end++)%20 -1];
119                         toFloors[end - 2] = personFloor;
120                         if (toFloor > toFloors[end - 1])//人要去楼层高于电梯所在楼层
121                             toFloors[(end++) % 20] = toFloor;
122                         else{    //人要去楼层低于电梯所在楼层
123                             toFloors[end] = toFloors[end - 1];
124                             toFloors[end - 1] = toFloor;
125                             end = (end++) % 20;
126                         }
127 
128                     }
129                 }
130                 else {//同向下
131                     if (personFloor < toFloors[end - 1])//人所在楼层 低于 电梯去的最高楼层
132                     {
133                         toFloors[(end++) % 20] = personFloor;
134                         toFloors[(end++) % 20] = toFloor;
135                     }
136                     else {//人所在楼层 高于 电梯去的最低楼层
137                         toFloors[end] = toFloors[end - 1];
138                         toFloors[end - 1] = personFloor;
139                         end = (end++)%20;
140                         if (toFloor < toFloors[end - 1])//人要去楼层低于电梯所在楼层
141                             toFloors[(end++) % 20] = toFloor;
142                         else {    //人要去楼层高于电梯所在楼层
143                             toFloors[end] = toFloors[end - 1];
144                             toFloors[end - 1] = toFloor;
145                             end = (end++) % 20;
146                         }
147                     }
148                 }
149                     
150             }
151             else {//反方向
152                 toFloors[(end++) % 20] = personFloor;
153                 toFloors[(end++) % 20] = toFloor;
154             }
155         }
156         else//电梯目标楼层数量为1或者0
157         {
158             toFloors[(end++) % 20] = personFloor;
159             toFloors[(end++) % 20] = toFloor;
160         }
161     }
162     
163     
164     public void run()throws Exception//电梯运行
165     {
166         if (start != end)//需要运行
167         {
168             if (floor < toFloors[start])//向上
169             {
170                 runState = 1;
171                 floor++;
172             }
173             else if (floor > toFloors[start])//向下
174             {
175                 runState = -1;
176                 floor--;
177             }
178             else//floor = toFloors[start] 到目的地
179             {
180                 System.out.println("电梯"+id+" 已到达到达目的地:"+floor);
181 
182                 runState = 0;
183                 start = (start+1)%20;
184             }
185         }
186     }
187 
188     public String show(){
189         info = id+"'s Elevator \non "+floor+"'s floor\nis ";
190         if(1 == runState)
191             return info+" ↑";
192         if(-1 == runState)
193             return info+" ↓";
194         return info+" -- ";
195             
196     }
197 
198     public int getRunState() {
199         return runState;
200     }
201 
202     public void setRunState(int runState) {
203         this.runState = runState;
204     }
205 
206     public int getFloor() {
207         return floor;
208     }
209 
210     public void setFloor(int floor) {
211         this.floor = floor;
212     }    
213 }
Elevator类

  2、Controller类

    控制器类,用以开启多线程,以及控制电梯的运行。

    控制器属性,电梯类的指针以及用以接收电梯类输出信息的字符串。

    控制器方法:

       不多说,开启多线成的两种方法,继承Thread和实现Runnable接口,无论哪种都需要覆盖的run方法。这个方法里调用电梯类的run方法后,用info接收电梯类的输出信息,以供主函数用来更新界面显示。

 1 class Controller implements Runnable
 2 {
 3     Elevator Elevator = null;
 4     String info = null;
 5     Controller(Elevator e)
 6     {
 7         this.Elevator = e;
 8     }
 9     
10     public String getInfo(){
11         return info;
12     }
13     public void run()//控制器执行,调度电梯
14     {    
15         while(true)//里面保持每个电梯的运行
16         {
17             try {
18                 Elevator.run();
19                 info = Elevator.show();
20             } catch (Exception e1) {
21                 // TODO 自动生成的 catch 块
22                 e1.printStackTrace();
23             }
24             try {
25                 Thread.sleep(3000);
26             } catch (InterruptedException e) {
27                 // TODO 自动生成的 catch 块
28                 e.printStackTrace();
29             }    
30         }
31     }    
32 }
Controller类

  3、主函数

    属性:界面控件,以及用来判断按钮的静态量 order

    方法:

      构造方法:执行界面的初始化、order的置零以及自定义的执行方法myRun();

      init() 图形界面初始化函数

      boolean isBetween20()用来判断输入数据的合法性所用到的小函数,当值不在0-20之间时返回false

      boolean isCorrect() 判断输入数据的合法性,例如向上时,人要去的楼层应该比人所在的楼层高,等等常识性问题的判断。

      int whoIsRun()  用来判断最优电梯方案,调用四个电梯的计算函数,计算距离,参数传入,封装成数组,找到最小距离后返回下标,利用返回值调用相应电梯做相应的调度。

      myEvent() 方法,用来为界面控件添加事件监听,当两个输入框输入非法字符时(非数字和删除键),控制台打印警告,不予录入。当两个按钮按下时,用isCorrect函数判断输入的合法性,如果合法,将order分别置为1或者-1,否则置零,视为此次输入无效。

 

  接下来说一下遇到的问题以及解决方案

    1、首先就是主函数的问题,由于主函数是静态的,无法访问非静态的变量和方法,所以我们采取了在主函数的构造函数中调用自己构建好的一个方法,主函数中创建这个自己的类即可实现。

    2、命令的传递问题,最初打算在按钮事件中直接调用电梯类的方法将目标楼层直接录入,后来发现以我们的水准无法实现,于是采用折中的办法,在主函数(myRun())d 循环中检察order的状态,并在按钮时间中更改order状态,以此来判断按钮以及调用电梯的方法,执行最优方案将目标楼层加入电梯的目标序列中。

    3、最优电梯方案,这个我们想了最久,也是最后实现的并且实现的不彻底,最优的方案应该是最令用户满意的方案,也就是说按了按钮以后电梯可以最快到达的方案。于是我们采用计算距离的方式,用距离最短的电梯去接人。

    4、由于采取了数组的方式存储电梯的目标序列,导致很难判断哪个楼层为上、哪个楼层为下,所以上多少人以及判断体重的功能我们还没彻底实现,由于时间关系我们只好写到这里,后续过程一定会实现它。

总结:

  首先感谢老师给的这次机会,让我对队友有了更深的理解,相信其他人应该也是如此。在这不短的时间里,两个人合作做成一件事情,虽然它不是多么难,多么的累,但仍然是一件让人感到满足感的事情。

  在这里简单评价下我的队友,虽然经验可能稍微缺少些,但是学习的精神很足,使用他所不擅长的语言他也没放弃过,一直为这个项目努力着并在其中扮演着重要的角色。代码的编写并没有按照时间轮转,而是根据我俩谁更想写哪里,我想写的我擅长写的我去写,他擅长写的他去写,期间我们的讨论对于解决问题发挥了很大作用。对于代码复审,在我编程期间他没有表现出一点的不耐,这令我非常佩服。我相信我写代码的过程比他听一篇没有意义的演讲更令人困倦,他的坚持令我汗颜,希望他不仅局限于这次结对编程,在以后的学习生活中还可以如同现在一般投入。

  最后说说我的感受,通过软件工程这门课,我们可以学习到很多课本上无法学习到的东西,软件的实际开发流程、软件开发团队的类型等等,这次的课程通过老师的讲解以及课下的作业练习,让我们的编程能力得以锻炼,通过解决遇到的问题,也使得我们在今后面对问题时有了可以战胜的信心,相信这对我们以后的发展是很有利的。这次的软件工程作业也令我对所学的知识运用的更加得心用手,再次让我明白,实践出真知,谢谢老师~

 

  附录:
    工作照:

 

 

    

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    程序运行图:

    

    

    

    源码:

      

  1 package cn.sau.homework;
  2 
  3 import java.awt.*;
  4 import java.awt.event.*;
  5 
  6 public class Main {
  7     // 定义图形化界面引用
  8     private Frame f;
  9     private Button butUp;//上升按钮
 10     private Button butDown;//下降按钮
 11     private Label lab1;//当前楼层说明
 12     private Label lab2;//目的楼层说明
 13     private TextField personFloor;//人所在楼层
 14     private TextField personToFloor; //人的目标楼层
 15     private TextArea screen1;//显示信息
 16     private TextArea screen2;//显示信息
 17     private TextArea screen3;//显示信息
 18     private TextArea screen4;//显示信息
 19     
 20     private static int order; //有无按钮提示  0:无  1:↑ -1:↓
 21 
 22     
 23     
 24     Main()
 25     {
 26         order = 0;
 27         init();    
 28         myRun();
 29     }
 30     
 31     public void init()//图形界面初始化
 32     {
 33         f = new Frame("Elevator dispatching");
 34         f.setSize(400,400);
 35         f.setLayout(new FlowLayout());
 36         f.setResizable(false);//窗体固定
 37         f.setLocationRelativeTo(null);//窗体居中
 38         
 39         lab1 = new Label("当前楼层");
 40         lab2 = new Label("目的楼层");
 41         
 42         personFloor = new TextField("",10);
 43         personToFloor = new TextField("",10);
 44         
 45         butUp = new Button("↑");
 46         butDown = new Button("↓");
 47 
 48         
 49         screen1 = new TextArea("显示屏",5,10,TextArea.SCROLLBARS_NONE);
 50         screen2 = new TextArea("显示屏",5,10,TextArea.SCROLLBARS_NONE);
 51         screen3 = new TextArea("显示屏",5,10,TextArea.SCROLLBARS_NONE);
 52         screen4 = new TextArea("显示屏",5,10,TextArea.SCROLLBARS_NONE);
 53         
 54         screen1.setEditable(false);
 55         screen2.setEditable(false);
 56         screen3.setEditable(false);
 57         screen4.setEditable(false);
 58         
 59         f.add(lab1);
 60         f.add(personFloor);
 61         f.add(butUp);
 62         f.add(butDown);
 63         f.add(lab2);
 64         f.add(personToFloor);
 65         f.add(screen1);
 66         f.add(screen2);
 67         f.add(screen3);
 68         f.add(screen4);
 69         
 70         myEvent();//添加事件
 71         
 72         f.setVisible(true);
 73     }
 74     
 75     public boolean isBetween20(int floor){
 76         if(floor>=0 && floor <=20)
 77             return true;
 78         return false;
 79     }
 80     
 81     public boolean isCorrect(int order,int floor,int toFloor)//判断输入是否合法
 82     {
 83         if(1 == order){//电梯向上
 84             if(!isBetween20(floor))
 85             {
 86                 System.out.println("你在这??      "+floor+"");
 87                 return false;
 88             }
 89             if(!isBetween20(toFloor))
 90             {
 91                 System.out.println("你要去这??   "+floor);
 92                 return false;
 93             }
 94             if(toFloor <= floor){
 95                 System.out.println("你确定是要上楼? 从  "+floor+"-> "+toFloor);
 96                 return false;
 97             }
 98             return true;
 99         }else{//电梯向下
100             if(!isBetween20(floor))
101             {
102                 System.out.println("你在这??      "+floor+"");
103                 return false;
104             }
105             if(!isBetween20(toFloor))
106             {
107                 System.out.println("你要去这?  "+floor);
108                 return false;
109             }
110             if(toFloor >= floor){
111                 System.out.println("你确定是要下楼? from  "+floor+" to "+toFloor);
112                 return false;
113             }
114             return true;
115         }
116     }
117     
118     public int whoIsRun(int e1Distance,int e2Distance,int e3Distance,int e4Distance){//根据传入参数判断哪个电梯最优
119         int[] arr = new int[]{e1Distance,e2Distance,e3Distance,e4Distance};
120         int index=0;
121         for(int i=1;i<4;i++){
122             if(arr[index]>arr[i])
123                 index = i;
124         }
125         return index+1;
126     }
127     
128     private void myEvent(){//创建事件监听
129         f.addWindowListener(new WindowAdapter(){
130             public void windowClosing(WindowEvent e){
131                 System.exit(0);
132             }
133         });
134         
135         personFloor.addKeyListener(new KeyAdapter(){
136             public void keyPressed(KeyEvent e){
137                 
138                 int code = e.getKeyCode();
139                 if(!(code>=KeyEvent.VK_0 && code <= KeyEvent.VK_9 || code==8))
140                 {
141                     System.out.println(code+"... 是非法的");
142                     e.consume();
143                 }
144             }
145         });
146         
147         personToFloor.addKeyListener(new KeyAdapter(){
148             public void keyPressed(KeyEvent e){
149                 int code = e.getKeyCode();
150                 if(!(code>=KeyEvent.VK_0 && code <= KeyEvent.VK_9 || code==8))
151                 {
152                     System.out.println(code+"... 是非法的");
153                     e.consume();
154                 }
155             }
156         });
157         
158         butUp.addActionListener(new ActionListener(){//上升按钮
159             public void actionPerformed(ActionEvent e){
160                 int personF = new Integer(personFloor.getText());
161                 int personTF = new Integer(personToFloor.getText());
162                 if(isCorrect(1,personF,personTF))
163                 {
164                     order = 1;
165                 }
166                 else
167                     order = 0;
168                 System.out.println("上升按钮按下");
169             }
170         });
171         
172         butDown.addActionListener(new ActionListener(){//下降按钮
173             public void actionPerformed(ActionEvent e){
174                 int personF = new Integer(personFloor.getText());
175                 int personTF = new Integer(personToFloor.getText());
176                 if(isCorrect(-1,personF,personTF))
177                 {
178                     order = -1;
179                 }
180                 else
181                     order = 0;
182                 System.out.println("下降按钮按下");
183             }
184         });
185     }
186     
187     
188     public void myRun()//为了调用非静态方法自创的主函数~
189     {    
190     
191         Elevator e1 = new Elevator(1,800,0);
192         Elevator e2 = new Elevator(2,800,1);
193         Elevator e3 = new Elevator(3,1600,2);
194         Elevator e4 = new Elevator(4,2000,0);
195         Controller controller1 = new Controller(e1);
196         Controller controller2 = new Controller(e2);
197         Controller controller3 = new Controller(e3);
198         Controller controller4 = new Controller(e4);
199         
200         Thread t1 = new Thread(controller1);
201         Thread t2 = new Thread(controller2);
202         Thread t3 = new Thread(controller3);
203         Thread t4 = new Thread(controller4);
204         
205         //开启电梯控制器
206         t1.start();
207         t2.start();
208         t3.start();
209         t4.start();
210         
211         while(true)//接收命令
212         {    
213             try {
214                 Thread.sleep(2000);
215             } catch (InterruptedException e) {
216                 // TODO 自动生成的 catch块
217                 e.printStackTrace();
218             }
219 
220             //逻辑判断,哪个电梯拥有最短路径哪个电梯去接人
221             if(1 == order){//上升按钮
222                 int personF = new Integer(personFloor.getText());
223                 int personTF = new Integer(personToFloor.getText());
224                 
225                 //逻辑判断 电梯最优方案
226                 int e1Distance = e1.countDistance(personF, order);
227                 int e2Distance = e2.countDistance(personF, order);
228                 int e3Distance = e3.countDistance(personF, order);
229                 int e4Distance = e4.countDistance(personF, order);
230                 int result = whoIsRun(e1Distance,e2Distance,e3Distance,e4Distance);
231                 switch(result){
232                     case 1:
233                         e1.add(personF, order, personTF);
234                         break;
235                     case 2:
236                         e2.add(personF, order, personTF);
237                         break;
238                     case 3:
239                         e3.add(personF, order, personTF);
240                         break;
241                     case 4:
242                         e4.add(personF, order, personTF);
243                         break;
244                         
245                 }
246                 
247                 order = 0;
248             }
249             else if(-1 == order)//下降按钮
250             {
251                 int personF = new Integer(personFloor.getText());
252                 int personTF = new Integer(personToFloor.getText());
253                 
254                 
255                 //逻辑判断 电梯最优方案
256                 int e1Distance = e1.countDistance(personF, order);
257                 int e2Distance = e2.countDistance(personF, order);
258                 int e3Distance = e3.countDistance(personF, order);
259                 int e4Distance = e4.countDistance(personF, order);
260                 int result = whoIsRun(e1Distance,e2Distance,e3Distance,e4Distance);
261                 switch(result){
262                     case 1:
263                         e1.add(personF, order, personTF);
264                         break;
265                     case 2:
266                         e2.add(personF, order, personTF);
267                         break;
268                     case 3:
269                         e3.add(personF, order, personTF);
270                         break;
271                     case 4:
272                         e4.add(personF, order, personTF);
273                         break;
274                         
275                 }
276                 
277                 order = 0;
278             }
279             //清理屏幕
280             screen1.setText(controller1.getInfo());
281             screen2.setText(controller2.getInfo());
282             screen3.setText(controller3.getInfo());
283             screen4.setText(controller4.getInfo());
284         }
285     }
286     
287     
288     public static void main(String[] args) {
289         new Main();
290     }
291 }
292 
293 class Controller implements Runnable
294 {
295     Elevator Elevator = null;
296     String info = null;
297     Controller(Elevator e)
298     {
299         this.Elevator = e;
300     }
301     
302     public String getInfo(){
303         return info;
304     }
305     public void run()//控制器执行,调度电梯
306     {    
307         while(true)//里面保持每个电梯的运行
308         {
309             try {
310                 Elevator.run();
311                 info = Elevator.show();
312             } catch (Exception e1) {
313                 // TODO 自动生成的 catch 块
314                 e1.printStackTrace();
315             }
316             try {
317                 Thread.sleep(3000);
318             } catch (InterruptedException e) {
319                 // TODO 自动生成的 catch 块
320                 e.printStackTrace();
321             }    
322         }
323     }    
324 }
325 
326 class Elevator
327 {
328     private int id;//电梯编号
329     private int maxLoadWeight;//最大载重
330     private int loadWeight;//当前重量
331     private int state;//0:全层 1:单层 2:双层
332     private int floor; //电梯当前楼层
333     private int runState;//电梯运行状态 0--不动       1--向上    -1--向下
334     private int[] toFloors;//电梯目标楼层
335     private int start,end;
336     private String info;//电梯信息
337     
338     Elevator(int id, int maxLoadWeight, int state){
339         this.id = id;
340         this.maxLoadWeight = maxLoadWeight;
341         this.loadWeight = 0;
342         this.state = state;
343         this.setFloor(1);
344         this.setRunState(0);
345         toFloors = new int[20];
346         this.start = 0;
347         this.end = 0;
348     }
349     
350     public int countDistance(int personFloor, int runDirection)
351     {
352         if(state ==1 && (personFloor%2)==0)
353             return 100;
354         if(state ==2 && (personFloor%2)==1)
355             return 100;
356         if(end == start)
357             return Math.abs(personFloor - floor);
358         else if(end-start ==1){//电梯目标值为1个
359             if(toFloors[end-1] > floor){//电梯上升
360                 if(1 == runDirection){//人上升    三种情况
361                     if(personFloor < floor){
362                         return (toFloors[end-1]-floor)*2+(floor-personFloor);
363                     }else{
364                         return personFloor-floor;
365                     }
366                 }else{//人下降  三种情况
367                     if(personFloor>toFloors[end-1]){
368                         return personFloor-floor;
369                     }else if(personFloor < floor){
370                         return (toFloors[end-1]-floor)*2+(floor-personFloor);
371                     }else{
372                         return (toFloors[end-1]-floor)+(personFloor-floor);
373                     }
374                 }
375             }else{//电梯下降
376                 if(1 == runDirection){//人上升
377                     if(personFloor>floor){
378                         return (floor-toFloors[end-1])*2+(personFloor-floor);        
379                     }else if(personFloor < toFloors[end-1]){
380                         return floor-personFloor;
381                     }else{
382                         return (floor-toFloors[end-1])+(personFloor-toFloors[end-1]);
383                     }
384                 }else{//人下降
385                     if(personFloor>floor){
386                         return (floor-toFloors[end-1])*2+(personFloor-floor);        
387                     }else if(personFloor < toFloors[end-1]){
388                         return floor-personFloor;
389                     }
390                 }
391             }
392         }else{//电梯目标值为两个以上
393             if(toFloors[end-1] >toFloors[end-2]){//电梯最终状态为上升
394                 if(1 == runDirection){//人上升    三种情况
395                     if(personFloor < toFloors[end-2]){
396                         return (toFloors[end-1]-toFloors[end-2])*2+(toFloors[end-2]-personFloor);
397                     }else{
398                         return personFloor-toFloors[end-2];
399                     }
400                 }else{//人下降  三种情况
401                     if(personFloor>toFloors[end-1]){
402                         return personFloor-toFloors[end-2];
403                     }else if(personFloor < toFloors[end-2]){
404                         return (toFloors[end-1]-toFloors[end-2])*2+(toFloors[end-2]-personFloor);
405                     }else{
406                         return (toFloors[end-1]-toFloors[end-2])+(personFloor-toFloors[end-2]);
407                     }
408                 }
409             }else{//电梯最终状态为下降
410                 if(1 == runDirection){//人上升
411                     if(personFloor>toFloors[end-2]){
412                         return (toFloors[end-2]-toFloors[end-1])*2+(personFloor-toFloors[end-2]);        
413                     }else if(personFloor < toFloors[end-1]){
414                         return toFloors[end-2]-personFloor;
415                     }else{
416                         return (toFloors[end-2]-toFloors[end-1])+(personFloor-toFloors[end-1]);
417                     }
418                 }else{//人下降
419                     if(personFloor>toFloors[end-2]){
420                         return (floor-toFloors[end-1])*2+(personFloor-toFloors[end-2]);        
421                     }else if(personFloor < toFloors[end-1]){
422                         return toFloors[end-2]-personFloor;
423                     }
424                 }
425             }
426         }
427         return -100;//防止出错判断        
428     }
429     
430     
431     public void add(int personFloor, int runDirection,int toFloor)
432     {
433         if (end - start > 0)//电梯目标楼层大于0个
434         {
435             if ((toFloors[end-1] - toFloors[end - 2])*runDirection > 0) {//人和电梯同方向
436                 if (1 == runDirection)//同向上
437                 {
438                     if (personFloor > toFloors[end - 1])//人所在楼层 高于 电梯去的最高楼层
439                     {
440                         toFloors[(end++) % 20] = personFloor;
441                         toFloors[(end++) % 20] = toFloor;
442                     }else {//人所在楼层 低于 电梯去的最高楼层
443                         toFloors[end] = toFloors[(end++)%20 -1];
444                         toFloors[end - 2] = personFloor;
445                         if (toFloor > toFloors[end - 1])//人要去楼层高于电梯所在楼层
446                             toFloors[(end++) % 20] = toFloor;
447                         else{    //人要去楼层低于电梯所在楼层
448                             toFloors[end] = toFloors[end - 1];
449                             toFloors[end - 1] = toFloor;
450                             end = (end++) % 20;
451                         }
452 
453                     }
454                 }
455                 else {//同向下
456                     if (personFloor < toFloors[end - 1])//人所在楼层 低于 电梯去的最高楼层
457                     {
458                         toFloors[(end++) % 20] = personFloor;
459                         toFloors[(end++) % 20] = toFloor;
460                     }
461                     else {//人所在楼层 高于 电梯去的最低楼层
462                         toFloors[end] = toFloors[end - 1];
463                         toFloors[end - 1] = personFloor;
464                         end = (end++)%20;
465                         if (toFloor < toFloors[end - 1])//人要去楼层低于电梯所在楼层
466                             toFloors[(end++) % 20] = toFloor;
467                         else {    //人要去楼层高于电梯所在楼层
468                             toFloors[end] = toFloors[end - 1];
469                             toFloors[end - 1] = toFloor;
470                             end = (end++) % 20;
471                         }
472                     }
473                 }
474                     
475             }
476             else {//反方向
477                 toFloors[(end++) % 20] = personFloor;
478                 toFloors[(end++) % 20] = toFloor;
479             }
480         }
481         else//电梯目标楼层数量为1或者0
482         {
483             toFloors[(end++) % 20] = personFloor;
484             toFloors[(end++) % 20] = toFloor;
485         }
486     }
487     
488     
489     public void run()throws Exception//电梯运行
490     {
491         if (start != end)//需要运行
492         {
493             if (floor < toFloors[start])//向上
494             {
495                 runState = 1;
496                 floor++;
497             }
498             else if (floor > toFloors[start])//向下
499             {
500                 runState = -1;
501                 floor--;
502             }
503             else//floor = toFloors[start] 到目的地
504             {
505                 System.out.println("电梯"+id+" 已到达到达目的地:"+floor);
506 
507                 runState = 0;
508                 start = (start+1)%20;
509             }
510         }
511     }
512 
513     public String show(){
514         info = id+"'s Elevator \non "+floor+"'s floor\nis ";
515         if(1 == runState)
516             return info+" ↑";
517         if(-1 == runState)
518             return info+" ↓";
519         return info+" -- ";
520             
521     }
522 
523     public int getRunState() {
524         return runState;
525     }
526 
527     public void setRunState(int runState) {
528         this.runState = runState;
529     }
530 
531     public int getFloor() {
532         return floor;
533     }
534 
535     public void setFloor(int floor) {
536         this.floor = floor;
537     }    
538 }
源码

 

 

 

 

 

 

转载于:https://www.cnblogs.com/lishida/p/5366029.html

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值