Dijkstra Algorithm 实现

本文介绍了一种使用C#在Unity环境中实现迪杰斯特拉最短路径算法的方法。通过定义顶点集、路径值等数据结构,实现了从指定起点到终点的最短路径计算。该实现包括初始化路径值、顶点值,不断更新最短路径直至找到最终答案。
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;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值