电梯调度算法

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

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

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

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查找在上行梯之中响应该呼叫时间最短的梯(已经路过了的下行梯应尽快
返回基站)

posted @ 2012-10-23 23:32  MagicCode1023  阅读(935)  评论(0编辑  收藏  举报