using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
public class DijkstraAlgorithm : MonoBehaviour
{
public string StartPos = "a";
public string TargetPos = "e";
public bool CalculateAgain = false;
// 顶点集
private List<string> VertexSet = new List<string>(){"a", "b", "c", "d", "e"};
// 路径值
private Dictionary<string, int> valueMap = new Dictionary<string, int>();
//已处理顶点
private List<string> _AfterCalculate = new List<string>();
//未处理顶点
private List<string> _NotCalculte = new List<string>();
// 顶点权值记录
private Dictionary<string, int> vertexValue = new Dictionary<string, int>();
// 第一个是目标节点,后面是路径
private Dictionary<string, string> PathRecord = new Dictionary<string, string>();
private void DijkstraAlgo(string startVertex, string targetVertex)
{
// 清除掉所有信息
vertexValue.Clear();
PathRecord.Clear();
_NotCalculte.Clear();
_AfterCalculate.Clear();
valueMap.Clear();
// 初始化路径图数据
InitPathValue();
InitVertexValue();
// 设置起点的路径值为0
vertexValue[startVertex] = 0;
PathRecord.Add(startVertex, startVertex);
// 设置未处理的顶点列表为所有的顶点
_NotCalculte.AddRange(VertexSet);
while(_NotCalculte.Count > 0)
{
// 找到权值最小的作为起点
// 找到最小权值顶点
string minVertex = _NotCalculte[0];
int minVertexValue = vertexValue[minVertex];
for(int index = 0, imax = _NotCalculte.Count; index < imax; index++)
{
string crtVertex = _NotCalculte[index];
int crtVertexValue = vertexValue[crtVertex];
if(minVertexValue > crtVertexValue)
{
minVertex = crtVertex;
minVertexValue = crtVertexValue;
}
}
string tempStart = minVertex;
// 以起点开始,计算其它顶点的权值
for(int index = 0, imax = _NotCalculte.Count; index < imax; index++)
{
string targetPos = _NotCalculte[index];
// 查看当前点到每个点的路径值
int pathValue = GetPathValue(tempStart, targetPos);
if(pathValue == int.MaxValue)
{
continue;
}
// 在有路径的情况下,比较当前的顶点权值
// 当前点的路径权值直接从记录中查找,新的权值等于开始点的权值+ 路径权值
int crtValue = vertexValue[targetPos];
int preVextex = vertexValue[tempStart];
if(crtValue > preVextex + pathValue)
{
vertexValue[targetPos] = preVextex + pathValue;
// 记录其路径
if(PathRecord.ContainsKey(targetPos))
{
PathRecord.Remove(targetPos);
}
// 路径等于前一节点 + 当前节点
string crtPath = PathRecord[tempStart] + targetPos;
PathRecord.Add(targetPos, crtPath);
}
}
// 将最小权值点移动到已处理顶点列表中
_AfterCalculate.Add(tempStart);
_NotCalculte.Remove(tempStart);
}
PrintMinPathRecord(targetVertex);
}
void Update()
{
if(CalculateAgain)
{
CalculateAgain = false;
DijkstraAlgo(StartPos, TargetPos);
}
}
private void InitPathValue()
{
valueMap.Add("ab", 3);
valueMap.Add("ac", 2);
valueMap.Add("bc", 2);
valueMap.Add("cd", 1);
valueMap.Add("ce", 6);
valueMap.Add("de", 1);
}
private void InitVertexValue()
{
for(int index = 0, imax = VertexSet.Count; index < imax; index++)
{
string vertex = VertexSet[index];
vertexValue.Add(vertex, int.MaxValue);
}
}
private void PrintVertexValue()
{
foreach(var key in vertexValue.Keys)
{
Debug.Log(key + " = " + vertexValue[key]);
}
}
private void PrintMinPathRecord(string targetPos)
{
string minPath;
if(PathRecord.TryGetValue(targetPos, out minPath))
{
Debug.Log("PATH = " + minPath);
}
}
private void PrintMinPathRecord()
{
Debug.Log("************Min PATH *****************");
foreach(var key in PathRecord.Keys)
{
Debug.Log(key + " = " + PathRecord[key]);
}
Debug.Log("************End PATH *****************");
}
private string GetVertexMinPath(string vertex)
{
string minPath;
if(!PathRecord.TryGetValue(vertex,out minPath))
{
return null;
}
return minPath;
}
private int GetPathValue(string s, string d)
{
foreach(var key in valueMap.Keys)
{
string tempS = key.Substring(0, 1);
string tempD = key.Substring(1, 1);
if(tempS == s && tempD == d)
{
return valueMap[key];
}
}
return int.MaxValue;
}
}