ICTCLAS代码学习笔记之CNShortPath类

来源:互联网 发布:深度触网 知乎 编辑:程序博客网 时间:2024/06/05 14:56
N-最短路径算法类,这个是核心算法之一,用于进行中文词语的粗分,算法的相关理论可参见论文《基于N-最短路方法的中文词语粗分模型》。
类中包含的几个成员变量依次说明如下:
m_apCost是一个动态数组的指针,用于记录词图中的各结点及其路径的权重值;
m_nValueKind是无符号整型数据,用于记录共生成几个结果,一般为1,也可能生成多组结果;
m_nVertex是无符号整型数据,用于记录词图中结点的个数,取值为词图的行列值中较大的一个再加1。
m_pParent和m_pWeight都是二维数组指针,前者用于记录每组结果中的每个结点的前驱后者记录N个最短路径值。例如传入的词图为5*4,只要求生成一组结果,则m_pParent为[5][1]的Cqueue二维数组,而m_pWeight为[5][1]的double二维数组。前者记录每个结点处的父结点及相关信息,后者记录相应的权重值。
最短路径算法主要调用的函数是int CNShortPath::ShortPath()。这个函数根据成员变量m_apCost中记录的词图中的各个边的相关信息计算出路径并保存在m_pParent和m_pWeight中。
从第一个结点开始(0结点为起始结点),对每个结点
读取列值为当前结点的边链表,该边的行值记为前一个结点,该边的value值记为权重。然后产
生所需要的m_nValueKind个结果,如果前一个结点已经是起始结点(为0)则将这个结点及其当前权重值压入队列;如果还没有回到起始结点则将这个结点以及当前权重与前一个结点的权重值相加的新权重值压入。需要注意的是,如果前一个结点已经无路可走,即权重为无限值INFINITE_VALUE则跳出生成过程。生成结果之后,对当前结点的前一个结点的权重值都置为无限值,然后按权重从小到大依次取出每个结点,如果前一个位置的权重值为无限即没有被走到过则置为当前读出的这个权值,否则如果前一个位置的权重值比读出的这个还要小,那就记录到后面去。记录权值的同时不要忘记还要把前驱结点记录到m_pParent中去。这里要说明的另一点是,由于队列中的结果是按权值从小到大排序的,因此不会再现已记录的结果比后面的结果权值大的情况。相等的情况也会在前驱表中有相应的记录。
GetPaths是另一个重要的函数,虽然其类型为private的只供内部使用。函数的声明如下:
void CNShortPath::GetPaths(unsigned int nNode,unsigned int nIndex,int **nResult,bool bBest)
第一个参数是结点id,第二个参数是结果索引,第三个参数是用来存储路径的二维数组,bBest为真时只取最好结果忽略其他。算法是回溯从nNode处往前找到起点的路径。
首先将传入的nNode及其结果索引nIndex压入队列,从这个结点开始往前走,即每次读当前结点的父结点中的第一个侯选(即前驱结点中的第一个候选),只要有前驱就更新当前结点并注意将合法的前驱结点及其索引值保存起来,直到到达起始始点,注意这时是浏览状态。如果最后得到的这个结点是起始结点(结点值为0)则认为找到了一条路径,记录这条路径在nResult中。达到最大结果个数或者只要求一个最好结果就返回,否则回溯找下一条路径,直到队列为空或者达到了最大结果个数。
Output用于将路径结果写入二维数组中,如果结点数不超过2,那么只有唯一的路径,即只生成了一个结果;否则的话从尾结点回溯调用getpaths来获得路径值。最终要几个结果就循环几次,需要注意的一个地方是参数bBest用于控制是否只生成一个最优结果即返回。同样,每个结果中的路径候选不超过MAX_SEGMENT_NUM(10)个。
CshortPath类总结:
利用已有的词图信息求最短路径,是改进的最短路径算法。核心的两个函数是GetPaths和ShortPath。
原创粉丝点击