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