using FLCompanionByDvurechensky.Data; using System.Collections.Generic; /// /// TODO: работает не корректно /// Алгоритм Дейкстры /// public class Dijkstra { Graph graph; List infos; /// /// Конструктор /// /// Граф public Dijkstra(Graph graph) { this.graph = graph; } /// /// Инициализация информации /// void InitInfo() { infos = new List(); foreach (var v in graph.Vertices) { infos.Add(new GraphVertexInfo(v)); } } /// /// Получение информации о вершине графа /// /// Вершина /// Информация о вершине GraphVertexInfo GetVertexInfo(GraphVertex v) { if (v == null) return null; foreach (var i in infos) { if (i.Vertex.Name.Contains(v.Name)) { return i; } } return null; } /// /// Поиск непосещенной вершины с минимальным значением суммы /// /// Информация о вершине public GraphVertexInfo FindUnvisitedVertexWithMinSum() { var minValue = int.MaxValue; GraphVertexInfo minVertexInfo = null; foreach (var i in infos) { if (i.IsUnvisited && i.EdgesWeightSum < minValue) { minVertexInfo = i; minValue = i.EdgesWeightSum; } } return minVertexInfo; } /// /// Поиск кратчайшего пути по названиям вершин /// /// Название стартовой вершины /// Название финишной вершины /// Кратчайший путь public string FindShortestPath(string startName, string finishName) { return FindShortestPath(graph.FindVertex(startName), graph.FindVertex(finishName)); } /// /// Поиск кратчайшего пути по вершинам /// /// Стартовая вершина /// Финишная вершина /// Кратчайший путь public string FindShortestPath(GraphVertex startVertex, GraphVertex finishVertex) { InitInfo(); var first = GetVertexInfo(startVertex); first.EdgesWeightSum = 0; while (true) { var current = FindUnvisitedVertexWithMinSum(); if (current == null) { break; } SetSumToNextVertex(current); } return GetPath(startVertex, finishVertex); } /// /// Вычисление суммы весов ребер для следующей вершины /// /// Информация о текущей вершине void SetSumToNextVertex(GraphVertexInfo info) { info.IsUnvisited = false; foreach (var e in info.Vertex.Edges) { var nextInfo = GetVertexInfo(e.ConnectedVertex); var sum = info.EdgesWeightSum + e.EdgeWeight; if (sum < nextInfo.EdgesWeightSum) { nextInfo.EdgesWeightSum = sum; nextInfo.PreviousVertex = info.Vertex; } } } /// /// Формирование пути /// /// Начальная вершина /// Конечная вершина /// Путь string GetPath(GraphVertex startVertex, GraphVertex endVertex) { var path = endVertex.ToString(); while (startVertex != endVertex) { if(endVertex == null) return path; endVertex = GetVertexInfo(endVertex).PreviousVertex; if(endVertex != null) path = endVertex.ToString() + " = " + path; } return path; } }