电梯调度算法

经过一系列的讨论,确定了可能要用到的变量

电梯外部的需求信号称为“外召信号”

      内部的需求新号称谓“内召信号”

Fc:当前外召信号所在楼层
Fo-电梯当前所在的楼层
Fm:电梯运行方向上最远的内召目标楼层
Fmax:电梯当前运行方向需要响应的最远楼层

Fmin:电梯反向运行到达的最远楼层
Tr:电梯匀速运行一个楼层所需时间
Ts-电梯在一个楼层的平均停靠时间
N:电梯到达外召楼层所需要响应的召唤总数
N1:电梯在当前运行方向上到达最远内召目标层所需响应的召唤总数
On:电梯当前已登记的停层次数

确定了两个重要的参量时间  TOW()和TOR()

代码如下:

        int TOW(int Foutside, int Fcurrent, int Fmax, int Fmin, int N, int state) //T1,T2作为常量

        {

            if (state == 0)//外信号与电梯运行方向相同,且在前方



                return System.Math.Abs(Foutside - Fcurrent) * T1 + N * T2;



            else if (state == 1)//外信号与电梯运行方向相同,且在后方



                return (System.Math.Abs(Fmax - Fcurrent) + System.Math.Abs(Fmax - Fmin) + System.Math.Abs(Fmin - Foutside)) * T1 + N * T2;



            else                //外信号与电梯运行反方向相反

                return (System.Math.Abs(Fmax - Fcurrent) + System.Math.Abs(Fmax - Foutside)) * T1 + N * T2;



        }



        int TOR(int Fmax, int Fcurrent, int N)

        {

            return System.Math.Abs(Fmax - Fcurrent) * T1 + N * T2;

        }

约束条件:超载。

public bool isOverLoad(IElevator elev)

        {

            if (elev.FreeCapability < 45)

                return true;

            else

                return false;

        }

设想的相应算法流程如下

(1)读出系统初始化时电梯匀速运行一个楼层所需
时间Tr、电梯在一个楼层的平均停靠时间Ts;
(2)读出当前外召信号所在楼层Fc,
(3)读出各单梯的运行状态:Fo,Fm,Fmax,N,N1,
Qn:
(4)计算出各单梯的TOW(n),TOR(n)。

算法的主代码:

private void assignReq(IRequest req)

        {

            switch (_Scenario)

            {

                case Scenario.Random:

                    double opt = Double.MaxValue;

                    int optElev = -1;

                    for (int i = 0; i < 4; i++)

                    {

                        int tow = 0;

                        int tor = 0;

                        double time = 0;

                        

                        IElevator elev = _Elevators[i].Elev;

                        Direction direction = elev.CurrentStatus.CurrentDirection == Direction.No ? elev.HistoryDirection : elev.CurrentStatus.CurrentDirection;

                        if (direction == req.UpDown)

                        {

                            if (direction == Direction.Up && elev.CurrentStatus.CurrentHeight < req.DirectionReqSource * floorHeight

                                || direction == Direction.Down && elev.CurrentStatus.CurrentHeight > req.DirectionReqSource * floorHeight)

                            {

                                tow = TOW(req.DirectionReqSource, elev.CurrentStatus.CurrentFloor, 0, 0, _Elevators[i].GetN(req.DirectionReqSource), 0);

                            }



                            if (direction == Direction.Up && elev.CurrentStatus.CurrentHeight > req.DirectionReqSource * floorHeight

                                || direction == Direction.Down && elev.CurrentStatus.CurrentHeight < req.DirectionReqSource * floorHeight)

                            {

                                tow = TOW(req.DirectionReqSource, elev.CurrentStatus.CurrentFloor, _Elevators[i].getMaxCodirFloor(), _Elevators[i].getMaxIndirFloor(), _Elevators[i].GetN(req.DirectionReqSource), 1);

                            }

                        }

                        else

                        {

                            tow = TOW(req.DirectionReqSource, elev.CurrentStatus.CurrentFloor, _Elevators[i].getMaxCodirFloor(), _Elevators[i].getMaxIndirFloor(), _Elevators[i].GetN(req.DirectionReqSource), 2);

                        }

                        

                        tor = TOR(_Elevators[i].getMaxCodistFloor(),elev.CurrentStatus.CurrentFloor,_Elevators[i].GetN(req.DirectionReqSource));

                        time = k1*tor + k2*tow;

                        if (time < opt)

                        {

                            optElev = i;

                            opt = time;

                        }

                    }

                    wrapReq(req, _Elevators[optElev].Elev);

                    break;

                case Scenario.RushHourCome:

                case Scenario.RushHourLeave:

                    break;

            }

        }


可以进行的改进:将情况进行分类

(1)基站上召请求
If基站有空闲梯Then派某空闲梯
Else if有下行的梯Then根据优化算法派出适量台去基站
Else if无下行的梯Then查找上行任务将执行完的若干梯,派去基站
(2)非基站上召请求
If有上行且将经过外召楼层的梯And此梯未满载
{
If有梯在该层有内选Then根据优化算法从中派出最优梯
Else if没有梯在该层有内选Then根据优化算法派出最优梯
)

Else if上行梯全部已过外召层
Then查找下行梯中最快到达基站的梯等待它从基站上来响应(下行梯应尽
量返回基站,不应被上行呼叫截停)
(3)下召请求
If有下行且将经过外召楼层的梯
{
If有梯在该层有内选Then根据多目标优化算法从中派出最优梯
Else if没有梯在该层有内选Then根据多目标优化算法派出最优梯
)
Else查找在上行梯之中响应该呼叫时间最短的梯(已经路过了的下行梯应尽快
返回基站)

你可能感兴趣的:(算法)