python自然语言处理-广度优先搜索

来源:互联网 发布:wave动作数据mmd 编辑:程序博客网 时间:2024/06/11 02:39

一.概念

    在前面的例子中,我们创建了收集从凯文.贝肯开始的维基百科词条链接的爬虫,最后存储在数据库里。这个游戏体现了一种从一个页面指向另一个页面的链接路径选择问题。这个上篇文章找出一个单词到另一个单词的路径问题是一样的。这类问题被称为有向图(direct graph)问题,其中A-->B连通,并不意味着B-->A同样连通。单词“football”后面经常跟着“player”,但是单词“player”后面却很少跟着“football”。虽然“凯文贝肯”的维基百科词条连接到他的老家费城(Philadelphia),但是费城的维基百科词条里却没有连接到他的连接。

    相反,原来的凯文贝肯六度分割游戏是一个无向图(undirected graph)问题。例如,凯文贝肯和茱莉亚罗伯茨(Julia Roberts)共同演过电影《别闯阴阳界》(Flatliners,1990),因此,凯文贝肯词条通过《别闯阴阳界》的维基百科词条会连接到茱莉亚罗伯茨词条,而茱莉亚罗伯茨也会通过《别闯阴阳界》连接到凯文贝肯词条,两者的关系是相互的(也就是没有方向性)。在计算机科学中,无向图问题比有向图问题不太常见,两者都属于计算难题。

  虽然解决这两类问题和对应的多个分支问题的方法有很多,但是在寻找有向图的最短路径问题中,即找出维基百科中凯文贝肯词条和其他词条之间最短路径的方法中,效果最好且最常用的一种方法就是广度搜索算法(breadth-first search)。

   广度优先搜索算法的思路就是优先搜寻直接连接到起始页的所有链接(而不是找到一个链接就纵向深入搜索)。如果这些链接不包含目标页面(你想要找到词条),就对第二层的链接-连接到起始页的页面的所有链接--进行搜索。这个过程不断重复,知道达到搜索深度限制(本例中使用的层数限制是6)或者找到目标页面为止。

二.实例

   用前面获得的链接数据表,实现一个广度有限搜索算法,代码如下:

empty
   上述代码中函数getLinks和constructDict()是辅助函数,用来从数据库里获取给定页面的链接,然后把链接转换成字典。主函数searchDepth会递归执行,同时构建和搜索链接树,一次搜索一层。其运行规则如下:
  • 如果递归限制已经到达(即程序已经调用过很多次),就停止搜索,返回结果;
  • 如果函数获取的链接字典是空,就对当前页面的链接进行搜索。如果当前页面也没有链接,就返回空链接字典
  • 如果当前页面包含我们搜索的页面链接,就把页面ID复制到递归的栈顶,然后抛出一个异常,显示页面已经找到。递归过程会打印出当前的页面ID,然后后抛出异常显示页面已经找到,最终打印在屏幕上的就是一个完整的额ID路径列表。
  • 如果链接没有找到,把递归限制减一,然后调用函数搜索下一层链接。

原创粉丝点击