private static Problem GetProblem(Airline airline) { //机场限制和航班限制 var problem = CheckCondition.CheckAirLine(airline); //限制没有问题,则检查故障表 var TyphoonProblem = CheckCondition.IsExistTyphoon(airline); if (airline.PreviousAirline != null) { if (airline.PreviousAirline.FixMethod == enmFixMethod.EmptyFly || (airline.ModifiedPlaneID != null && airline.PlaneID != null && !airline.ModifiedPlaneID.Equals(airline.PlaneID))) { //向上查找第一个不是取消的航班 var PreviousNotCancel = airline.PreviousAirline; while (PreviousNotCancel.FixMethod == enmFixMethod.Cancel) { if (PreviousNotCancel.PreviousAirline != null) { PreviousNotCancel = PreviousNotCancel.PreviousAirline; } } //从这个开始的最后一个不是取消的航班 //检查一下是否过站时间有问题 if (airline.ModifiedStartTime.Subtract(PreviousNotCancel.ModifiedEndTime).TotalMinutes < Utility.StayAtAirPortMinutes) { problem.IsNotEnoughStayAirportTime = true; problem.TakeoffAfterThisTimeFixStayTime = PreviousNotCancel.ModifiedEndTime.AddMinutes(Utility.StayAtAirPortMinutes); } } } //检查是否同时有两个问题 if (problem.DetailType != ProblemType.None && TyphoonProblem.DetailType != ProblemType.None) { //台风提早起飞的6小时检查时候,可能遇见台风和 problem.DetailType = ProblemType.AirPortTyphoonMix; return(problem); } ; if (TyphoonProblem.DetailType != ProblemType.None) { TyphoonProblem.IsNotEnoughStayAirportTime = problem.IsNotEnoughStayAirportTime; TyphoonProblem.TakeoffAfterThisTimeFixStayTime = problem.TakeoffAfterThisTimeFixStayTime; return(TyphoonProblem); } return(problem); }
private static Airline GetEmptyFly(List <Airline> AirlineList, int StartIndex, int EndIndex) { var EmptyFly = new Airline(); //起飞时间取起飞前50分钟 int EmptyFlySpan = Solution.FlyTimeDic[AirlineList[StartIndex].PlaneType + int.Parse(AirlineList[StartIndex].StartAirPort).ToString("D2") + int.Parse(AirlineList[EndIndex].StartAirPort).ToString("D2")]; EmptyFly.EndTime = AirlineList[EndIndex].StartTime.AddMinutes(-Utility.StayAtAirPortMinutes); EmptyFly.StartTime = EmptyFly.EndTime.AddMinutes(-EmptyFlySpan); EmptyFly.ModifiedStartTime = EmptyFly.StartTime; EmptyFly.ModifiedPlaneID = AirlineList[StartIndex].ModifiedPlaneID; EmptyFly.PlaneType = AirlineList[StartIndex].PlaneType; EmptyFly.FixMethod = enmFixMethod.EmptyFly; EmptyFly.StartAirPort = AirlineList[StartIndex].StartAirPort; EmptyFly.EndAirPort = AirlineList[EndIndex].StartAirPort; //调整调机后航班的PreviousAirLine的值 AirlineList[EndIndex].PreviousAirline = EmptyFly; EmptyFly.NextAirLine = AirlineList[EndIndex]; AirlineList[StartIndex - 1].NextAirLine = EmptyFly; EmptyFly.PreviousAirline = AirlineList[StartIndex - 1]; //目标机场能否降落? var TyphoonProblem = CheckCondition.IsExistTyphoon(EmptyFly); switch (TyphoonProblem.DetailType) { //调整落地时间 case ProblemType.TyphoonLand: //获得降落机场停机的最后降落时间 foreach (var typhoon in CheckCondition.TyphoonList) { if (typhoon.AirPort == EmptyFly.EndAirPort) { EmptyFly.EndTime = typhoon.EndTime; EmptyFly.StartTime = EmptyFly.EndTime.AddMinutes(-EmptyFlySpan); EmptyFly.ModifiedStartTime = EmptyFly.StartTime; //过站时间不足的处理 if (EmptyFly.NextAirLine.ModifiedStartTime.Subtract(EmptyFly.ModifiedEndTime).TotalMinutes < Utility.StayAtAirPortMinutes) { EmptyFly.NextAirLine.Problem = new Problem { TakeOffBeforeThisTime = DateTime.MinValue, TakeoffAfterThisTime = EmptyFly.ModifiedEndTime.AddMinutes(Utility.StayAtAirPortMinutes) }; FixAirportProblemByChangeTakeOffTime(AirlineList, EndIndex, EmptyFly.NextAirLine); } if (AirlineList[EndIndex].IsUseTyphoonRoom) { //如果降落的时候使用IsCanEmptyFly方法是用了机库,这里通过调整,使得不用到机库,退还机库 CheckCondition.TyphoonAirportRemain[EmptyFly.EndAirPort]++; } break; } } break; case ProblemType.TyphoonTakeOff: //获得起飞机场停机的最早起飞时间 foreach (var typhoon in CheckCondition.TyphoonList) { if (typhoon.AirPort == EmptyFly.StartAirPort && typhoon.TroubleType.Equals("起飞")) { EmptyFly.StartTime = typhoon.StartTime; EmptyFly.EndTime = EmptyFly.StartTime.AddMinutes(EmptyFlySpan); EmptyFly.ModifiedStartTime = EmptyFly.StartTime; //最早时间起飞,再影响上一个航班也没有办法了 break; } } break; } var AirportCloseLand = CheckCondition.IsAirPortAvalible(EmptyFly.EndAirPort, EmptyFly.ModifiedEndTime); var AirportCloseTakeoff = CheckCondition.IsAirPortAvalible(EmptyFly.StartAirPort, EmptyFly.ModifiedStartTime); if (!AirportCloseLand.IsAvalible) { var TempProblem = new Problem(); CheckCondition.SetRecoverInfo(EmptyFly, TempProblem, AirportCloseLand, false); EmptyFly.ModifiedStartTime = TempProblem.TakeoffAfterThisTime; } if (!AirportCloseTakeoff.IsAvalible) { var TempProblem = new Problem(); CheckCondition.SetRecoverInfo(EmptyFly, TempProblem, AirportCloseTakeoff, true); EmptyFly.ModifiedStartTime = TempProblem.TakeOffBeforeThisTime; } AdjustTakeOffTime(EmptyFly); return(EmptyFly); }
public static bool FixChainByChangeTakeOffTime_Force(List <Airline> PlaneAirlines, int index) { var adjustAirline = PlaneAirlines[index]; var TakeOffTime = adjustAirline.Problem.IsNotEnoughStayAirportTime ? adjustAirline.Problem.GetTakeOffTime() : adjustAirline.Problem.TakeoffAfterThisTime; //如果上一个航班也是经过台风修正的,这里起飞和降落将重叠 if (adjustAirline.PreviousAirline != null) { if (TakeOffTime.Subtract(adjustAirline.PreviousAirline.ModifiedEndTime).TotalMinutes < Utility.StayAtAirPortMinutes) { TakeOffTime = adjustAirline.PreviousAirline.ModifiedEndTime.AddMinutes(Utility.StayAtAirPortMinutes); } } if (!IsLatable(adjustAirline, TakeOffTime)) { return(false); } var LandTime = TakeOffTime.Add(adjustAirline.FlightSpan); //实际过站时间 var ActualStayMinutes = adjustAirline.NextAirLine.ModifiedStartTime.Subtract(LandTime).TotalMinutes; //过站时间不足 var NotEnoughMinutes = Utility.StayAtAirPortMinutes - ActualStayMinutes; var TempStartTime = adjustAirline.ModifiedStartTime; adjustAirline.ModifiedStartTime = TakeOffTime; var typhoon = CheckCondition.IsExistTyphoon(adjustAirline).DetailType; if (typhoon != ProblemType.None) { return(false); } Utility.Log("[起飞(机场限制)]调整完毕航班:航班ID:" + adjustAirline.ID + " 修改起飞时间:" + TempStartTime + "->" + adjustAirline.ModifiedStartTime); for (int i = index + 1; i < PlaneAirlines.Count; i++) { //从待处理航班的下一个开始,到过站时间允许为止,都需要处理 //每个航班都相应推迟 var airline = PlaneAirlines[i]; if (airline.FixMethod == enmFixMethod.Cancel) { continue; } if (airline.Problem == null) { airline.Problem = new Problem(); } TempStartTime = airline.ModifiedStartTime; //无需每个航班都添加不足时间,有可能原来的航班就已经有多余时间出现了。 //airline.ModifiedStartTime = airline.ModifiedStartTime.AddMinutes(NotEnoughMinutes); var NewStartTime = airline.PreviousAirline.ModifiedEndTime.AddMinutes(Utility.StayAtAirPortMinutes); var NewEndTime = NewStartTime.Add(airline.FlightSpan); var AirportCloseTakeoff = CheckCondition.IsAirPortAvalible(airline.StartAirPort, NewStartTime); var AirportCloseLand = CheckCondition.IsAirPortAvalible(airline.EndAirPort, NewEndTime); if (!AirportCloseLand.IsAvalible) { var TempProblem = new Problem(); var AirClone = Utility.DeepCopy(airline); AirClone.ModifiedStartTime = NewStartTime; CheckCondition.SetRecoverInfo(AirClone, TempProblem, AirportCloseLand, false); //只能延迟。。。 NewStartTime = TempProblem.IsNotEnoughStayAirportTime ? TempProblem.GetTakeOffTime() : TempProblem.TakeoffAfterThisTime; } if (!AirportCloseTakeoff.IsAvalible) { var TempProblem = new Problem(); var AirClone = Utility.DeepCopy(airline); AirClone.ModifiedStartTime = NewStartTime; CheckCondition.SetRecoverInfo(AirClone, TempProblem, AirportCloseTakeoff, true); //只能延迟。。。 NewStartTime = TempProblem.IsNotEnoughStayAirportTime ? TempProblem.GetTakeOffTime() : TempProblem.TakeoffAfterThisTime; } if (!IsLatable(airline, NewStartTime)) { return(false); } //如果新的起飞时间比原来的起飞时间还要早,则直接退出循环 if (NewStartTime > airline.ModifiedStartTime) { if (!airline.IsAllowAdjust) { return(false); } airline.ModifiedStartTime = NewStartTime; if (CheckCondition.IsExistTyphoon(airline).DetailType != ProblemType.None) { return(false); } Utility.Log("[起飞(机场限制)]调整完毕航班:航班ID:" + airline.ID + " 修改起飞时间:" + TempStartTime + "->" + airline.ModifiedStartTime); } else { break; } } return(true); }
public static bool FixByChangeTakeOffTime(List <Airline> PlaneAirlines, int index) { var adjustAirline = PlaneAirlines[index]; var TakeOffTime = adjustAirline.Problem.IsNotEnoughStayAirportTime ? adjustAirline.Problem.GetTakeOffTime() : adjustAirline.Problem.TakeoffAfterThisTime; //如果上一个航班也是经过台风修正的,这里起飞和降落将重叠 if (adjustAirline.PreviousAirline != null) { if (TakeOffTime.Subtract(adjustAirline.PreviousAirline.ModifiedEndTime).TotalMinutes < Utility.StayAtAirPortMinutes) { TakeOffTime = adjustAirline.PreviousAirline.ModifiedEndTime.AddMinutes(Utility.StayAtAirPortMinutes); } } if (!IsLatable(adjustAirline, TakeOffTime)) { return(false); } var LandTime = TakeOffTime.Add(adjustAirline.FlightSpan); //实际过站时间 if (adjustAirline.NextAirLine == null) { //最后航班 adjustAirline.ModifiedStartTime = TakeOffTime; return(true); } var ActualStayMinutes = adjustAirline.NextAirLine.ModifiedStartTime.Subtract(LandTime).TotalMinutes; //过站时间不足 var NotEnoughMinutes = Utility.StayAtAirPortMinutes - ActualStayMinutes; //寻找足够大的时间,使得整个延迟链可以完成 var LargeStayMinutes = Utility.StayAtAirPortMinutes + NotEnoughMinutes; for (int i = index + 1; i < PlaneAirlines.Count - 1; i++) { //i开始计算的是下一个和下两个之间的时间差。如果计算未更改的当前和下一个之间的差距,则会出现问题 //注意,最后一班是无法修改起飞时间的! var staytime = PlaneAirlines[i + 1].ModifiedStartTime.Subtract(PlaneAirlines[i].ModifiedEndTime).TotalMinutes; if (staytime >= LargeStayMinutes) { Utility.Log("航班:" + PlaneAirlines[i].ID + "和航班" + PlaneAirlines[i + 1].ID + "之间的停机时间为:" + staytime); Utility.Log("航班:" + PlaneAirlines[i].ID + "降落时间:" + PlaneAirlines[i].ModifiedEndTime); Utility.Log("航班:" + PlaneAirlines[i + 1].ID + "起飞时间:" + PlaneAirlines[i + 1].ModifiedStartTime); var TempStartTime = adjustAirline.ModifiedStartTime; adjustAirline.ModifiedStartTime = TakeOffTime; if (CheckCondition.IsExistTyphoon(adjustAirline).DetailType != ProblemType.None) { return(false); } Utility.Log("[起飞(机场限制)]调整完毕航班:航班ID:" + adjustAirline.ID + " 修改起飞时间:" + TempStartTime + "->" + adjustAirline.ModifiedStartTime); for (int j = index + 1; j < i + 1; j++) { //从待处理航班的下一个开始,到过站时间允许为止,都需要处理 //每个航班都相应推迟 var airline = PlaneAirlines[j]; if (airline.FixMethod == enmFixMethod.Cancel) { continue; } if (airline.Problem == null) { airline.Problem = new Problem(); } TempStartTime = airline.ModifiedStartTime; //无需每个航班都添加不足时间,有可能原来的航班就已经有多余时间出现了。 //airline.ModifiedStartTime = airline.ModifiedStartTime.AddMinutes(NotEnoughMinutes); var NewStartTime = airline.PreviousAirline.ModifiedEndTime.AddMinutes(Utility.StayAtAirPortMinutes); var NewEndTime = NewStartTime.Add(airline.FlightSpan); if (!CheckCondition.IsAirPortAvalible(airline.StartAirPort, NewStartTime).IsAvalible || !CheckCondition.IsAirPortAvalible(airline.EndAirPort, NewEndTime).IsAvalible) { return(false); } if (!IsLatable(airline, NewStartTime)) { return(false); } //如果新的起飞时间比原来的起飞时间还要早,则直接退出循环 if (NewStartTime > airline.ModifiedStartTime) { if (!airline.IsAllowAdjust) { return(false); } airline.ModifiedStartTime = NewStartTime; if (CheckCondition.IsExistTyphoon(airline).DetailType != ProblemType.None) { return(false); } Utility.Log("[起飞(机场限制)]调整完毕航班:航班ID:" + airline.ID + " 修改起飞时间:" + TempStartTime + "->" + airline.ModifiedStartTime); } else { break; } } return(true); } } return(false); }
public static bool FixByComplexAdjust(List <Airline> airlineList) { //将所有的航班分组(假设没有从台风飞到台风的航班,如果有的话,暂时不处理) //分组的规则为,第一个是起飞是台风关联航班,最后一个结尾是台风关联航班 var airlinegrpList = new List <List <Airline> >(); var IsGroupStarted = false; List <Airline> CurrentGroup = null; for (int i = 0; i < airlineList.Count; i++) { if (CheckCondition.TyphoonAirport.Contains(airlineList[i].StartAirPort)) { //起飞是台风航班 CurrentGroup = new List <Airline>(); airlinegrpList.Add(CurrentGroup); CurrentGroup.Add(airlineList[i]); IsGroupStarted = true; } else { if (CheckCondition.TyphoonAirport.Contains(airlineList[i].EndAirPort)) { //降落是台风航班 if (IsGroupStarted) { //分组开始状态 CurrentGroup.Add(airlineList[i]); IsGroupStarted = false; } else { //分组未开始状态(第一个航班降落在台风机场的情况) CurrentGroup = new List <Airline>(); airlinegrpList.Add(CurrentGroup); CurrentGroup.Add(airlineList[i]); } } else { //起飞降落都是台风航班 if (IsGroupStarted) { //分组开始状态 CurrentGroup.Add(airlineList[i]); } else { //普通航班 CurrentGroup = new List <Airline>(); airlinegrpList.Add(CurrentGroup); CurrentGroup.Add(airlineList[i]); } } } } var firstTyphoonGroupId = -1; for (int i = 0; i < airlinegrpList.Count; i++) { foreach (var airline in airlinegrpList[i]) { //判断被台风影响的航班 var Problem = CheckCondition.IsExistTyphoon(airline); if (Problem.DetailType == ProblemType.TyphoonLand) { firstTyphoonGroupId = i; break; } } if (firstTyphoonGroupId != -1) { break; } } //索引检查 if (firstTyphoonGroupId >= airlinegrpList.Count - 1) { return(false); } if (firstTyphoonGroupId <= 0) { return(false); } // Console.WriteLine("台风开始组号:[" + firstTyphoonGroupId + "]"); var firstAirline = airlinegrpList[firstTyphoonGroupId + 1].First(); var lastAirline = airlinegrpList[firstTyphoonGroupId - 1].Last(); //台风上一组的结束和台风下一组的开始能否衔接? if (lastAirline.EndAirPort != firstAirline.StartAirPort) { return(false); } //下一组的第一个航班是否可以通过提早飞行而成功? firstAirline.Problem = GetProblem(firstAirline); //检查之前,需要正确设置上一个航班的信息! firstAirline.PreviousAirline = lastAirline; if (firstAirline.Problem.DetailType == ProblemType.None || firstAirline.Problem.DetailType == ProblemType.TyphoonStay) { return(false); } if (!FixTyphoonTakeOffByChangeTakeOffTime(firstAirline)) { return(false); } //尝试将第一组台风影响航班取消 foreach (var item in airlinegrpList[firstTyphoonGroupId]) { item.FixMethod = enmFixMethod.Cancel; } return(CoreAlgorithm.AdjustAirLineList(airlineList)); }