Пример #1
0
        /// <summary>
        /// Осуществляет поиск кратчайшего пути до необходимого типа постройки в «городе».
        /// Если построек такого типа несколько, то возвращает путь только до той, который оказался самым кратчайшим.
        /// Если не удалось найти, то возвращает пустой путь.
        /// </summary>
        /// <param name="graph">Граф, соответствующий городу, в котором будем искать путь.</param>
        /// <param name="startPoint">Стартовая точка, из которой ищем путь.</param>
        /// <param name="institutionType">Тип постройки, к которой ищем путь.</param>
        /// <returns>Объект с информацией о найденном или не найденном пути.</returns>
        public static PathInfo FindPathTo(Graph graph, Vertex startPoint, InstitutionType institutionType)
        {
            PathInfo shortestPath       = PathInfo.CreateEmptyPath();
            float    shortestPathLength = float.MaxValue;

            /**
             * Для нахождения вершин в графе, которые соответствуют нужной нам постройке,
             * осуществляется проход по всем вершинам, и ищется объект нужного нам типа.
             * Далее вызывается алгоритм Дейкстры до найденной вершины. Так повторяется до тех пор, пока
             * не пройдемся по всем нужным нам вершинам. Далее среди всех найденных путей ищется тот, который
             * является наикратчайшим.
             */

            foreach (Vertex vertex in graph.Vertices)
            {
                // Стартовая точка не может оказаться конечной.
                if (vertex == startPoint)
                {
                    continue;
                }

                Institution institution = vertex.Tag as Institution;
                if (institution != null && institution.GetInstitutionType() == institutionType)
                {
                    DijkstraAlgorithm dijkstraAlgorithm = new DijkstraAlgorithm(graph);
                    PathInfo          pathInfo          = dijkstraAlgorithm.FindShortestPath(startPoint, vertex);

                    if (pathInfo.IsEmptyPath())
                    {
                        continue;
                    }
                    if (pathInfo.TotalLength > shortestPathLength)
                    {
                        continue;
                    }

                    // На слишком малых расстояниях между узлами, может быть проблема, что дистанция одинаковая.
                    // Поэтому в таких случаях берем элемент с наименьшим числом узлов.
                    if (pathInfo.TotalLength == shortestPathLength)
                    {
                        if (pathInfo.Path.Length < shortestPath.Path.Length)
                        {
                            shortestPath       = pathInfo;
                            shortestPathLength = pathInfo.TotalLength;
                        }
                    }
                    else
                    {
                        shortestPath       = pathInfo;
                        shortestPathLength = pathInfo.TotalLength;
                    }
                }
            }

            return(shortestPath);
        }