Advertisement
VssA

NEWNEWPATHFIND

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