http://www.cnblogs.com/zxjyuan/archive/2010/01/06/1640092.html

 

冒泡法:

}



选择排序法

}



插入排序法

}



希尔排序法



以前空闲的时候用C#实现的路径规划算法,今日贴它出来,看大家有没有更好的实现方案。关于路径规划(最短路径)算法的背景知识,大家可以参考《C++算法--图算法》一书。
    该图算法描述的是这样的场景:图由节点和带有方向的边构成,每条边都有相应的权值,路径规划(最短路径)算法就是要找出从节点A到节点B的累积权值最小的路径。
    首先,我们可以将“有向边”抽象为Edge类:

    public class Edge
    {
        public string StartNodeID ;
        public string EndNodeID   ;
        public double Weight      ; //权值,代价        
    }

    节点则抽象成Node类,一个节点上挂着以此节点作为起点的“出边”表。

C#排序相关算法       public class Node
    }

    
    在计算的过程中,我们需要记录到达每一个节点权值最小的路径,这个抽象可以用PassedPath类来表示:

    /// <summary>
    /// PassedPath 用于缓存计算过程中的到达某个节点的权值最小的路径
    /// </summary>
    public class PassedPath
    {
        private string     curNodeID ;
        private bool     beProcessed ;   //是否已被处理
        private double     weight ;        //累积的权值
        private ArrayList passedIDList ; //路径

        public PassedPath(string ID)
        {
            this.curNodeID = ID ;
            this.weight    = double.MaxValue ;
            this.passedIDList = new ArrayList() ;
            this.beProcessed = false ;
        }

        #region property
        public bool BeProcessed
        {
            get
            {
                return this.beProcessed ;
            }
            set
            {
                this.beProcessed = value ;
            }
        }

        public string CurNodeID
        {
            get
            {
                return this.curNodeID ;
            }
        }

        public double Weight 
        {
            get
            {
                return this.weight ;
            }
            set
            {
                this.weight = value ;
            }
        }

        public ArrayList PassedIDList
        {
            get
            {
                return this.passedIDList ;
            }
        }
        #endregion
    }


    另外,还需要一个表PlanCourse来记录规划的中间结果,即它管理了每一个节点的PassedPath。


    /// <summary>
    /// PlanCourse 缓存从源节点到其它任一节点的最小权值路径=》路径表
    /// </summary>
    public class PlanCourse
    {
        private Hashtable htPassedPath ;    

        #region ctor
        public PlanCourse(ArrayList nodeList ,string originID)
        {
            this.htPassedPath = new Hashtable() ;

            Node originNode = null ;
            foreach(Node node in nodeList)
            {
                if(node.ID == originID)
                {
                    originNode = node ;
                }
                else
                {
                    PassedPath pPath = new PassedPath(node.ID) ;
                    this.htPassedPath.Add(node.ID ,pPath) ;
                }
            }

            if(originNode == null) 
            {
                throw new Exception("The origin node is not exist !") ;
            }        
    
            this.InitializeWeight(originNode) ;
        }

        private void InitializeWeight(Node originNode)
        {
            if((originNode.EdgeList == null) ||(originNode.EdgeList.Count == 0))
            {
                return ;
            }

            foreach(Edge edge in originNode.EdgeList)
            {
                PassedPath pPath = this[edge.EndNodeID] ;
                if(pPath == null)
                {
                    continue ;
                }

                pPath.PassedIDList.Add(originNode.ID) ;
                pPath.Weight = edge.Weight ;
            }
        }
        #endregion

        public PassedPath this[string nodeID]
        {
            get
            {
                return (PassedPath)this.htPassedPath[nodeID] ;
            }
        }
    }


    在所有的基础构建好后,路径规划算法就很容易实施了,该算法主要步骤如下:
(1)用一张表(PlanCourse)记录源点到任何其它一节点的最小权值,初始化这张表时,如果源点能直通某节点,则权值设为对应的边的权,否则设为double.MaxValue。
(2)选取没有被处理并且当前累积权值最小的节点TargetNode,用其边的可达性来更新到达其它节点的路径和权值(如果其它节点   经此节点后权值变小则更新,否则不更新),然后标记TargetNode为已处理。
(3)重复(2),直至所有的可达节点都被处理一遍。
(4)从PlanCourse表中获取目的点的PassedPath,即为结果。
    
    下面就来看上述步骤的实现,该实现被封装在RoutePlanner类中:

    /// <summary>
    /// RoutePlanner 提供图算法中常用的路径规划功能。
    /// 2005.09.06
    /// </summary>
    public class RoutePlanner
    {
        public RoutePlanner()
        {            
        }

        #region Paln
        //获取权值最小的路径
        public RoutePlanResult Paln(ArrayList nodeList ,string originID ,string destID)
        {
            PlanCourse planCourse = new PlanCourse(nodeList ,originID) ;

            Node curNode = this.GetMinWeightRudeNode(planCourse ,nodeList ,originID) ;

            #region 计算过程
            while(curNode != null)
            {
                PassedPath curPath = planCourse[curNode.ID] ;
                foreach(Edge edge in curNode.EdgeList)
                {
                    PassedPath targetPath = planCourse[edge.EndNodeID] ;
                    double tempWeight = curPath.Weight + edge.Weight ;

                    if(tempWeight < targetPath.Weight)
                    {
                        targetPath.Weight = tempWeight ;
                        targetPath.PassedIDList.Clear() ;

                        for(int i=0 ;i<curPath.PassedIDList.Count ;i++)
                        {
                            targetPath.PassedIDList.Add(curPath.PassedIDList[i].ToString()) ;
                        }

                        targetPath.PassedIDList.Add(curNode.ID) ;
                    }
                }

                //标志为已处理
                planCourse[curNode.ID].BeProcessed = true ;
                //获取下一个未处理节点
                curNode = this.GetMinWeightRudeNode(planCourse ,nodeList ,originID) ;
            }
            #endregion
            
            //表示规划结束
            return this.GetResult(planCourse ,destID) ;                
        }
        #endregion

        #region private method
        #region GetResult
        //从PlanCourse表中取出目标节点的PassedPath,这个PassedPath即是规划结果
        private RoutePlanResult GetResult(PlanCourse planCourse ,string destID)
        {
            PassedPath pPath = planCourse[destID]  ;            

            if(pPath.Weight == int.MaxValue)
            {
                RoutePlanResult result1 = new RoutePlanResult(null ,int.MaxValue) ;
                return result1 ;
            }
            
            string[] passedNodeIDs = new string[pPath.PassedIDList.Count] ;
            for(int i=0 ;i<passedNodeIDs.Length ;i++)
            {
                passedNodeIDs[i] = pPath.PassedIDList[i].ToString() ;
            }
            RoutePlanResult result = new RoutePlanResult(passedNodeIDs ,pPath.Weight) ;

            return result ;            
        }
        #endregion

        #region GetMinWeightRudeNode
        //从PlanCourse取出一个当前累积权值最小,并且没有被处理过的节点
        private Node GetMinWeightRudeNode(PlanCourse planCourse ,ArrayList nodeList ,string originID)
        {
            double weight = double.MaxValue ;
            Node destNode = null ;

            foreach(Node node in nodeList)
            {
                if(node.ID == originID)
                {
                    continue ;
                }

                PassedPath pPath = planCourse[node.ID] ;
                if(pPath.BeProcessed)
                {
                    continue ;
                }

                if(pPath.Weight < weight)
                {
                    weight = pPath.Weight ;
                    destNode = node ;
                }
            }

            return destNode ;
        }
        #endregion
        #endregion
    }

相关文章:

  • 2021-11-04
  • 2021-08-19
  • 2021-08-15
  • 2021-10-18
  • 2022-02-19
  • 2021-05-17
猜你喜欢
  • 2021-04-18
  • 2022-12-23
  • 2021-07-17
  • 2022-12-23
  • 2021-12-24
  • 2021-12-24
  • 2021-12-24
相关资源
相似解决方案