static bool Exchange(List <Airline> first, int firstIndex, List <Airline> second, int secondIndex) { //firstIndex,secondIndex也是需要交换的 var firstPlaneId = first.First().ModifiedPlaneID; var secondPlandId = second.First().ModifiedPlaneID; //1.设定ModifyPlaneID for (int i = secondIndex; i < second.Count; i++) { second[i].ModifiedPlaneID = firstPlaneId; if (!CheckCondition.IsAirlinePlaneAvalible(second[i].StartAirPort, second[i].EndAirPort, second[i].ModifiedPlaneID)) { return(false); } } for (int i = firstIndex; i < first.Count; i++) { first[i].ModifiedPlaneID = secondPlandId; if (!CheckCondition.IsAirlinePlaneAvalible(first[i].StartAirPort, first[i].EndAirPort, first[i].ModifiedPlaneID)) { return(false); } } //2.修改交接处的NextAirline和PreviousAirline first[firstIndex - 1].NextAirLine = second[secondIndex]; second[secondIndex - 1].NextAirLine = first[firstIndex]; first[firstIndex].PreviousAirline = second[secondIndex - 1]; second[secondIndex].PreviousAirline = first[firstIndex - 1]; return(true); }
public static void PlaneProhibit() { //飞机航线限制 //失败 Airline B0001 = new Airline() { ID = "B0001", StartAirPort = "SH", EndAirPort = "BJ", StartTime = new DateTime(2017, 3, 15, 8, 0, 0), EndTime = new DateTime(2017, 3, 15, 11, 0, 0), ModifiedPlaneID = "1" }; CheckCondition.CheckAirLine(B0001); //正常 Airline B0002 = new Airline() { ID = "B0002", StartAirPort = "SH", EndAirPort = "BJ", StartTime = new DateTime(2017, 3, 15, 8, 0, 0), EndTime = new DateTime(2017, 3, 15, 11, 0, 0), ModifiedPlaneID = "2" }; CheckCondition.CheckAirLine(B0002); }
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 bool IsCanEmptyFly(List <Airline> AirlineList, ref int StartIndex, ref int EndIndex) { bool CanEmptyFly = false; //航班表检查 for (int st = StartIndex; st > 0; st--) { var key = AirlineList[st].PlaneType + int.Parse(AirlineList[st].StartAirPort).ToString("D2"); for (int ed = EndIndex; ed < AirlineList.Count; ed++) { //是否拥有航线 if (Solution.FlyTimeDic.ContainsKey(key + int.Parse(AirlineList[ed].StartAirPort).ToString("D2"))) { //是否为国内 if (Solution.DomaticAirport.Contains(AirlineList[ed].StartAirPort) && Solution.DomaticAirport.Contains(AirlineList[st].StartAirPort)) { //是否航班机飞机限制 if (CheckCondition.IsAirlinePlaneAvalible(AirlineList[ed].StartAirPort, AirlineList[st].StartAirPort, AirlineList[0].ModifiedPlaneID)) { if (IsTyphoonOK(AirlineList, st, ed)) { EndIndex = ed; StartIndex = st; CanEmptyFly = true; break; } } } } } if (CanEmptyFly) { break; } } return(CanEmptyFly); }
public static void CheckAirPortProhibit() { //航班一览 //失败:起飞机场关闭 Airline A0001 = new Airline() { ID = "A0001", StartAirPort = "SH", EndAirPort = "BJ", StartTime = new DateTime(2017, 3, 15, 20, 0, 0), EndTime = new DateTime(2017, 3, 15, 23, 0, 0) }; var problem = CheckCondition.CheckAirLine(A0001); Utility.Log("StartTime:" + A0001.StartTime); Utility.Log("TakeOffEarlyTime:" + problem.TakeOffBeforeThisTime + " TakeoffLateTime:" + problem.TakeoffAfterThisTime); //失败:起飞机场关闭(跨日) Airline A0002 = new Airline() { ID = "A0002", StartAirPort = "BJ", EndAirPort = "SH", StartTime = new DateTime(2017, 3, 14, 23, 30, 0), EndTime = new DateTime(2017, 3, 15, 3, 0, 0) }; problem = CheckCondition.CheckAirLine(A0002); Utility.Log("StartTime:" + A0002.StartTime); Utility.Log("LandEarlyTime:" + problem.TakeOffBeforeThisTime + " LandLateTime:" + problem.TakeoffAfterThisTime); Airline A0003 = new Airline() { ID = "A0003", StartAirPort = "BJ", EndAirPort = "SH", StartTime = new DateTime(2017, 3, 15, 1, 30, 0), EndTime = new DateTime(2017, 3, 15, 4, 0, 0) }; problem = CheckCondition.CheckAirLine(A0003); Utility.Log("StartTime:" + A0003.StartTime); Utility.Log("TakeOffBeforeThisTime:" + problem.TakeOffBeforeThisTime + " TakeoffAfterThisTime:" + problem.TakeoffAfterThisTime); //失败:降落机场关闭 Airline B0001 = new Airline() { ID = "B0001", StartAirPort = "BJ", EndAirPort = "SH", StartTime = new DateTime(2017, 3, 15, 15, 0, 0), EndTime = new DateTime(2017, 3, 15, 19, 0, 0) }; problem = CheckCondition.CheckAirLine(B0001); Utility.Log("EndTime:" + B0001.EndTime); Utility.Log("TakeOffBeforeThisTime:" + problem.TakeOffBeforeThisTime + " TakeoffAfterThisTime:" + problem.TakeoffAfterThisTime); //失败:降落机场关闭(跨日,次日) Airline B0002 = new Airline() { ID = "B0002", StartAirPort = "SH", EndAirPort = "BJ", StartTime = new DateTime(2017, 3, 14, 22, 30, 0), EndTime = new DateTime(2017, 3, 15, 1, 0, 0) }; problem = CheckCondition.CheckAirLine(B0002); Utility.Log("EndTime:" + B0002.EndTime); Utility.Log("TakeOffBeforeThisTime:" + problem.TakeOffBeforeThisTime + " TakeoffAfterThisTime:" + problem.TakeoffAfterThisTime); //失败:降落机场关闭(跨日,当日) Airline B0003 = new Airline() { ID = "B0003", StartAirPort = "SH", EndAirPort = "BJ", StartTime = new DateTime(2017, 3, 14, 21, 30, 0), EndTime = new DateTime(2017, 3, 14, 23, 0, 0) }; problem = CheckCondition.CheckAirLine(B0003); Utility.Log("EndTime:" + B0003.EndTime); Utility.Log("TakeOffBeforeThisTime:" + problem.TakeOffBeforeThisTime + " TakeoffAfterThisTime:" + problem.TakeoffAfterThisTime); }
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 CanChangePlane(List <Airline> AirlineList) { int StartIndex, EndIndex; var range = CoreAlgorithm.GetTyphoonRange(AirlineList); StartIndex = range.StartIndex; EndIndex = range.EndIndex; if (StartIndex <= 0 || EndIndex == -1) { return(false); } /*StartIndex 是受 台风影响的航班 * EndIndex 是不受 台风影响的航班! * 空飞航班起点在 StartIndex,终点在 EndIndex * 第一:机型相同(不同机型惩罚太大) * 第二:被取代的航班的飞机,其被取代航班的前期航班,能有一个目的地为当前调整航班台风后的机场的机会 * 第三:代价不能太大*/ var CurrentAirline = AirlineList[StartIndex - 1]; var MinTakeOffTime = CurrentAirline.ModifiedEndTime.AddMinutes(Utility.StayAtAirPortMinutes); var Airport = CurrentAirline.EndAirPort; var orgPlaneType = CurrentAirline.PlaneType; int MinScore = int.MaxValue; var OrgAirlineList = new List <Airline>(); var RepAirlineList = new List <Airline>(); var BaseAirlineList = new List <Airline>(); var OrgAirlineIdx = new List <int>(); var RepAirlineIdx = new List <int>(); var BaseIdx = new List <int>(); foreach (var info in AirportIdAirlineDic[Airport]) { //机型相同(不同机型惩罚太大) if (info.IsTakeOff && info.EventTime >= MinTakeOffTime && info.EventAirline.PlaneType == orgPlaneType) { //已经有调机或者取消的情况,则跳过 if (CoreAlgorithm.EmptyFlyList.Count((x => { return(x.ModifiedPlaneID == info.EventAirline.ModifiedPlaneID); })) == 1) { continue; } if (Solution.PlaneIdAirlineDic[info.EventAirline.ModifiedPlaneID].Count((x => { return(x.FixMethod == enmFixMethod.Cancel); })) > 0) { continue; } var ReplaceAirline = Solution.PlaneIdAirlineDic[info.EventAirline.ModifiedPlaneID]; //被取代的航班的飞机,其被取代航班的前期航班,能有一个目的地为当前调整航班台风后的机场的机会 for (int org = EndIndex; org < AirlineList.Count; org++) { //遍历原来航班的台风后的航班(包括台风后的第一个航班) //当前被替代航班为止(倒序,越接近越好) var replbase = 0; //被取代航班索引号 for (int i = 0; i < ReplaceAirline.Count; i++) { if (ReplaceAirline[i].ID == info.EventAirline.ID) { replbase = i; } } for (int rep = replbase - 1; rep > 0; rep--) { if (ReplaceAirline[rep].EndAirPort.Equals(AirlineList[org].EndAirPort)) { var Score = replbase - rep + org - EndIndex; /* * Console.Write("被取代航班在原飞行计划中的索引:" + RepIdx); * Console.WriteLine(" 前导航班索引:" + rep + " 间隔航班数:" + (RepIdx - rep)); * Console.WriteLine("被前导航班:" + ReplaceAirline[rep].ToString()); * Console.Write("台风后续首航班索引:" + EndIndex); * Console.WriteLine("台风后续目标航班索引:" + org + " 间隔航班数:" + (org - EndIndex)); * Console.WriteLine("总体偏差:" + Score); */ if (Score < MinScore) { OrgAirlineList.Clear(); RepAirlineList.Clear(); BaseAirlineList.Clear(); OrgAirlineIdx.Clear(); RepAirlineIdx.Clear(); BaseIdx.Clear(); MinScore = Score; OrgAirlineList.Add(AirlineList[org]); RepAirlineList.Add(ReplaceAirline[rep]); BaseAirlineList.Add(info.EventAirline); OrgAirlineIdx.Add(org); RepAirlineIdx.Add(rep); BaseIdx.Add(replbase); } else { if (Score == MinScore) { OrgAirlineList.Add(AirlineList[org]); RepAirlineList.Add(ReplaceAirline[rep]); BaseAirlineList.Add(info.EventAirline); OrgAirlineIdx.Add(org); RepAirlineIdx.Add(rep); BaseIdx.Add(replbase); } } break; } } } } } if (OrgAirlineList.Count != 0) { //选择基准时间最早的航班,理由如下 //在衔接的时候,越是早交换,则越可以避免过站时间不足的问题 var SetIdx = 0; var OrgPlandId = AirlineList[0].ModifiedPlaneID; var RelPlaneId = BaseAirlineList[SetIdx].ModifiedPlaneID; var ReplaceAirlineList = Solution.PlaneIdAirlineDic[RelPlaneId]; //取消的时候牵涉到台风场景 if (CheckCondition.TyphoonAirport.Contains(ReplaceAirlineList[RepAirlineIdx[SetIdx]].EndAirPort)) { return(false); } if (CheckCondition.TyphoonAirport.Contains(AirlineList[OrgAirlineIdx[SetIdx]].EndAirPort)) { return(false); } //飞机航线的测试 for (int i = BaseIdx[SetIdx]; i < ReplaceAirlineList.Count; i++) { if (!CheckCondition.IsAirlinePlaneAvalible(ReplaceAirlineList[i].StartAirPort, ReplaceAirlineList[i].EndAirPort, OrgPlandId)) { return(false); } } for (int i = OrgAirlineIdx[SetIdx] + 1; i < AirlineList.Count; i++) { if (!CheckCondition.IsAirlinePlaneAvalible(AirlineList[i].StartAirPort, AirlineList[i].EndAirPort, RelPlaneId)) { return(false); } } var AirlineListClone = Utility.DeepCopy(AirlineList); var ReplaceAirlineListClone = Utility.DeepCopy(ReplaceAirlineList); //1.从StartIndex开始,到ORG为止的航班取消掉 for (int i = StartIndex; i < OrgAirlineIdx[SetIdx] + 1; i++) { AirlineListClone[i].FixMethod = enmFixMethod.Cancel; } //2.被取代的部分取消 for (int i = RepAirlineIdx[SetIdx] + 1; i < BaseIdx[SetIdx]; i++) { ReplaceAirlineListClone[i].FixMethod = enmFixMethod.Cancel; } //3.取代操作(取代者) for (int i = BaseIdx[SetIdx]; i < ReplaceAirlineList.Count; i++) { ReplaceAirlineListClone[i].ModifiedPlaneID = OrgPlandId; } //4.取代操作(被取代者) for (int i = OrgAirlineIdx[SetIdx] + 1; i < AirlineList.Count; i++) { AirlineListClone[i].ModifiedPlaneID = RelPlaneId; } var NewOrgPlaneList = new List <Airline>(); var NewRelPlaneList = new List <Airline>(); for (int i = 0; i < AirlineListClone.Count; i++) { if (AirlineListClone[i].ModifiedPlaneID == OrgPlandId) { NewOrgPlaneList.Add(AirlineListClone[i]); } if (AirlineListClone[i].ModifiedPlaneID == RelPlaneId) { NewRelPlaneList.Add(AirlineListClone[i]); } } for (int i = 0; i < ReplaceAirlineListClone.Count; i++) { if (ReplaceAirlineListClone[i].ModifiedPlaneID == OrgPlandId) { NewOrgPlaneList.Add(ReplaceAirlineListClone[i]); } if (ReplaceAirlineListClone[i].ModifiedPlaneID == RelPlaneId) { NewRelPlaneList.Add(ReplaceAirlineListClone[i]); } } NewOrgPlaneList.Sort((x, y) => { return(x.ModifiedEndTime.CompareTo(y.ModifiedStartTime)); }); NewRelPlaneList.Sort((x, y) => { return(x.ModifiedEndTime.CompareTo(y.ModifiedStartTime)); }); //检查时间间隔 for (int i = 0; i < NewOrgPlaneList.Count; i++) { if (i != 0) { if (NewOrgPlaneList[i].PlaneID != NewOrgPlaneList[i].ModifiedPlaneID) { if (NewOrgPlaneList[i].ModifiedStartTime.Subtract(NewOrgPlaneList[i - 1].ModifiedEndTime).TotalMinutes < Utility.StayAtAirPortMinutes) { return(false); } } } } for (int i = 0; i < NewRelPlaneList.Count; i++) { if (i != 0) { if (NewRelPlaneList[i].PlaneID != NewRelPlaneList[i].ModifiedPlaneID) { if (NewRelPlaneList[i].ModifiedStartTime.Subtract(NewRelPlaneList[i - 1].ModifiedEndTime).TotalMinutes < Utility.StayAtAirPortMinutes) { return(false); } } } } //1.从StartIndex开始,到ORG为止的航班取消掉 for (int i = StartIndex; i < OrgAirlineIdx[SetIdx] + 1; i++) { AirlineList[i].FixMethod = enmFixMethod.Cancel; } //2.被取代的部分取消 for (int i = RepAirlineIdx[SetIdx] + 1; i < BaseIdx[SetIdx]; i++) { ReplaceAirlineList[i].FixMethod = enmFixMethod.Cancel; } //3.取代操作(取代者) for (int i = BaseIdx[SetIdx]; i < ReplaceAirlineList.Count; i++) { ReplaceAirlineList[i].ModifiedPlaneID = OrgPlandId; ReplaceAirlineList[i].FixMethod = enmFixMethod.ChangePlane; } //4.取代操作(被取代者) for (int i = OrgAirlineIdx[SetIdx] + 1; i < AirlineList.Count; i++) { AirlineList[i].ModifiedPlaneID = RelPlaneId; AirlineList[i].FixMethod = enmFixMethod.ChangePlane; } //5.Solution的飞机表更新 Solution.PlaneIdAirlineDic[OrgPlandId].Clear(); Solution.PlaneIdAirlineDic[RelPlaneId].Clear(); foreach (var airline in AirlineList) { Solution.PlaneIdAirlineDic[airline.ModifiedPlaneID].Add(airline); } foreach (var airline in ReplaceAirlineList) { Solution.PlaneIdAirlineDic[airline.ModifiedPlaneID].Add(airline); } Console.WriteLine(OrgPlandId + "->" + RelPlaneId); return(true); } return(false); }
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)); }