电梯调度算法——编程之美

编程之美——电梯调度算法 2011-06-02 15:24

一座大厦一共有6部电梯。在高峰时间,每层都有人上下,电梯在每层都停。

实习生小飞常常会被每层都停的电梯弄得很不耐烦,于是他提出了这样的一个办法:

由于楼层并不太高,那么在繁忙的上下班时间,每次电梯从一层往上走时,我们只允许电梯停在其中的一层。

所有乘客都从一楼上电梯,到达某楼层后,电梯停下来,所有乘客再从这里爬到自己的目的层。

在一楼上电梯的时候,每个乘客选择自己的目的层,电梯则自动计算出应停的楼层。

问:电梯停在哪一层,能够保证这次乘坐的电梯所有乘客爬楼梯的层数之和最少?

首先,有两个因素会影响到最后的结果:

乘客的数目和要停的目的楼层

假设楼层总共有N层,电梯停在第x层,要去第i层的乘客数目总数为Tot【i】,这样,总数就是 { Tot [ i ] * | i – x |};

我们的任务就是找到这样的一个最小值

枚举的代码:

// nMinFloor:返回这次乘坐电梯所有乘客爬楼梯的层数之和的最小值

//  nTargetFloor:返回电梯停在那一层

void solve(int & nTargetFloor, int & nMinFloor){
int nFloor;
nTargetFloor=-1;
for(int i=1;i<=N;i++)   //电梯停在第i层
{

nFloor=0;

//计算nFloor,人们下楼梯的总层数

for(int j=1;j<i;j++)    

         nFloor+=nPerson[j]*(i-j);

//计算nFloor,人们上楼梯的总层数

for(int j=i+1;j<=N;j++)   

          nFloor+=nPerson[j]*(j-i);

if(nTargetFloor == -1 || nMinFloor > nFloor)

{

nMinFloor=nFloor;

nTargetFloor=i;

}

}

}

显然这个解法可以进一步优化:

假设电梯停在第i层,显然我们可以计算出所有乘客总共要爬的层数Y。

如果有N1个乘客目的楼层在i层以下,有N2个乘客在i层,还有N3个乘客在第i层以上。

这个时候,如果电梯改停在第i-1层,所有目的地在i层以上的乘客都要多爬一层,总共需要N2+N3层,而所有目的地在第i-1层以下的乘客都可以少爬一层,总共少爬N1层。所以乘客总共需要爬Y-(N1-N2-N3)

反之,如果电梯停在i+1层,那么乘客总共需要爬Y+(N1+N2-N3)层。

由此可知:

当N1>N2+N3时,电梯停在i-1层好,乘客少走N1-N2-N3层

当N1+N2<N3时,电梯停在i+1层好

其他情况停在i层好

这样我们可以从第一层开始考虑

代码如下:

[cpp]  view plain copy

  1. void solve(int & nTargetFloor,int & nMinFloor)  
  2. {  
  3.    int N1,N2,N3,i;  
  4.    nTargetFloor=1;  
  5.    nMinFloor=0;  
  6.    for(N1=0,N2=nPerson[1],N3=0,i=2;  i<=N;i++)  
  7.    {  
  8.         N3+=nPerson[i];  
  9.         nMinFloor+=nPerson[i]*(i-1);  
  10.    }  
  11.    for(i=2;i<=N;i++)  
  12.    {  
  13.        if(N1+N2<N3)  
  14.        {  
  15.            nTargetFloor=i;  
  16.            nMinFloor+=(N1+N2-N3);  
  17.            N1+=N2;  
  18.            N2=nPerson[i];  
  19.            N3-=nPerson[i];  
  20.        }  
  21.        else  
  22.          break;  
  23.     }  
  24. }  
    原文作者:报恩的猫
    原文地址: https://blog.csdn.net/baoendemao/article/details/41246265
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞