【原理】
STEP1.假设以起点直达图中各点,更新图中各点的MinWeight和PreVertex
STEP2.找出上一次方案中最优解,并记录最优Vertex。
STEP3.假设以最优Vertex到达图中各点,更新图中各点的MinWeight和PreVertex
STEP4.重复STEP2/STEP3,直到图中各点均记录了起点到达的最优解
STEP5.根据终点,反向把最短路径输出。
【实现】
#region ShortPath
public List<CVertex> Dijkstra(int iStartVertexIndex, int iEndVertexIndex)
{
List<CVertex> lstRes = new List<CVertex>();
//1.更新每个节点以iStartVertex起始节点的方案(设置每个Vertex的MinWeight和PreVertexIndex)
foreach (var oVertex in this.m_lstVertex)
{
if (this.m_lstVertex.IndexOf(oVertex) == iStartVertexIndex)
{
oVertex.MinWeight = this.m_lstMatrix[iStartVertexIndex][this.m_lstVertex.IndexOf(oVertex)];
oVertex.PreVertexIndex = iStartVertexIndex;
oVertex.IsVisited = true;
}
else
{
oVertex.MinWeight = this.m_lstMatrix[iStartVertexIndex][this.m_lstVertex.IndexOf(oVertex)];
if (oVertex.MinWeight != INFINITY)
{
oVertex.PreVertexIndex = iStartVertexIndex;
}
else
{
oVertex.PreVertexIndex = -1;
}
}
}
//2.遍历图上每个节点
for (var iVertexIndex = 0; iVertexIndex < this.m_lstVertex.Count; iVertexIndex++)
{
//2.1.按照上次每个节点方案,找到其中最优方案(找到iTmpMinWeight和候选节点)
var iNextVertexIndex = -1;
var iTmpMinWeight = INFINITY;
foreach(var oVertex in this.m_lstVertex)
{
if(oVertex.MinWeight < iTmpMinWeight && false == oVertex.IsVisited)
{
iNextVertexIndex = this.m_lstVertex.IndexOf(oVertex);
iTmpMinWeight = oVertex.MinWeight;
}
}
if (-1 == iNextVertexIndex) break;
this.m_lstVertex[iNextVertexIndex].IsVisited = true;
//2.2.更新m_lstVertex中未访问节点的MinWeight和PreVertexIndex
foreach (var oVertex in this.m_lstVertex)
{
if(false == oVertex.IsVisited)
{
var iDistanceToNextVertex = this.m_lstMatrix[iNextVertexIndex][this.m_lstVertex.IndexOf(oVertex)];
if (INFINITY != iDistanceToNextVertex &&
iTmpMinWeight + iDistanceToNextVertex < oVertex.MinWeight)
{
oVertex.MinWeight = iTmpMinWeight + iDistanceToNextVertex;
oVertex.PreVertexIndex = iNextVertexIndex;
}
}
}
}
//3.输出最短路径
var oEndVertex = this.m_lstVertex[iEndVertexIndex];
lstRes.Add(oEndVertex);
var iPreVertexIndex = oEndVertex.PreVertexIndex;
while (iPreVertexIndex != iStartVertexIndex)
{
var oTargetVertex = this.m_lstVertex[iPreVertexIndex];
lstRes.Add(oTargetVertex);
iPreVertexIndex = oTargetVertex.PreVertexIndex;
}
lstRes.Add(this.m_lstVertex[iStartVertexIndex]);
return lstRes;
}
#endregion
PS:以前公司做过一个自动生成路径覆盖的测试工具,当时穷举图中所有<iStartVertex, iEndVertex>的路径最后求得最优,远不及DJ算法,或许这就是算法吸引人之处。
浙公网安备 33010602011771号