[软件工程学习笔记]结对项目---电梯调度(二)---外部控制

      结对项目小组成员:张永、吴盈盈    

      又是一周过去了,在上周对电梯调度问题做过大概的分析之后,本周末我们开始对这个项目进行实现,因为时间紧迫,我们目前只实现了其中的电梯的外部调度的部分,也是较为重要的一部分。

      周五白天和永哥进行了一番商量,下午因为永哥要练车,于是我开始了对界面进行设计。

      我们的界面分为三个部分,一是电梯外部控制模块,二是电梯内部的控制模块,三是电梯运行状态的显示模块。在外部控制模块中有0-20层,每层(除0和20外)都有上下键按钮,用于乘客向电梯发出请求;在电梯的内部控制模块中,都有0-20的按键用于乘客选择目的楼层;在电梯运行状态的模块,我们用了四个电梯门来表示电梯门的运动状态,当到达知道指定楼层时,电梯门会开启,电梯门上面显示的是当前的楼层,旁边则记录着当前人数和重量,如遇超载则发出警报。

      其中电梯按键都是用的checkbox,因为可以支持多选。电梯门用的panel。

      周六的上午,永哥开始为我们的程序填充内容。

      首先按照我们之前的设想建立了如下几个类:

因为本次项目楼层众多,电梯数目也较多,算法和思想虽并不难理解,但重复的代码较为繁杂。

我们首先实现的是电梯的外部控制。

在电梯的外部控制中,我们对其算法的设想是:

准备:我们把电梯的运行状态分为以下五种,(1)静止STOP,(2)向上运行UP,(3)向下运行DOWN,(4)向上运行暂停UP_STOP,(5)向下运行暂停DOWN_STOP。

第一步:用电梯的当前楼层减去乘客发出请求的楼层,并对其差值进行比较排序,按差值从小到达存入数组a[]中。

代码实现如下:

  public static ElevatorObject choseElevator(People people, ElevatorObject elevator1, ElevatorObject elevator2, ElevatorObject elevator3, ElevatorObject elevator4)
        {
            ElevatorObject chosenElevator=new ElevatorObject(0) ;
            ElevatorObject testElevator=null;
            ElevatorObject[] a_Elevator = new ElevatorObject[]{elevator1,elevator2,elevator3,elevator4};
            int test = 0;
            int elevator1_distance=elevator1.getCurFloor()-people.getPeopleFloor();//1号电梯现在的楼层距当前乘客的距离
            int elevator2_distance=elevator2.getCurFloor()-people.getPeopleFloor();//2号电梯现在的楼层距当前乘客的距离
            int elevator3_distance=elevator3.getCurFloor()-people.getPeopleFloor();//3号电梯现在的楼层距当前乘客的距离
            int elevator4_distance=elevator4.getCurFloor()-people.getPeopleFloor();//4号电梯现在的楼层距当前乘客的距离
            int[] a = new int[] { elevator1_distance, elevator2_distance, elevator3_distance, elevator4_distance };
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3 - i; j++)
                {
                    if (a[j] > a[j + 1])
                    {
                        test = a[j];
                        testElevator = a_Elevator[j];
                        a[j] = a[j + 1];
                        a_Elevator[j] = a_Elevator[j + 1];
                        a[j + 1] = test;
                        a_Elevator[j + 1] = testElevator;
                    }
                }
            }

第二步:以电梯上升时为例,分情况进行调度。

1、当四部电梯的当前楼层都在乘客指定楼层之下时,选定a[0]对其运动状态进行判断,当其的运动状态为(1)(2)(4)时,则对它进行调度,若为其他状态则判断a[1],以此类推。

 case Number.UP:
                   
                    if (a[3] < 0)
                    {
                        for (int i = 3; i >= 0; i--)
                        {
                            if (a_Elevator[i].getElevatorStates() == Number.UP || a_Elevator[i].getElevatorStates() == Number.UP_STOP || a_Elevator[i].getElevatorStates() == Number.STOP)
                            {
                                chosenElevator = a_Elevator[i];
                                i = -1;//跳出for循环
                            }
                        }
                    }

2、当只有三部电梯的当前楼层在乘客指定楼层之下时,首先判断第四部电梯a[3]是否在指定楼层及其以上(<a[2])停止,若不是则继续按1中判断进行调度。

                    else if (a[2] < 0)
                    {
                        if ((a[3] == 0&&a_Elevator[3].getElevatorStates()==Number.UP_STOP)||(a_Elevator[3].getElevatorStates()==Number.STOP&&a[3]<(0-a[2])))
                        {
                            chosenElevator = a_Elevator[3];
                        }
                        else
                        {
                            for (int i = 2; i >= 0; i--)
                            {
                                if (a_Elevator[i].getElevatorStates() == Number.UP || a_Elevator[i].getElevatorStates() == Number.UP_STOP || a_Elevator[i].getElevatorStates() == Number.STOP)
                                {
                                    chosenElevator = a_Elevator[i];
                                    i = -1;//跳出for循环
                                }
                            }
                        }
                    }

3、当只有两部电梯的当前楼层在乘客指定的楼层之下时,首先判断距离指定楼层最近的a[2]是在指定楼层及其以上(<|a[1]|)停止,其次再判断a[3](<|a[2]|),都不是则继续按1中判断进行调度。

 else if (a[1] < 0)
                    {
                        if ((a[2] == 0 && a_Elevator[2].getElevatorStates() == Number.UP_STOP) || (a_Elevator[3].getElevatorStates()==Number.STOP && a[2] < (0 - a[1])))
                        {
                            chosenElevator = a_Elevator[2];
                        }
                        else if((a[3] == 0&&a_Elevator[3].getElevatorStates()==Number.UP_STOP)||(a_Elevator[3].getElevatorStates()==Number.STOP&&a[3]<(0-a[2])))
                        {
                            chosenElevator = a_Elevator[3];
                        }
                        else
                        {
                            for (int i = 1; i >= 0; i--)
                            {
                                if (a_Elevator[i].getElevatorStates() == Number.UP || a_Elevator[i].getElevatorStates() == Number.UP_STOP || a_Elevator[i].getElevatorStates() == Number.STOP)
                                {
                                    chosenElevator = a_Elevator[i];
                                    i = -1;//跳出for循环
                                }
                            }
                        }
                    }

4、当只有一部电梯的当前楼层在乘客的指定楼层之下时,首先判断距离指定楼层最近的a[1]是在指定楼层及其以上(<|a[0]|)停止,其次再判断a[2](<|a[1]|),在判断a[3](<|a[2]|)都不是则继续按1中判断进行调度。

else if (a[0] < 0)
                    {
                        if ((a[1] == 0 && a_Elevator[1].getElevatorStates() == Number.UP_STOP) || (a_Elevator[1].getElevatorStates()==Number.STOP && a[1] < (0 - a[0])))
                        {
                            chosenElevator = a_Elevator[1];
                        }
                        else if ((a[2] == 0 && a_Elevator[2].getElevatorStates() == Number.UP_STOP) || (a_Elevator[3].getElevatorStates() == Number.STOP && a[2] < (0 - a[1])))
                        {
                            chosenElevator = a_Elevator[2];
                        }
                        else if ((a[3] == 0 && a_Elevator[3].getElevatorStates() == Number.UP_STOP) || (a_Elevator[3].getElevatorStates() == Number.STOP && a[3] < (0 - a[2])))
                        {
                            chosenElevator = a_Elevator[3];
                        }

5、当所有电梯都在指定楼层之上时,则选择静止状态的进行调度。

    else
                    {
                        if ((a[0] == 0 && a_Elevator[0].getElevatorStates() == Number.UP_STOP) || a_Elevator[0].getElevatorStates()==Number.STOP )
                        {
                            chosenElevator = a_Elevator[0];
                            a_Elevator[0].setElevatorStates(Number.UP);
                        }
                        else if ((a[1] == 0 && a_Elevator[1].getElevatorStates() == Number.UP_STOP) || (a_Elevator[1].getElevatorStates() == Number.STOP && a[1] < (0 - a[0])))
                        {
                            chosenElevator = a_Elevator[1];
                        }
                        else if ((a[2] == 0 && a_Elevator[2].getElevatorStates() == Number.UP_STOP) || (a_Elevator[3].getElevatorStates() == Number.STOP && a[2] < (0 - a[1])))
                        {
                            chosenElevator = a_Elevator[2];
                        }
                        else if ((a[3] == 0 && a_Elevator[3].getElevatorStates() == Number.UP_STOP) || (a_Elevator[3].getElevatorStates() == Number.STOP && a[3] < (0 - a[2])))
                        {
                            chosenElevator = a_Elevator[3];
                        }
                    }


在多次调试之后,电梯的外部控制的调度告一段落。

以下是运行的截图。

相比外部控制,内部的控制更为容易一些,我们已经实现了电梯一的内部控制,还没来得及给剩下的三部添加。还有对人的类的随机从产生人数和体重的功能还没有实现,在接下来的开发中我们会慢慢的实现。

PS.跟着永哥做项目特别有收获,我们在结对开发的过程中,绝大多数都是永哥作飞行员,我做导航的学员,在看他调试程序的过程中学到很多,同时也会提出一些可能存在的问题,或是出现问题的原因,永哥总是能按部就班的进行测试发现问题所在并很快的改正,这份踏实和机智是我特别应该学习的。OK,今天就先到这吧。

原文地址:https://www.cnblogs.com/wingwyy511/p/3604255.html