电梯调度算法
经过一系列的讨论,确定了可能要用到的变量
电梯外部的需求信号称为“外召信号”
内部的需求新号称谓“内召信号”
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查找在上行梯之中响应该呼叫时间最短的梯(已经路过了的下行梯应尽快
返回基站)