您的位置:首页 > 编程语言 > C语言/C++

小飞的电梯调度算法

2016-06-22 15:15 507 查看
1、问题描述:

某大厦一共有6部电梯,在高峰时间,每层都有人上下,电梯在每层都停,实习生小飞常常会被每层都停的电梯弄的很不耐烦,于是他提出了这样一个办法:由于楼层不太高,每次电梯往上走时,我们只允许电梯停在其中的某一层。所有乘客都从一楼上电梯,到达某层后,电梯停下来,所有乘客再从这里爬楼梯到自己的目的层。在一楼的时候,每个乘客选择自己的目的层,电梯自动计算出相应的楼层。电梯应停在哪一层,能够保证这次乘坐电梯的所有乘客爬楼梯的层数之和最小?

2、分析:

该问题本质上是一个优化问题,从问题中我们可以看到,影响结果的主要有两个因素:乘客人数和电梯停的层数。假设楼层总共有N层,电梯停在x层,到第i层的乘客人数为Tot[i],则所爬楼梯的总数是:|x-1|*Tot[1]+|x-2|*Tot[2]+.....+|x-N|*Tot
。我们就是寻找一个最优的x,使总和最小。

3、解法:

<1>解法一

可以从第一层开始来枚举x,一直到第N层,然后计算出乘客所爬楼梯的总数,并求出最小值以及此时的x的值。这个算法的时间复杂度为O(n*n)。

#include <iostream>

using namespace std;

void min_floor(int floor_num,int tot_person[]);//参一:楼层总数;参二:去每层的人数

int main()
{
int tot_person[7] = { 0,1, 2, 2, 0, 3, 2 };
min_floor(6, tot_person);
}

void min_floor(int floor_num, int tot_person[])
{
int i,j, minFloor,total_floor = 0, target_floor = -1;

for (i = 1; i <= floor_num;i++)
{
for (j = 1; j <= i; j++)
total_floor += tot_person[j] * (i - j);
for (j = i + 1; j <= floor_num;j++)
total_floor += tot_person[j] * (j - i);
if (target_floor == -1 || minFloor > total_floor)
{
target_floor = i;
minFloor = total_floor;
}
total_floor = 0;
}
cout << "目标楼层:" << target_floor << endl << "最少层数:" << minFloor << endl;
}
运行结果:



<2>解法二

假设电梯停在第i层楼,那我们可以计算出所有乘客爬的总楼层数Y。如果有N1个乘客目的楼层在i层楼以下,N2个乘客目的楼层在i层楼,N3个乘客在i层楼以上。在这种情况下,如果电梯改停在(i+1)层,那么目的楼层在i层以上的乘客将少爬一层,即N3个乘客将少爬N3层,目的楼层在i层及i层以下的乘客将多爬一层,及多爬(N1+N2)层,因此所有乘客爬的楼层数为Y-N3+N1+N2 = Y+(N1+N2-N3)。同理可以求的电梯改停在(i-1)层时,乘客所爬的楼层总数为Y-(N1-N2-N3)。由此可见当N1+N2
< N3时乘客少爬的楼层数为N3-N1-N2,电梯在i+1层停更好;如果N2+N3 < N1,乘客少爬的楼层数为N1-N2-N3,电梯停在i-1层更好;其它情况停在i层更好。

根据这个规律我们从第一层开始考察,计算乘客所爬楼梯的总数。然后再根据上面的策略进行调整,直到找到最佳楼层。总的时间复杂度为O(N)。

#include <iostream>

using namespace std;
void min_floor_second(int floor_num, int tot_person[]);//参一:楼层总数;参二:去每层的人数

int main()
{
int tot_person[7] = { 0,1, 2, 2, 0, 3, 2 };
min_floor_second(6,tot_person);
}

void min_floor_second(int floor_num, int tot_person[])
{
int N1 = 0, N2 = tot_person[1], N3 = 0;
int i, target_floor = 1,min_floor = 0;

for (i = 2; i <= floor_num; i++)
{
N3 += tot_person[i];
min_floor += tot_person[i] * (i - 1);
}

for (i = 2; i <= floor_num;i++)
{
if ( (N1 + N2) < N3)
{
target_floor = i;
min_floor += (N1 + N2 - N3);
N3 -= tot_person[i];
N1 += N2;
N2 = tot_person[i];
}
else
break;
}
cout << "目标楼层:" << target_floor << endl << "所爬层数:" << min_floor << endl;
}运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 c语言