/* * /// <summary> * /// Откатывает вершины до момента, когда они еще не содержали блокируемые фрагменты пути. * /// </summary> * /// <param name="ignoringFragments">Блокируемые фрагменты пути.</param> * /// <returns>Возвращает ближайшую версию, не содержащую блокируемые фрагменты пути.</returns> * public Points Downgrade(IgnoringFragments ignoringFragments) * { * Points newP = new Points(startPoint, finalPoint); * foreach (Point p in this) newP.Add(p.Downgrade(ignoringFragments)); * return newP; * }*/ /// <summary> /// Находит кратчайший путь. /// </summary> /// <param name="myStartPoint"></param> /// <param name="myFinishPoint"></param> /// <param name="myIgnoringFragments"></param> /// <param name="time"></param> /// <param name="types"></param> /// <param name="speed"></param> /// <param name="reservedTime"></param> /// <param name="databaseMysqlConnection"></param> public void CountShortWay(/*Point myStartPoint, Point myFinishPoint,*/ List <Route> ignoringRoutes, IgnoringFragments myIgnoringFragments, DateTime time, IEnumerable <RouteType> types, double speed, TimeSpan reservedTime, MySql.Data.MySqlClient.MySqlConnection databaseMysqlConnection) { //TimeSpan overLimitResedvedTime = TimeSpan.FromMinutes(20); DEBUG_timeToCreateNext = new TimeSpan(); DateTime t0 = DateTime.Now, t1; TimeSpan /*t_total = new TimeSpan(),*/ t_giversin = new TimeSpan(), t_finding_time = new TimeSpan() /*, t_upd_in_stations = new TimeSpan()*/; TimeSpan /*t_updating_total = new TimeSpan(),*/ t_going_check_total = new TimeSpan(), t_stations = new TimeSpan(), t_without_finding_marks = new TimeSpan(); for (Point selectedPoint = Next(); selectedPoint != null; selectedPoint = Next()) { //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! if (selectedPoint.TotalTime > finalPoint.TotalTime /* + overLimitResedvedTime*/) //... Пропускаем и удаляем, если значение метки превышает минимальное время до пункта назначения. { //points.Remove(selectedPoint);// break; //continue;// } DateTime t4 = DateTime.Now; DateTime t3 = DateTime.Now; Station selectedPointStation = selectedPoint.Station; if (selectedPointStation != null) { // Момент, когда мы прибудем на остановку: DateTime momentWhenComingToStation = time + selectedPoint.TotalTime; //t1 = DateTime.Now; // Загружаем маршруты, проходящие через остановку: List <Route> routesOnStation;// = routesOnStation = Database.GetRoutesOnStation(selectedPointStation.hashcode, canReadDataFromLocalCopy: true); if (selectedPointStation.routes != null) { routesOnStation = selectedPointStation.routes; } else { continue; } //t_total += DateTime.Now - t1; foreach (Route selectedRoute in routesOnStation) { if (ignoringRoutes != null && ignoringRoutes.Contains(selectedRoute)) { continue; } if (types.Contains(RouteTypeConverter.FromString(selectedRoute.type))) { //t1 = DateTime.Now; // Следующая остановка у данного транспорта: Station nextStation = selectedRoute.getNextStation(selectedPointStation); /*// Код остановки, на которую попадем на данном транспорте: * string nextCode = selectedRoute.getNextStationCodeAfter(selectedPointStation.hashcode, canReadDataFromLocalCopy: true);*/ //t_total += DateTime.Now - t1; if (nextStation /*nextCode*/ != null) // Если остановка не является конечной, то: { //t1 = DateTime.Now; // Загружаем расписание: Timetable table = selectedRoute.GetTimetable(selectedPointStation);//Database.GetTimetable(selectedPointStation.hashcode, selectedRoute.hashcode, databaseMysqlConnection, canReadDataFromLocalCopy: true); //t_total += DateTime.Now - t1; // Блокируем попытку попасть указанным транспортом на указанную остановку: if (myIgnoringFragments.Contains(nextStation.hashcode /*nextCode*/, selectedRoute.hashcode, selectedPointStation.hashcode)) { continue; } if (table.type == TableType.table) // Если это точное расписание, то: { // Минимальный начальный момент, с который можно начинать ожидать посадку: DateTime momentWhenAskingForGoing = momentWhenComingToStation; // Резервируем дополнительное время, если будем пересаживаться на другой маршрут: //if (selectedPoint.RouteCode == null || selectedPoint.RouteCode != selectedRoute.hashcode) momentWhenAskingForGoing += reservedTime; if (selectedPoint.Route != null && selectedPoint.Route != selectedRoute) { momentWhenAskingForGoing += reservedTime; } t1 = DateTime.Now; // Подсчитываем, сколько будем ожидать этот транспорт на остановке: TimeSpan waitingTime = table.FindTimeAfter(momentWhenAskingForGoing); t_finding_time += DateTime.Now - t1; // Момент, когда мы сядем в транспорт: DateTime momentWhenSitInTransport = momentWhenAskingForGoing + waitingTime; //t1 = DateTime.Now; /*// Следующая остановка у данного транспорта: * Station nextStation = Database.GetStationByHashcode(nextCode, databaseMysqlConnection, canReadDataFromLocalCopy: true);*/ // И соответствующее расписание на этой остановке: Timetable tbl = selectedRoute.GetTimetable(nextStation);//Database.GetTimetable(nextStation.hashcode, selectedRoute.hashcode, databaseMysqlConnection, canReadDataFromLocalCopy: true); //t_total += DateTime.Now - t1; t1 = DateTime.Now; // (сколько будем ехать до следующей остановки): TimeSpan goingOnTransportTime = tbl.FindTimeAfter(momentWhenSitInTransport); t_finding_time += DateTime.Now - t1; // Метка времени: TimeSpan onNextPointTotalTime = momentWhenSitInTransport - momentWhenComingToStation + goingOnTransportTime + selectedPoint.TotalTime; //t1 = DateTime.Now; if (Find(nextStation).tryUpdate(onNextPointTotalTime, selectedPoint, selectedPointStation, selectedRoute)) { } //t_updating_total += DateTime.Now - t1; } else if (table.type == TableType.periodic) { throw new NotImplementedException(); } } } } } //t_upd_in_stations = TimeSpan.FromMilliseconds(t_updating_total.TotalMilliseconds); t_stations += DateTime.Now - t3; GeoCoords selectedPointCoords = selectedPoint.Coords; t_without_finding_marks += DateTime.Now - t4; // Нет смысла идти пешком "транзитом" через остановку: /*//11111111111111111111111111!!!!!!!!!!!!!!!!!*/ if (selectedPoint.Route == null) { continue; } t4 = DateTime.Now; DateTime t2 = DateTime.Now; // Попробуем пройти пешком до других "вершин": foreach (Point p in this /*!!!!!!!!!!!!points*/) { if (!p.IsVisited && p != selectedPoint) { // Блокируем попытку дойти пешком до указанной остановки: if (myIgnoringFragments.Contains(p.StationCode, null, selectedPointStation.hashcode)) { continue; } t1 = DateTime.Now; int distanceToSelectedPoint = GeoCoords.Distance(selectedPointCoords, p.Coords); t_giversin += DateTime.Now - t1; TimeSpan goingTime = GetTimeForGoingTo(distanceToSelectedPoint, speed /*, true, sp*/); TimeSpan newTime = selectedPoint.TotalTime + goingTime + reservedTime; /*if (p != myFinishPoint)*/ // newTime += reservedTime; //t1 = DateTime.Now; if (p.tryUpdate(newTime, selectedPoint, selectedPointStation)) { } //t_updating_total += DateTime.Now - t1; } } t_going_check_total += DateTime.Now - t2; t_without_finding_marks += DateTime.Now - t4; if (myIgnoringFragments.Contains(null, null, selectedPointStation.hashcode)) { continue; } //t1 = DateTime.Now; if (finalPoint.tryUpdate(selectedPoint.TotalTime + GetTimeForGoingTo(selectedPointCoords, finalPoint.Coords, speed), selectedPoint, selectedPointStation)) { } //t_updating_total += DateTime.Now - t1; } t1 = DateTime.Now; // Сокращаем время ходьбы пешком до минимума и избавляемся от "бессмысленных" пересадок, сохраняя общее время неизменным: Point currentPoint = finalPoint.Previous; while (currentPoint != startPoint) { Route r = currentPoint.Route; if (r != null) { Point previousPoint = currentPoint.Previous; if (previousPoint != startPoint && previousPoint.Route != r) // Если на предыдущую остановку мы добрались другим транспортом, то: { Station previousRouteStation = r.getPreviousStation(previousPoint.Station); if (previousRouteStation != null) { Point point = previousRouteStation.Point; if (point != null && point.IsVisited) { Timetable ttt = r.GetTimetable(previousRouteStation); if (ttt != null) { DateTime ddd = time + previousPoint.TotalTime; TimeSpan moment = r.GetTimetable(currentPoint.Station).FindTimeAfter(ddd); TimeSpan tmp_time = ttt.FindTimeBefore(ddd + moment); TimeSpan momentArriveOnCurrent = previousPoint.TotalTime + moment; TimeSpan momentSittingOnPrevious = momentArriveOnCurrent + tmp_time; /*bool bbb = point.Route != null && point.Route.GetTimetable(point.Station) != null && point.Route.GetTimetable(point.Station).FindTimeAfter(time + point.TotalTime) <= previousPoint.TotalTime + moment + tmp_time; * if (bbb) * { * previousPoint.Route = r; * previousPoint.Previous = point;////!bbb && point.TotalTime <= momentSittingOnPrevious && * } * else */ if (/*point.TotalGoingTime>=previousPoint.TotalGoingTime || */ point.TotalTime <= previousPoint.TotalTime /* && point.TotalGoingTime <= previousPoint.TotalGoingTime*/) { previousPoint.Route = r; previousPoint.Previous = point; } } } } } } currentPoint = currentPoint.Previous; } //MessageBox.Show("Total: " + (DateTime.Now - t0).TotalMilliseconds ///**///+ "\n\tWithout finding minimal marks: " + t_without_finding_marks.TotalMilliseconds //+ "\n\tFinding minimal marks: " + DEBUG_timeToCreateNext.TotalMilliseconds //+ "\n\tStations: " + t_stations.TotalMilliseconds //+ "\n\t\tFinding time: " + t_finding_time.TotalMilliseconds //+ "\n\tWalking checks: " + t_going_check_total.TotalMilliseconds //+ "\n\t\tGaversin: " + t_giversin.TotalMilliseconds/**/ //+ "\n\tRecount: " + (DateTime.Now - t1).TotalMilliseconds //); }