路径规划(最短路径)算法C#实现[转]

关于路径规划(最短路径)算法的背景知识,大家可以参考《C++算法--图算法》一书。
    该图算法描述的是这样的场景:图由节点和带有方向的边构成,每条边都有相应的权值,路径规划(最短路径)算法就是要找出从节点A到节点B的累积权值最小的路径。
    首先,我们可以将“有向边”抽象为Edge类:
     public   class  Edge
    
{
        
public string StartNodeID ;
        
public string EndNodeID   ;
        
public double Weight      ; //权值,代价        
    }

节点则抽象成Node类,一个节点上挂着以此节点作为起点的“出边”表。
      public   class  Node
    
{
        
private string iD ;
        
private ArrayList edgeList ;//Edge的集合--出边表

        
public Node(string id )
     
{
            
this.iD = id ;
            
this.edgeList = new ArrayList() ;
        }


        property
property
    }

在计算的过程中,我们需要记录到达每一个节点权值最小的路径,这个抽象可以用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 ;
        }


        
property
    }

另外,还需要一个表PlanCourse来记录规划的中间结果,即它管理了每一个节点的PassedPath。
     /// <summary>
    
/// PlanCourse 缓存从源节点到其它任一节点的最小权值路径=》路径表
    
/// </summary>

     public   class  PlanCourse
    
{
        
private Hashtable htPassedPath ;    

        
ctor

        
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()
        
{            
        }


        
Paln

        
private method
    }
下面给出一个简单示例:
RoutePlanner.Plan 过程详解:
(1)用一张表(PlanCourse)记录源点到任何其它一节点的最小权值,初始化这张表时,如果源点能直通某节点,则权值设为对应的
   边的权,否则设为double.MaxValue
(2)选取没有被处理并且当前累积权值最小的节点TargetNode,用其边的可达性来更新到达其它节点的路径和权值(如果其它节点
   经此节点后权值变小则更新,否则不更新),然后标记TargetNode为已处理
(3)重复(2),直至所有的可达节点都被处理一遍。
(4)从PlanCourse表中获取目的点的PassedPath,即为结果。
[STAThread]
        
static   void  Main( string [] args)
        
{
            ArrayList nodeList 
= new ArrayList() ;
 
            
//***************** B Node *******************
            Node aNode  = new Node("A") ;
            nodeList.Add(aNode) ;
            
//A -> B
            Edge aEdge1 = new Edge() ;
            aEdge1.StartNodeID 
= aNode.ID ;
            aEdge1.EndNodeID   
= "B" ;
            aEdge1.Weight      
= 10 ;
            aNode.EdgeList.Add(aEdge1) ;
            
//A -> C
            Edge aEdge2 = new Edge() ;
            aEdge2.StartNodeID 
= aNode.ID ;
            aEdge2.EndNodeID   
= "C" ;
            aEdge2.Weight      
= 20 ;
            aNode.EdgeList.Add(aEdge2) ;
            
//A -> E
            Edge aEdge3 = new Edge() ;
            aEdge3.StartNodeID 
= aNode.ID ;
            aEdge3.EndNodeID   
= "E" ;
            aEdge3.Weight      
= 30 ;
            aNode.EdgeList.Add(aEdge3) ;

            
//***************** B Node *******************
            Node bNode  = new Node("B") ;
            nodeList.Add(bNode) ;
            
//B -> C
            Edge bEdge1 = new Edge() ;
            bEdge1.StartNodeID 
= bNode.ID ;
            bEdge1.EndNodeID   
= "C" ;
            bEdge1.Weight      
= 5 ;
            bNode.EdgeList.Add(bEdge1) ;
            
//B -> E
            Edge bEdge2 = new Edge() ;
            bEdge2.StartNodeID 
= bNode.ID ;
            bEdge2.EndNodeID   
= "E" ;
            bEdge2.Weight      
= 10 ;
            bNode.EdgeList.Add(bEdge2) ;

            
//***************** C Node *******************
            Node cNode  = new Node("C") ;
            nodeList.Add(cNode) ;
            
//C -> D
            Edge cEdge1        = new Edge() ;
            cEdge1.StartNodeID 
= cNode.ID ;
            cEdge1.EndNodeID   
= "D" ;
            cEdge1.Weight      
= 30 ;
            cNode.EdgeList.Add(cEdge1) ;

            
//***************** D Node *******************
            Node dNode  = new Node("D") ;
            nodeList.Add(dNode) ;

            
//***************** C Node *******************
            Node eNode  = new Node("E") ;
            nodeList.Add(eNode) ;
            
//C -> D
            Edge eEdge1        = new Edge() ;
            eEdge1.StartNodeID 
= eNode.ID ;
            eEdge1.EndNodeID   
= "D" ;
            eEdge1.Weight      
= 20 ;
            eNode.EdgeList.Add(eEdge1) ;


            RoutePlanner planner 
= new RoutePlanner() ;
            RoutePlanResult result 
= planner.Paln(nodeList ,"A" ,"D") ;

            planner 
= null ;
        }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值