Advertisement
VssA

pathFind

Jan 12th, 2024
605
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.39 KB | None | 0 0
  1. using Optimizer.Domain.Common.Entities;
  2. using Optimizer.Domain.Common.ValueObjects;
  3. using Optimizer.Domain.Route.ValueObjects;
  4.  
  5. namespace Optimizer.Application;
  6.  
  7. public class PathFinder
  8. {
  9.     public static (List<(Transport<TTransportId>, List<Station>)>, TimeSpan Time, double avgMaxPassPercent)
  10.         FindPath<TTransportId>(
  11.             Station firstStation,
  12.             Station lastStation,
  13.             List<Transport<TTransportId>> allTransport,
  14.             DateTime currentDateTime)
  15.         where TTransportId : TransportId
  16.     {
  17.         var firstStationTransport = new List<Transport<TTransportId>>();
  18.         foreach (var transport in allTransport)
  19.         {
  20.             if (transport.TransportRoutes.Any(r =>
  21.                     r.ArrivalTimes.Any(a => a.Station == firstStation && a.Time > currentDateTime)
  22.                     && r.ArrivalTimes[^1].Station != firstStation))
  23.             {
  24.                 firstStationTransport.Add(transport);
  25.             }
  26.         }
  27.  
  28.         var possibleWays =
  29.             new List<(List<(Transport<TTransportId>, List<ArrivalTime>)> transportRoutes, TimeSpan TotalTime)>();
  30.         var intermediateWays =
  31.             new List<(List<(Transport<TTransportId>, List<ArrivalTime>)> TransportRoutes, TimeSpan TotalTime)>();
  32.  
  33.         foreach (var transport in firstStationTransport)
  34.         {
  35.             foreach (var route in transport.TransportRoutes)
  36.             {
  37.                 if (!route.ArrivalTimes.Any(a => a.Station == firstStation && a.Time > currentDateTime)
  38.                     || route.ArrivalTimes[^1].Station == firstStation)
  39.                 {
  40.                     continue;
  41.                 }
  42.  
  43.                 var firstStationIndex = route.ArrivalTimes
  44.                     .ToList()
  45.                     .FindIndex(a => a.Station == firstStation);
  46.  
  47.                 var lastStationIndex = route.ArrivalTimes
  48.                     .ToList()
  49.                     .FindIndex(a => a.Station == lastStation);
  50.  
  51.                 if (route.ArrivalTimes.Any(a => a.Station == lastStation) && firstStationIndex < lastStationIndex)
  52.                 {
  53.                     AddWays(possibleWays,transport,route,firstStationIndex,lastStationIndex);
  54.                 }
  55.  
  56.                 foreach (var arrivalTime in route.ArrivalTimes.Where(a => a.Time > currentDateTime))
  57.                 {
  58.                     var intermediateStationIndex = route.ArrivalTimes
  59.                         .ToList()
  60.                         .FindIndex(a => a.Station == arrivalTime.Station);
  61.  
  62.                     if (firstStationIndex < intermediateStationIndex && intermediateStationIndex != lastStationIndex)
  63.                     {
  64.                         AddWays(intermediateWays, transport, route, firstStationIndex, intermediateStationIndex);
  65.                     }
  66.                 }
  67.             }
  68.         }
  69.  
  70.         var transfersCount = 2;
  71.         for (var j = 0; j < transfersCount; j++)
  72.         {
  73.             var paths = intermediateWays.ToList();
  74.             intermediateWays.Clear();
  75.             foreach (var path in paths)
  76.             {
  77.                 var lastTransportRoute = path.TransportRoutes.Last();
  78.                 var startArrival = lastTransportRoute.Item2.Last();
  79.                 var startArrivalStationTransport = new List<Transport<TTransportId>>();
  80.                 foreach (var transport in allTransport)
  81.                 {
  82.                     if (transport.TransportRoutes.Any(r =>
  83.                             r.ArrivalTimes.Any(a => a.Station == startArrival.Station && a.Time > startArrival.Time)
  84.                             && r.ArrivalTimes[^1].Station != startArrival.Station))
  85.                     {
  86.                         startArrivalStationTransport.Add(transport);
  87.                     }
  88.                 }
  89.  
  90.  
  91.                 foreach (var transport in startArrivalStationTransport)
  92.                 {
  93.                     foreach (var route in transport.TransportRoutes)
  94.                     {
  95.                         if (!route.ArrivalTimes.Any(
  96.                                 a => a.Station == startArrival.Station && a.Time > startArrival.Time)
  97.                             || route.ArrivalTimes[^1].Station == startArrival.Station)
  98.                         {
  99.                             continue;
  100.                         }
  101.  
  102.                         var firstStationIndex = route.ArrivalTimes
  103.                             .ToList()
  104.                             .FindIndex(a => a.Station == startArrival.Station);
  105.  
  106.                         var lastStationIndex = route.ArrivalTimes
  107.                             .ToList()
  108.                             .FindIndex(a => a.Station == lastStation);
  109.  
  110.                         if (route.ArrivalTimes.Any(a => a.Station == lastStation) && firstStationIndex < lastStationIndex)
  111.                         {
  112.                             RefreshRoutesAndTime(possibleWays, path, transport, route, firstStationIndex, lastStationIndex);
  113.                         }
  114.  
  115.                         foreach (var arrivalTime in route.ArrivalTimes.Where(a => a.Time > startArrival.Time))
  116.                         {
  117.                             var intermediateStationIndex = route.ArrivalTimes
  118.                                 .ToList()
  119.                                 .FindIndex(a => a.Station == arrivalTime.Station);
  120.  
  121.                             if (firstStationIndex < intermediateStationIndex &&
  122.                                 intermediateStationIndex != lastStationIndex)
  123.                             {
  124.                                 RefreshRoutesAndTime(intermediateWays, path, transport, route, firstStationIndex, intermediateStationIndex);
  125.                             }
  126.                         }
  127.                     }
  128.                 }
  129.             }
  130.         }
  131.  
  132.  
  133.         var routesWithAvgMaxPassengersPercent = possibleWays.Select(way =>
  134.             (way, way.transportRoutes
  135.                 .Select(r => r.Item2
  136.                     .Average(at => (double)at.PassengersCount / r.Item1.MaxPassengersCount))
  137.                 .Average()));
  138.  
  139.         var transportRoute = routesWithAvgMaxPassengersPercent.MinBy(r =>
  140.             r.way.TotalTime.TotalMinutes * (r.Item2 * r.Item2));
  141.         var (transportRoutes, TotalTime) = transportRoute.way;
  142.         var routes = transportRoutes;
  143.  
  144.         var result = new List<(Transport<TTransportId>, List<Station>)>();
  145.         foreach (var way in routes)
  146.         {
  147.             var stations = way.Item2.Select(at => at.Station).ToList();
  148.             result.Add((way.Item1, stations));
  149.         }
  150.  
  151.         return (result, TotalTime, transportRoute.Item2);
  152.     }
  153.  
  154.     private static void RefreshRoutesAndTime<TTransportId>(
  155.         List<(List<(Transport<TTransportId>, List<ArrivalTime>)> TransportRoutes,TimeSpan TotalTime)> ways,
  156.         (List<(Transport<TTransportId>, List<ArrivalTime>)> TransportRoutes,TimeSpan TotalTime) path,
  157.         Transport<TTransportId> transport,
  158.         Domain.Route.Route<TTransportId> route,
  159.         int firstIndex,
  160.         int secondIndex) where TTransportId : TransportId
  161.     {
  162.         var stations = new List<ArrivalTime>();
  163.         for (var i = firstIndex; i <= secondIndex; i++)
  164.         {
  165.             stations.Add(route.ArrivalTimes[i]);
  166.         }
  167.  
  168.         var totalTime = stations[^1].Time - stations[0].Time;
  169.         var transportRoutes = new List<(Transport<TTransportId>, List<ArrivalTime>)>();
  170.         foreach (var oldTransportRoute in path.TransportRoutes)
  171.         {
  172.             transportRoutes.Add(oldTransportRoute);
  173.         }
  174.  
  175.         transportRoutes.Add((transport, stations));
  176.  
  177.         ways.Add((transportRoutes, totalTime + path.TotalTime));
  178.     }
  179.  
  180.     private static void AddWays<TTransportId>(
  181.         List<(List<(Transport<TTransportId>,List<ArrivalTime>)> TransportRoutes,TimeSpan TotalTime)> ways,
  182.         Transport<TTransportId> transport,
  183.         Domain.Route.Route<TTransportId> route,
  184.         int firstIndex,
  185.         int secondIndex) where TTransportId : TransportId
  186.     {
  187.         var stations = new List<ArrivalTime>();
  188.         for (var i = firstIndex; i <= secondIndex; i++)
  189.         {
  190.             stations.Add(route.ArrivalTimes[i]);
  191.         }
  192.  
  193.         var totalTime = stations[^1].Time - stations[0].Time;
  194.         var transportRoutes = new List<(Transport<TTransportId>, List<ArrivalTime>)>
  195.                         {
  196.                             (transport, stations)
  197.                         };
  198.  
  199.         ways.Add((transportRoutes, totalTime));
  200.     }
  201. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement