/// <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); }