public static OptimalRoute SelectOptimalRouteWithMinimalMark(IEnumerable <OptimalRoute> points, Priority priority)
        {
            OptimalRoute p = null;

            foreach (OptimalRoute t in points)
            {
                if (!(t.IsVisited))
                {
                    p = t;
                    break;
                }
            }
            if (p == null)
            {
                return(p);
            }
            if (priority == Priority.MinimalTime)
            {
                foreach (OptimalRoute t in points)
                {
                    if (!(t.IsVisited) && t.TotalTime < p.TotalTime)
                    {
                        p = t;
                    }
                }
            }
            else if (priority == Priority.MinimalGoingTime)
            {
                foreach (OptimalRoute t in points)
                {
                    if (!(t.IsVisited) && t.TotalGoingTime < p.TotalGoingTime)
                    {
                        p = t;
                    }
                }
            }
            else if (priority == Priority.MinimalTransportChanging)
            {
                foreach (OptimalRoute t in points)
                {
                    if (!(t.IsVisited) && t.TotalTransportChangingCount < p.TotalTransportChangingCount)
                    {
                        p = t;
                    }
                }
            }
            return(p);
        }
        public OptimalWay(OptimalRoute optimalRoute)
        {
            totalTimeSeconds            = (int)optimalRoute.TotalTime.TotalSeconds;
            totalGoingTimeSeconds       = (int)optimalRoute.TotalGoingTime.TotalSeconds;
            totalTransportChangingCount = optimalRoute.TotalTransportChangingCount;
            points = new List <WayPoint>();
            OptimalRoute.Points optRoutePoints = optimalRoute.MyPoints;
            points.Add(new WayPoint(optRoutePoints.startPoint.TotalTime, optRoutePoints.startPoint.Station, optRoutePoints.startPoint.Route, optRoutePoints.startPoint.Coords));

            List <WayPoint> tmp = new List <WayPoint>();

            for (OptimalRoute.Points.Point tmpP = optimalRoute.MyPoints.finalPoint; tmpP.Previous != null; tmpP = tmpP.Previous)
            {
                tmp.Add(new WayPoint(tmpP.TotalTime, tmpP.Station, tmpP.Route, tmpP.Coords));
            }
            tmp.Reverse();
            points.AddRange(tmp);

            /*foreach (OptimalRoute.Points.Point p in optRoutePoints)
             * {
             *  points.Add(new WayPoint(p.Station, p.Route, p.Coords));
             * }
             * points.Add(new WayPoint(optRoutePoints.finalPoint.Station, optRoutePoints.finalPoint.Route, optRoutePoints.finalPoint.Coords));*/
        }
        public static OptimalRoutesCollection FindOptimalRoutes(GeoCoords nowPos, GeoCoords needPos, DateTime time, Dictionary <Priority, double> priorities, IEnumerable <RouteType> types = null, double speed = 5, double dopTimeMinutes = 2, double percentTotalTime = 1, double percentTotalGoingTime = 1, double percentTotalTransportChangingCount = 1)
        {
            int n1 = 1, n2 = 1;

            if (priorities == null || priorities.Count == 0)
            {
                throw new Exception("Не заданы приоритеты.");
            }

            OptimalRoutesCollection findedOptimalRoutes = new OptimalRoutesCollection();

            //DateTime ttt1 = DateTime.Now;
            findedOptimalRoutes.Add(new OptimalRoute(nowPos, needPos, time, types, speed, dopTimeMinutes));
            //MessageBox.Show((DateTime.Now - ttt1).TotalMilliseconds.ToString());

            //return findedOptimalRoutes;//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1

            List <Route> ignoringRoutes   = new List <Route>();


            Stack <Priority> myPriorities = new Stack <Priority>(priorities.Keys);
            //for (Priority currentPriority = myPriorities.Pop(); myPriorities.Count != 0; currentPriority = myPriorities.Pop())
            //{
            Priority currentPriority      = myPriorities.Pop();
            //double ddd = priorities[currentPriority];
            double ddd = 0.25;// 0.95;// 0.85; // Порог эффективности маршрута по выбранному критерию.

            if (ddd > 1 || ddd < 0.25)
            {
                throw new Exception("Priority must been from [0.25; 1]");
            }
            //List<IgnoringFragment> globalIgnoringFragments = new List<IgnoringFragment>();
            IgnoringFragments ignoringFragments = new IgnoringFragments();//!!!!!!!!!!!!!!

            //List<IgnoringFragment> currentIgnoringFragments;

            //Point myStartPoint = findedOptimalRoutes[0].startPoint;

            for (OptimalRoute selectedOptimalRoute = findedOptimalRoutes[0]; selectedOptimalRoute != null; selectedOptimalRoute.Visited(), selectedOptimalRoute = SelectOptimalRouteWithMinimalMark(findedOptimalRoutes, Priority.MinimalTime))
            {
                ignoringRoutes = new List <Route>();//!!!!!!!!!!!1111111111
                // Проходим по всем ребрам выбранного пути и строим новые маршруты при удалении ребер:
                for (Points.Point tmpP = selectedOptimalRoute.myPoints.finalPoint; tmpP.Previous != null; tmpP = tmpP.Previous)
                {
                    if (tmpP.Route != null && !ignoringRoutes.Contains(tmpP.Route))
                    {
                        ignoringRoutes.Add(tmpP.Route);
                    }


                    ////// Игнорируемое "ребро":
                    ////IgnoringFragment tmpIgnFragm = new IgnoringFragment(tmpP.StationCode, tmpP.RouteCode, tmpP.PreviousStationCode);

                    //////!!!!!!!!!!!!!!!!!//
                    ////ignoringFragments = new IgnoringFragments(selectedOptimalRoute.myIgnoringFragments);//!!!!

                    ////if (ignoringFragments.Contains(tmpIgnFragm)) continue;
                    ////ignoringFragments.Add(tmpIgnFragm);

                    ////Points myPoints = null;
                    //////Point myFinishPoint = null;
                    ////OptimalRoute tmpOptimalRoute = null;

                    //////myPoints = selectedOptimalRoute.MyPoints.Downgrade(ignoringFragments);
                    //////myFinishPoint = selectedOptimalRoute.finalPoint.Downgrade(ignoringFragments);

                    //////myPoints = tmpP.Previous.CurrentGraph;

                    ////// Строим новый маршрут, избегая указанные ребра:
                    ////tmpOptimalRoute = new OptimalRoute(nowPos, needPos, time, types, speed, dopTimeMinutes, ignoringList: ignoringFragments/*,/*myStartPoint,*/ /*myPoints*//*, myFinishPoint*/);


                    ////n2++;
                    ////if (tmpOptimalRoute.TotalTime.TotalSeconds <= findedOptimalRoutes[0].TotalTime.TotalSeconds / ddd)
                    ////{
                    ////    string tmpJSON = JsonConvert.SerializeObject(tmpOptimalRoute.points);
                    ////    bool ok = false;
                    ////    foreach (OptimalRoute opt in findedOptimalRoutes)
                    ////    {
                    ////        if (JsonConvert.SerializeObject(opt.points) == tmpJSON)
                    ////        {
                    ////            ok = true;
                    ////            break;
                    ////        }
                    ////    }
                    ////    if (ok) continue;
                    ////    findedOptimalRoutes.Add(tmpOptimalRoute);
                    ////    n1++;
                    ////}
                }
                foreach (Route r in ignoringRoutes)
                {
                    if (selectedOptimalRoute.ignoringRoutes.Contains(r))
                    {
                        continue;
                    }
                    List <Route> ignoringRoutesAdd = new List <Route>(selectedOptimalRoute.ignoringRoutes);
                    ignoringRoutesAdd.Add(r);
                    OptimalRoute tmpOptimalRoute = new OptimalRoute(nowPos, needPos, time, types, speed, dopTimeMinutes, ignoringRoutesAdd: ignoringRoutesAdd);

                    n2++;
                    if (tmpOptimalRoute.TotalTime.TotalSeconds <= findedOptimalRoutes[0].TotalTime.TotalSeconds / ddd)
                    {
                        string tmpJSON = JsonConvert.SerializeObject(tmpOptimalRoute.points);
                        bool   ok      = false;
                        foreach (OptimalRoute opt in findedOptimalRoutes)
                        {
                            if (JsonConvert.SerializeObject(opt.points) == tmpJSON)
                            {
                                ok = true;
                                break;
                            }
                        }
                        if (ok)
                        {
                            continue;
                        }
                        findedOptimalRoutes.Add(tmpOptimalRoute);
                        n1++;
                    }
                }
            }
            //MessageBox.Show(n1 + " from " + n2);
            return(findedOptimalRoutes);
        }