博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

图6——DJ最短路径

Posted on 2010-10-23 00:05  猴王无敌  阅读(339)  评论(0)    收藏  举报

【原理】

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算法,或许这就是算法吸引人之处。