From 7f1d03beec403578d4da10e1b29e1cc6fbb68cf8 Mon Sep 17 00:00:00 2001 From: iFish Date: Fri, 28 Nov 2014 19:04:24 +0800 Subject: [PATCH] sync projects --- TrainInfomationProviderService/Program.cs | 5 +- .../TrainInfo/Entities/Train.cs | 13 ++++ .../TrainTransitOnceResultCollection.cs | 77 ++++++++++++++++++- .../Entities/TrainTransitSearchOptions.cs | 43 +++++++++++ 4 files changed, 135 insertions(+), 3 deletions(-) diff --git a/TrainInfomationProviderService/Program.cs b/TrainInfomationProviderService/Program.cs index 35320de..b06a345 100644 --- a/TrainInfomationProviderService/Program.cs +++ b/TrainInfomationProviderService/Program.cs @@ -41,7 +41,10 @@ namespace TrainInfomationProviderService var searchProvider = new TrainInfoSearchProvider(); var lines = searchProvider.FindDirectTrains(DateTime.Parse("2014-12-10"), "NVH", "JJG").ToArray(); var maxTimeRage = lines.Max(s => s.CalculatedMinutesBase); - var altLines = searchProvider.FindOnceTransitTrains(DateTime.Parse("2014-12-12"), "CCT", "ZHQ", new TrainTransitSearchOptions() { MaxExtraMinutes = int.MaxValue }).ToArray(); + + var opt = new TrainTransitSearchOptions(); + opt.InitLimit(780); + var altLines = searchProvider.FindOnceTransitTrains(DateTime.Parse("2014-12-12"), "NVH", "JJG", opt).ToArray(); var availableLines = lines.Select(s => s.Train.Code + "," + s.FromStation.Name + "," + s.ToStation.Name + "," + s.ElapsedTime).ToArray(); Array.ForEach(altLines.Select(s => diff --git a/TrainInfomationProviderService/TrainInfo/Entities/Train.cs b/TrainInfomationProviderService/TrainInfo/Entities/Train.cs index e529512..545d23f 100644 --- a/TrainInfomationProviderService/TrainInfo/Entities/Train.cs +++ b/TrainInfomationProviderService/TrainInfo/Entities/Train.cs @@ -123,5 +123,18 @@ namespace TrainInfomationProviderService.TrainInfo.Entities return _trainClass ?? '*'; } } + + /// + /// 是否是高速列车 + /// + [JsonIgnore] + public bool IsHighSpeedClass + { + get + { + var c = TrainClass; + return c == 'G' || c == 'D' || c == 'C'; + } + } } } diff --git a/TrainInfomationProviderService/TrainInfo/Entities/TrainTransitOnceResultCollection.cs b/TrainInfomationProviderService/TrainInfo/Entities/TrainTransitOnceResultCollection.cs index be5107c..6f7fd49 100644 --- a/TrainInfomationProviderService/TrainInfo/Entities/TrainTransitOnceResultCollection.cs +++ b/TrainInfomationProviderService/TrainInfo/Entities/TrainTransitOnceResultCollection.cs @@ -173,7 +173,7 @@ namespace TrainInfomationProviderService.TrainInfo.Entities { case 'C': case 'G': - return 30+extraTime; + return 30 + extraTime; case 'D': return 30 + extraTime; case 'Z': @@ -320,6 +320,16 @@ namespace TrainInfomationProviderService.TrainInfo.Entities _list.Remove(line); } } + + //如果线路数超过五条,则砍掉时间太多的 + if (Options.StartCutLongRunningCount <= _list.Count) + { + //基础时间 + var times = _list.Select(s => s.FirstElapsedTime.Add(s.SecondElapsedTime)).OrderBy(s => s).Skip((int)(_list.Count * Options.CutLongRunningSampleRate)).Max(); + var maxTime = (long)(times.Ticks * Options.CutLongRunningRate); + + Array.ForEach(_list.Where(s => (s.SecondElapsedTime + s.FirstElapsedTime).Ticks > maxTime).ToArray(), _ => _list.Remove(_)); + } } #endregion @@ -328,7 +338,70 @@ namespace TrainInfomationProviderService.TrainInfo.Entities void ProcessPriority() { - + //对换乘站点计算优先级 + var stData = _list.GroupBy(s => s.First.ToStation).Select(s => new KeyValuePair(s.Key, s.ToArray())).ToList(); + + stData.Sort((x, y) => + { + //前车高铁/动车等,优先推荐 + var fhc1 = x.Value.Count(_ => _.First.Train.IsHighSpeedClass); + var shc1 = y.Value.Count(_ => _.First.Train.IsHighSpeedClass); + if (shc1 != fhc1) + return shc1 < fhc1 ? 1 : -1; + + //否则推荐后车的高铁/动车 + var fhc2 = x.Value.Count(_ => _.Second.Train.IsHighSpeedClass); + var shc2 = y.Value.Count(_ => _.Second.Train.IsHighSpeedClass); + if (shc2 != fhc2) + return shc1 < fhc1 ? 1 : -1; + + //如果都米有,则按线路数推荐 + if (x.Value.Length != y.Value.Length) + return y.Value.Length - x.Value.Length; + + //线路数也相同。。。。那好像没啥再区别的了 + return 0; + }); + //对应起排序 + var stationWeight = new Dictionary(stData.Count); + for (var i = 0; i < stData.Count; i++) + { + stationWeight.Add(stData[i].Key, i); + } + + //分组排序 + _list.Sort((x, y) => + { + //不推荐,按不推荐来排序 + if (x.NotRecommand ^ y.NotRecommand) + return x.NotRecommand ? 1 : -1; + + //车站不同,按车站来排序 + if (x.First.To != y.First.To) + { + return stationWeight[x.First.ToStation] - stationWeight[y.First.ToStation]; + } + //按前车是否是高速车排序 + if (x.First.Train.IsHighSpeedClass ^ y.First.Train.IsHighSpeedClass) + return x.First.Train.IsHighSpeedClass ? -1 : 1; + //按后车是否是高速车排序 + if (x.Second.Train.IsHighSpeedClass ^ y.Second.Train.IsHighSpeedClass) + return x.Second.Train.IsHighSpeedClass ? -1 : 1; + + //如果到的时间是不推荐的时间 + var xIsTimeNotRecommand = x.FirstTrainArriveDate.Hour < 6 || x.FirstTrainArriveDate.Hour >= 23; + var yIsTimeNotRecommand = y.FirstTrainArriveDate.Hour < 6 || y.FirstTrainArriveDate.Hour >= 23; + if (xIsTimeNotRecommand ^ yIsTimeNotRecommand) + return xIsTimeNotRecommand ? 1 : -1; + + //按总耗时排序 + var ttl1 = x.First.ElapsedTime + x.SecondElapsedTime; + var ttl2 = y.First.ElapsedTime + y.SecondElapsedTime; + + if (ttl1 != ttl2) + return ttl1 < ttl2 ? -1 : 1; + return 0; + }); } #endregion diff --git a/TrainInfomationProviderService/TrainInfo/Entities/TrainTransitSearchOptions.cs b/TrainInfomationProviderService/TrainInfo/Entities/TrainTransitSearchOptions.cs index df2962c..a146c1b 100644 --- a/TrainInfomationProviderService/TrainInfo/Entities/TrainTransitSearchOptions.cs +++ b/TrainInfomationProviderService/TrainInfo/Entities/TrainTransitSearchOptions.cs @@ -13,17 +13,60 @@ namespace TrainInfomationProviderService.TrainInfo.Entities /// public int MaxExtraMinutes { get; set; } + public void InitLimit(int baseMinutes) + { + if (baseMinutes < 120) + { + //2小时内的车最大允许到6小时 + MaxExtraMinutes = baseMinutes*3; + } + else if (baseMinutes < 180) + { + MaxExtraMinutes = (int)(baseMinutes * 2.5); + } + else if (baseMinutes < 300) + { + MaxExtraMinutes = (int)(baseMinutes * 2); + } + else if (baseMinutes < 900) + { + MaxExtraMinutes = (int)(baseMinutes * 1.5); + } + else + { + MaxExtraMinutes = (int)(baseMinutes * 1.3); + } + } + /// /// 同一个车次最高保持的换乘站数 /// public int SameLineMaxKeepStations { get; set; } + /// + /// 当换乘线路数超过此数目时,砍掉超过时间的 + /// + public int StartCutLongRunningCount { get; set; } + + /// + /// 砍掉超过时间比例 + /// + public double CutLongRunningRate { get; set; } + + /// + /// 砍掉时间超过比例时,采样的最高保证比例 + /// + public double CutLongRunningSampleRate { get; set; } + /// /// 创建 的新实例(TrainTransitSearchOptions) /// public TrainTransitSearchOptions() { SameLineMaxKeepStations = 3; + CutLongRunningRate = 1.5; + StartCutLongRunningCount = 5; + CutLongRunningSampleRate = 0.7; } } }