hanlp中的N最短路径分词

N-最短路径 是中科院分词工具NLPIR进行分词用到的一个重要算法,张华平、刘群老师在论文《基于N-最短路径方法的中文词语粗分模型》中做了比较详细的介绍。该算法算法基本思想很简单,就是给定一待处理字串,根据词典,找出词典中所有可能的词,构造出字串的一个有向无环图,算出从开始到结束所有路径中最短的前N条路径。因为允许相等长度的路径并列,故最终的结果集合会大于或等于N。

根据算法思想,当我们拿到一个字串后,首先构造图,接着针对图计算最短路径。下面以一个例子“他说的确实在理”进行说明,开始为了能够简单说明,首先假设图上的边权值均为1。 

先给出对这句话的3-最短路(即路径最短的前3名, 因为有并列成分, 所以可能候选路径大于3)径求解过程图: 

从节点4开始, 因为4是第一个出现多个前驱节点的


 

 

首先看图中上方,它是根据一个已有词典构造出的有向无环图。它将字串分为单个的字,每个字用图中相邻的两个结点表示,故对于长度为n的字串,需要n+1个结点。两节点间若有边,则表示两节点间所包含的所有结点构成的词,如图中结点2、3、4构成词“的确”。
图构造出来后,接下来就要计算最短路径,N-最短路径是基于Dijkstra算法的一种简单扩展,它在每个结点处记录了N个最短路径值与该结点的前驱,具体过程如上图中下方列表。Table(4)表示位于结点4时的最短路径情况,表示从结点0到4有两条路径,长度为3的路径前驱为2;长度为4的路径前驱为3。前驱括号里面第二个数表示对相同前驱结点的区分,如(4,1)、(4,2)。由列表可知,该字串的3-最短路径结果集合为{5,5,6,6,7}。

当然,在实际情况中,权值不可能都设为1的,否则随着字串长度n和最短路径N的增大,长度相同的路径数将会急剧增加。为了解决这样的问题,我们需要通过某种策略为有向图的边赋权重,很自然的想法就是边的权重就是该词出现的可能性。

 

 

 

 

NShortPath的基本思想是Dijkstra算法的变种,拿1-最短路来说吧,先Dijkstra求一次最短路,然后沿着最短路的路径走下去,只不过在走到某个节点的时候,检查到该节点在路径上的下一个节点是否还有别的路到它(从PreNode查),如果有,就走这些别的路中的没走过第一条(它们都是最短路上的途径节点)。然后推广到N-最短路,N-最短路中PreNode有N个,分别对应n-最短路时候的PreNode,就这么简单。

图解

再谈PreNode的准备

需要为每个顶点维护一个最小堆,最小堆里储存的是边的花费,每条边的终点是这个顶点。还需要维护到每个顶点的前N个最小路径的花费:

回忆一下Dijkstra求最短路的时候,我们只需记录一个最短路的累计花费就行了

这与此处的N-最短路径显著不同。

在遍历图的时候,与Dijkstra最短路径不同,N-最短路径从第二个节点开始,需要将当前节点可能到达的边根据累积第i短长度+该边的长度之和排序记录到PreNode队列数组中,排序由CQueue完成的。

然后从CQueue出队,这样路径长度就是升序了,按顺序更新 weightArray[当前节点][第几短路]就行了。

另外CQueue是一个不同于普通队列的队列,它维护了一个当前指针(下图的蓝色部分),这个蓝色指针在求解第i短路径的时候会用到。

 

 

假定看到这里,算法已经计算出了正确的PreNode队列,下面讨论如何从PreNode中找出N最短路径的确切途经节点集合。

1-最短路径的求解

整个计算过程维护了一个路径栈,对于上图来说,

1)首先将最后一个元素压入栈(本例中是6号结点),什么时候这个元素弹出栈,什么时候整个任务结束。

2)对于每个结点的PreNode队列,维护了一个当前指针,初始状态都指向PreNode队列中第一个元素。这个指针是由CQueue维护的,严格来讲不属于算法关心的问题。

3)从右向左依次取出PreNode队列中的当前元素(当前元素出队)并压入栈,并将队列指针重新指向队列中第一个元素。如上图:6号元素PreNode是3,3号元素PreNode是1,1号元素PreNode是0。

4)当第一个元素压入栈后,输出栈内容即为一条队列。本例中0, 1, 3, 6便是一条最短路径。

5)将栈中的内容依次弹出,每弹出一个元素,就将当时压栈时该元素对应的PreNode队列指针下移一格。如果到了末尾无法下移,则继续执行第5步(也就是继续出栈),如果仍然可以移动,则执行第3步。

对于本例,先将“0”弹出栈,在路径上0的下一个是1,得出该元素对应的是1号“A”结点的PreNode队列,该队列的当前指针已经无法下移,因此继续弹出栈中的“1” ;同理该元素对应3号“C”结点,因此将3号“C”结点对应的PreNode队列指针下移。由于可以移动,因此将队列中的2压入队列,2号“B”结点的PreNode是1,因此再压入1,依次类推,直到0被压入,此时又得到了一条最短路径,那就是0,1,2,3,6。如下图:

 

 

再往下,0、1、2都被弹出栈,3被弹出栈后,由于它对应的6号元素PreNode队列记录指针仍然可以下移,因此将5压入堆栈并依次将其PreNode入栈,直到0被入栈。此时输出第3条最短路径:0, 1, 2, 4, 5, 6。如下图:

 

 

输出完成后,紧接着又是出栈,此时已经没有任何栈元素对应的PreNode队列指针可以下移,于是堆栈中的最后一个元素6也被弹出栈,此时输出工作完全结束。我们得到了3条最短路径,分别是:

0, 1, 3, 6,

0, 1, 2, 3, 6,

0, 1, 2, 4, 5, 6,

推广到N-最短路

N-最短路中PreNode有N个,分别对应n-最短路时候的PreNode,也就是当前路径是第n短的时候,当前节点对应的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。

当N=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,

 

 

文章来源于random-walk的博客

转载于:https://www.cnblogs.com/tiantiankong/p/10150152.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/364523.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎么在ReactNative里面使用Typescript

今天来搞一搞怎么搭建一个可以使用Typescript的ReactNative环境好吧,一句废话不多说,直接开始好吧 1.全局安装create-react-native-app yarn global add create-react-native-app 2.create-react-native-app 你的项目名称 例如:create-r…

如何不使用Java 8默认方法

警告:一旦阅读,您将无法看不到它 我在上一篇博客文章中讨论了默认方法的多重继承,以及它们在编译和运行时的行为。 这周,我将研究如何使用默认方法进行真正的继承,实际上,默认方法并不是为这种方法而设计的…

linux mint 18.3 内核,Linux Mint 18.3 “Sylvia” Cinnamon正式发布上线

Linux Mint创建者Clement Lefebvre今天宣布Linux Mint 18.3 “"Sylvia” Cinnamon和MATE Beta版本正式发布和上线。Linux Mint 18.3基于Ubuntu 16.04 LTS(Xenial Xerus),搭载Linux Kernel 4.10内核,将持续到2021年获得更新和安全补丁。  Linux Mi…

浏览器兼容问题及解决方案

1.图片间隙 A)div中的图片间隙&#xff08;该bug出现在IE6以及更低版本当中&#xff09; 描述&#xff1a;在div中插入图片时&#xff0c;图片会将div下方撑大三像素 hack1&#xff1a;将</div>和<img>写在一行上 hack2&#xff1a;将<img>转化为块状元素&am…

Java 8星期五:Java 8的阴暗面

在Data Geekery &#xff0c;我们喜欢Java。 而且&#xff0c;由于我们真的很喜欢jOOQ的流畅的API和查询DSL &#xff0c;我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 Java 8星期五 每个星期五&#xff0c;我们都会向您展示一些不错的教程风格的Java 8新功能&#…

SQL,HQL,CQL,JPQL了解

SQL&#xff08;Structured Query Language&#xff09; 是关系数据库查询语言。from后面跟的是“表名”&#xff0c;where后用“表中字段”做条件 HQL&#xff08;Hibernate Query Language&#xff09; 是面向对象的查询&#xff0c;from后面跟的是“表名”&#xff0c;where…

报错集锦

1.在node后端使用express中的multer中间件来实现文件上传时报错 node multer 报错Unexpected field 1 var expressrequire(express); 2 3 var routerexpress.Router(); 4 5 var uploadrequire(...) router.post(/upload,upload.single(fileid)); 原因&&解决&#xff…

shipyard-----------docker容器的可视化管理

shipyard是什么&#xff0c;由题目就可知&#xff0c;是一个对docker进行管理的可视化界面 照此步骤就能完成对shipyard搭建 <ip-of-host>内容要修改成你的docker0的IP地址&#xff0c;不知道的话就ifconfig就好了 如果搭建不成功则是防火墙未开放4001端口&#xff1a;su…

virtualbox怎么共享文件夹 linux,Virtualbox中Ubuntu设置共享文件夹

1、安装增强功能包(Guest Additions)VirtualBox中&#xff0c;选择”设备” -> “安装增强功能”。命令行输入&#xff1a;$ cd /media/VBoxGuestAdditions_4.3.8_RC1$ sudo ./VboxLinuxAdditions.run开始安装工具包&#xff0c;安装完毕后重启虚拟机。2、配置共享文件夹Vir…

Eclipse对Java(TM)8的官方支持

Java开发工具&#xff08;JDT&#xff09;项目的项目负责人Dani Megert今天早些时候宣布了此声明 &#xff1a; Eclipse顶级项目非常自豪地宣布正式支持Java™8。从I20140318-0830开始&#xff0c;所有的Luna&#xff08;4.4&#xff09;构建都包含Eclipse对Java™8的支持。对…

Quartz.net使用笔记

一、需求场景&#xff1a;每天固定时间执行某个行为/动作。 一开始想用定时器&#xff0c;后来无意间发现了这个插件&#xff0c;感觉功能太强大了&#xff0c;完美解决了我的问题。 二、下载地址&#xff1a;https://www.quartz-scheduler.net/ 也可以在项目中直接使用nugut进…

JS里面的懒加载(lazyload)

懒加载技术(简称lazyload)并不是新技术, 它是js程序员对网页性能优化的一种方案.lazyload的核心是按需加载 涉及到图片&#xff0c;falsh资源 , iframe, 网页编辑器(类似FCK)等占用较大带宽&#xff0c;且这些模块暂且不在浏览器可视区内,因此可以使用lazyload在适当的时候加载…

远程拷贝 linux服务器,linux scp 服务器远程拷贝(示例代码)

一、将本机文件复制到远程服务器上#scp /home/administrator/news.txt [email protected]:/etc/squid/home/administrator/ 本地文件的绝对路径news.txt 要复制到服务器上的本地文件root 通过root用户登录到远程…

对偶图小结

前提 通常对偶图建立在平面图之上 平面图&#xff1a;单边除端点外无交点 解决范围 求平面图的最大流 做法 平面图显然在边的基础上分成了若干个块&#xff0c;每个块由一个结点来维护 在边缘出与源点汇点联通&#xff0c;中间处结点之间相互联通 连的边容量为该边穿过原图的边…

将Java 8支持添加到Eclipse Kepler

是否想向开普勒添加Java 8支持&#xff1f; Java 8尚未加入我们的标准下载包中 。 但是您可以将其添加到现有的Eclipse Kepler软件包中。 我有运行Java 8的三种不同的Eclipse安装&#xff1a; 面向Java开发人员的Eclipse IDE的全新Kepler SR2安装&#xff1b; 为RCP / RAP开…

CSS基础【1】:体验CSS

CSS起源 web的衰落&#xff1a;在 web 早期&#xff08;1990-1993&#xff09;,html是一个很局限的语言。几乎完全由用于描述段落&#xff0c;超链接&#xff0c;列表和标题的结构化元素组成。随着万维网的出现&#xff08;用户交互体验的加强&#xff09;&#xff0c;对 html …

JS中的兼容问题总结

今天总结总结在JS里面遇到的兼容性问题 1.获取滚动距离的兼容性问题: document.documentElement.scrollTop || document.body.scrollTop &#xff08;兼容IE&#xff09; 2.获取非行间样式 getComputedStyle(元素,false)[attr] || 元素.currentStyle[attr] 3.索引…

linux网络唤醒,如何在Ubuntu Server 18.04中启用网络唤醒(WOL)

网络唤醒(WOL)是一种行业标准协议&#xff0c;用于远程唤醒服务器。如果您管理着很多设备&#xff0c;因此不需要为了唤醒服务器而去数据中心。启用允许您远程执行此操作的功能&#xff0c;这样您可以更高效地工作。Ubuntu 系统默认没有启用WOL&#xff0c;所以我们要设置它。我…

php 分页处理

1、利用bootstrap的css框架的前提下&#xff0c;封装个Php的分页框架 命名为test.php&#xff0c;具体代码如下 1 <?php2 class Pagination3 {4 private $cfg;5 private $content ; //分页导行条内容部份6 7 public function __constr…

ActiveMQ –经纪人网络解释

目的 这个由7部分组成的博客系列将分享有关如何创建ActiveMQ代理网络以实现高可用性和可伸缩性的信息。 为什么要建立经纪人网络&#xff1f; ActiveMQ消息代理是企业中消息传递基础结构的核心组件。 它需要高度可用并且可以动态伸缩&#xff0c;以促进具有不同容量需求的动态…