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);
        }
Esempio n. 2
0
        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 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);
        }