SharpICTCLAS分词系统简介(5)NShortPath-2

本文详细阐述了N-最短路径的概念、计算方法,并通过实例展示了如何求解2-最短路径,包括数据表示、运算过程、具体实现及最终输出。通过实例分析,读者能够理解N-最短路径与1-最短路径的区别,以及如何使用特定算法求解更复杂的路径问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址:http://www.cnblogs.com/zhenyulu/articles/672442.html

在了解了1-最短路径的计算方式后,我们看看N-最短路径的计算。

N-最短路径的计算方式与1-最短路径基本相同,只是在记录所有可达路径时,要保留最短的前N个结果。让我们仍然以上篇文章的案例来看看如何实现N-最短路径的运算。

1、数据表示

这里我们仍然沿用前文例子,对下图求N-最短路径,每条边的权重已经在图中标注出来了。

(图一)

2、运算过程

仍然象1-最短路径一样,计算出每个结点上可达N-最短路的PreNode。我们这里以2-最短路径为例:

1)首先计算出每个结点上所有可达路径的可能路径长度并按从小到大排序。

2)根据排序结果取前2种路径长度并分别记录进各结点的PreNode队列。如下图:

(图二)

在该图中,到达1号、2号、3号结点的路径虽然有多条,但长度只有一种长度,但到达4号“D”结点的路径长度有两种,即长度可能是3也可能是4,此时在“最短路”处(index=0)记录长度为3时的PreNode,在“次短路”处(index=1)处记录长度为4时的PreNode,依此类推。

值得注意的是,此时用来记录PreNode的坐标已经由前文求“1-最短路径”时的一个数(ParentNode值)变为2个数(ParentNode值以及index值)。

如图二所示,到达6号“末”结点的次短路径由两个ParentNode,一个是index=0中的4号结点,一个是index=1的5号结点,它们都使得总路径长度为6。

3、具体实现

在具体实现上述算法时,首先要求得所有可能路径的长度,这在SharpICTCLAS中是通过一个EnQueueCurNodeEdges方法实现的,上篇文章给出了它的简化版本的代码,这里将完整的求N-最短路径的EnQueueCurNodeEdges方法代码放上来:

程序
//==================================================================== 
// 将所有到当前结点(nCurNode)可能的边根据eWeight排序并压入队列 
//==================================================================== 
private  static  void EnQueueCurNodeEdges( ref CQueue queWork,  int nCurNode) 

    int nPreNode; 
    double eWeight; 
   ChainItem<ChainContent> pEdgeList; 

   queWork.Clear(); 
   pEdgeList = m_apCost.GetFirstElementOfCol(nCurNode); 

    // Get all the edges 
    while (pEdgeList !=  null && pEdgeList.col == nCurNode) 
   { 
      nPreNode = pEdgeList.row;   //  很特别的命令,利用了row与col的关系  
      eWeight = pEdgeList.Content.eWeight;  //Get the eWeight of edges 

       for ( int i = 0; i <  m_nValueKind; i++) 
      { 
          // 第一个结点,没有PreNode,直接加入队列 
          if (nPreNode == 0) 
         { 
            queWork.EnQueue( new QueueElement(nPreNode, i, eWeight)); 
             break
         } 

          // 如果PreNode的Weight == Predefine.INFINITE_VALUE,则没有必要继续下去了 
          if (m_pWeight[nPreNode - 1][i] == Predefine.INFINITE_VALUE) 
             break

         queWork.EnQueue( new QueueElement(nPreNode, i, eWeight + m_pWeight[nPreNode - 1][i])); 
      } 
      pEdgeList = pEdgeList.next; 
   } 
}

这里的m_nValueKind就是你希望N-最短路径保留几种路径的结果。

当m_nValueKind=2时,我们求得了2-最短路径,路径长度有两种,分别长度为5和6,而路径总共有6条,如下:

最短路径:

  • 0, 1, 3, 6,
  • 0, 1, 2, 3, 6,
  • 0, 1, 2, 4, 5, 6,

========================

次短路径

  • 0, 1, 2, 4, 6,
  • 0, 1, 3, 4, 5, 6,
  • 0, 1, 2, 3, 4, 5, 6,

4、求解N-最短路径

N-最短路径的最终输出与上篇文章完全一致,仍然是借助堆栈完成的。只不过根据index的取值的不同,分多次完成压栈与出栈的操作而已。此处就不再重复,感兴趣的可以再看看上一篇文章。

 

  • 小结

1)N-最短路径中用来记录PreNode的坐标由前文求“1-最短路径”时的一个数(ParentNode值)变为2个数(ParentNode值以及index值)。

2)N-最短路径并不意味着求得得路径只有N条。

3)文中只演示了2-最短路径,但可以推广到N-最短路径。程序求得的3-最短路径中,最长的路径为:(0, 1, 3, 4, 6)与(0, 1, 2, 3, 4, 6),它们的长度都是7。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值