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);
        }
Example #2
0
        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);
        }
Example #4
0
        //是否能改为空飞航班
        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);
        }
Example #5
0
        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);
        }
Example #6
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 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);
        }
Example #10
0
        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));
        }