算法思想:
设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
namespace Dijkstra
{
public class Vertex
{
public object Data;
public Vertex(object data)
{
this.Data = data;
}
}
public class Edge
{
public int Start;
public int End;
public int Weight;
public Edge(int start,int end,int weight)
{
this.Start = start;
this.End = end;
this.Weight = weight;
}
}
public class Graph
{
public const int INFINITY = 65535;
public Vertex[] Vertexs;
public int VertexCount;
public Edge[] Edges;
public int[,] Matrix;
public Graph(Vertex[] vertexs,Edge[] edges)
{
this.Vertexs = vertexs;
this.Edges = edges;
VertexCount = Vertexs.Length;
this.Matrix = new int[VertexCount, VertexCount];
for (int i = 0; i < VertexCount; i++)
{
for (int j = 0; j < VertexCount; j++)
{
if (i != j)
{
Matrix[i, j] = INFINITY;
}
}
}
for (int i = 0; i < Edges.Length; i++)
{
int start = Edges[i].Start;
int end = Edges[i].End;
Matrix[start, end] = Edges[i].Weight;
Matrix[end, start] = Edges[i].Weight;
}
}
public static void Dijkstra(Graph graph,int original)
{
int[] S = new int[graph.VertexCount];
int[] distance = new int[graph.VertexCount];
int[] path = new int[graph.VertexCount];
S[original] = 1;
for (int i = 0; i < graph.VertexCount; i++)
{
distance[i] = graph.Matrix[original, i];
path[i] = distance[i] == INFINITY ? -1 : original;
}
for (int i = 1; i < graph.VertexCount; i++)
{
int min = INFINITY;
int k = original;
for (int j = 0; j < distance.Length; j++)
{
if (S[j] != 1 && distance[j] < min)
{
min = distance[j];
k = j;
}
}
S[k] = 1;
for (int j = 0; j < graph.VertexCount; j++)
{
if (S[j] != 1 && distance[j] > distance[k] + graph.Matrix[k, j])
{
distance[j] = distance[k] + graph.Matrix[k, j];
path[j] = k;
}
}
}
for (int i = 0; i < distance.Length; i++)
{
Debug.Log($"顶点{
original}到顶点{
i}的最短距离为{
distance[i]}");
}
for (int i = 0; i < path.Length; i++)
{
string s = DisPlayPath(FindPath(original, i, path));
Debug.Log($"顶点{
original}到顶点{
i}的路径为为{
s}");
}
}
private static List<int> FindPath(int original,int end,int[] path)
{
List<int> Path = new List<int>();
while (end != original)
{
Path.Add(end);
end = path[end];
}
Path.Add(original);
Path.Reverse();
return Path;
}
private static string DisPlayPath(List<int> paths)
{
string s = null;
foreach (var path in paths)
{
s += path;
}
return s;
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Dijkstra;
public class TestDijkstra : MonoBehaviour
{
Graph graph;
void Start()
{
Vertex[] vertexs = GenerateVertex(9);
Edge[] edges = GenerateEdges();
graph = new Graph(vertexs, edges);
Graph.Dijkstra(graph,0);
}
private Vertex[] GenerateVertex(int len)
{
Vertex[] vertexs = new Vertex[len];
for (int i = 0; i < len; i++)
{
vertexs[i] = new Vertex(i);
}
return vertexs;
}
private Edge[] GenerateEdges()
{
Edge edge0 = new Edge(0, 1, 1);
Edge edge1 = new Edge(0, 2, 5);
Edge edge2 = new Edge(1, 2, 3);
Edge edge3 = new Edge(1, 3, 7);
Edge edge4 = new Edge(1, 4, 5);
Edge edge5 = new Edge(2, 4, 1);
Edge edge6 = new Edge(2, 5, 7);
Edge edge7 = new Edge(3, 4, 2);
Edge edge8 = new Edge(3, 6, 3);
Edge edge9 = new Edge(4, 5, 3);
Edge edge10 = new Edge(4, 6, 6);
Edge edge11 = new Edge(4, 7, 9);
Edge edge12 = new Edge(5, 7, 5);
Edge edge13 = new Edge(6, 7, 2);
Edge edge14 = new Edge(6, 8, 7);
Edge edge15 = new Edge(7, 8, 4);
Edge[] edges = {
edge0, edge1, edge2, edge3, edge4, edge5, edge6, edge7, edge8, edge9, edge10, edge11, edge12, edge13, edge14,edge15 };
return edges;
}
}