• 结对开发:电梯调度(3)


    电梯模拟调度程序

      经过将近两个星期的结对开发,这个程序将要告一段落了,下面说说这个程序的整体思路与实现:

    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、界面设计:

  • 相关阅读:
    Java并发专题 带返回结果的批量任务执行
    angualejs
    Java并发编程:Callable、Future和FutureTask
    mybatis
    InitialContext和lookup
    git 常用使用命令
    junit spring 测试
    redis windows
    为何PS出的RSS总和大于实际物理内存
    32位机器的LowMemory
  • 原文地址:https://www.cnblogs.com/lijinji/p/3624282.html
Copyright © 2020-2023  润新知