FLGameCompanion/FLCompanionByDvurechensky/Models/Dijkstra.cs
Dvurechensky d057fe2c33 1.0
Main
2024-10-05 07:50:50 +03:00

149 lines
4.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using FLCompanionByDvurechensky.Data;
using System.Collections.Generic;
/// <summary>
/// TODO: работает не корректно
/// Алгоритм Дейкстры
/// </summary>
public class Dijkstra
{
Graph graph;
List<GraphVertexInfo> infos;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="graph">Граф</param>
public Dijkstra(Graph graph)
{
this.graph = graph;
}
/// <summary>
/// Инициализация информации
/// </summary>
void InitInfo()
{
infos = new List<GraphVertexInfo>();
foreach (var v in graph.Vertices)
{
infos.Add(new GraphVertexInfo(v));
}
}
/// <summary>
/// Получение информации о вершине графа
/// </summary>
/// <param name="v">Вершина</param>
/// <returns>Информация о вершине</returns>
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;
}
/// <summary>
/// Поиск непосещенной вершины с минимальным значением суммы
/// </summary>
/// <returns>Информация о вершине</returns>
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;
}
/// <summary>
/// Поиск кратчайшего пути по названиям вершин
/// </summary>
/// <param name="startName">Название стартовой вершины</param>
/// <param name="finishName">Название финишной вершины</param>
/// <returns>Кратчайший путь</returns>
public string FindShortestPath(string startName, string finishName)
{
return FindShortestPath(graph.FindVertex(startName), graph.FindVertex(finishName));
}
/// <summary>
/// Поиск кратчайшего пути по вершинам
/// </summary>
/// <param name="startVertex">Стартовая вершина</param>
/// <param name="finishVertex">Финишная вершина</param>
/// <returns>Кратчайший путь</returns>
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);
}
/// <summary>
/// Вычисление суммы весов ребер для следующей вершины
/// </summary>
/// <param name="info">Информация о текущей вершине</param>
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;
}
}
}
/// <summary>
/// Формирование пути
/// </summary>
/// <param name="startVertex">Начальная вершина</param>
/// <param name="endVertex">Конечная вершина</param>
/// <returns>Путь</returns>
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;
}
}