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


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

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

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

      

    电梯调度

          现有一新建办公大厦,共有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 
    on "+floor+"'s floor
    is ";
    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 
    on "+floor+"'s floor
    is ";
    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 }
    源码
  • 相关阅读:
    Linux基础命令:crontab
    linux基础命令:su和sudo
    Linux基础知识:文件权限管理以及umask
    Linux基础命令:useradd和groupadd
    Linux基础命令:more和less
    Linux基础命令:ln
    Linux基础命令:chattr和lsattr
    Linux基础命令:who和w
    vue项目1-pizza点餐系统6-路由精讲之复用router-view
    vue项目1-pizza点餐系统5-全局守卫
  • 原文地址:https://www.cnblogs.com/lishida/p/5366029.html
Copyright © 2020-2023  润新知