Esempio n. 1
0
        /// <summary>
        /// Поиск оптимального маршрута с посещением всех веток метро с помощью метода ветвей и границ
        /// </summary>
        /// <param name="scheme"></param>
        /// <returns></returns>
        public IEnumerable <IRoute> VisitAllLinesByBranchAndBound(Scheme scheme)
        {
            if (scheme == null)
            {
                throw new ArgumentNullException();
            }

            var stations = scheme.GetAllLineRelationStations();    // Все пересадочные станции всех веток


            var lines         = scheme.GetLines().ToArray(); // все ветки метро
            var linesStations = new Station[lines.Length][]; // массив станций переходов для каждой ветки
            var indeces       = new int[lines.Length];       // индекс станции для каждой ветки

            for (var i = 0; i < lines.Length; ++i)
            {
                linesStations[i] = lines[i].GetRelationStations().ToArray();
                indeces[i]       = 0;
            }

            var lastLineInd = indeces.Length - 1;

            var cache   = new RoutesCollection <Station>((r) => new TwoItemsKey <Station>(r.From, r.To));
            var visitor = new AllLinesVisitor();

            int counter = 0;
            int skipped = 0;

            bool next = true;

            do
            {
                // Обработка станций
                var routes = new List <IRoute>();

                for (int fromLineId = 0; fromLineId < indeces.Length - 1; ++fromLineId)
                {
                    var fromStation = linesStations[fromLineId][indeces[fromLineId]];
                    for (int toLineId = fromLineId + 1; toLineId < indeces.Length; ++toLineId)
                    {
                        var    toStation = linesStations[toLineId][indeces[toLineId]];
                        IRoute route;
                        if (!cache.TryGetRoute(fromStation, toStation, out route))
                        {
                            route = FindRoute(fromStation, toStation);
                            cache.Add(route);
                        }

                        routes.Add(route);
                    }
                }
                visitor.Push(routes);
                counter++;

                /*
                 * // ограничение маршрутов для тестирования
                 * if (counter > 10)
                 *  next = false;
                 */
                // Переход к следующей комбинации
                var lineInd = lastLineInd;
                do
                {
                    ++indeces[lineInd];
                    if (indeces[lineInd] >= linesStations[lineInd].Length)
                    {
                        if (lineInd == 0)
                        {   // перебраны все возможные комбинации
                            next = false;
                            break;
                        }
                        else
                        {
                            indeces[lineInd] = 0;
                        }
                    }
                    else
                    {
                        break;
                    }
                    --lineInd;
                }while (lineInd >= 0);
            }while (next);
            visitor.Complete();
            visitor.Completion.Wait();

            return(visitor.GetResults());
        }
Esempio n. 2
0
 public void Add(IRoute route)
 {
     _routes.Add(route);
     _lines.Add(route.From.Line);
     _lines.Add(route.To.Line);
 }