dance links 中文版分析和总结.docxVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
精确覆盖问题 dancelinks 中文版 /works/dlxcn/ 给定一个由 0 和 1 组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个 1?例如, 下面这个矩阵 就包含了这样一个集合(第 1,4,5 行)。我们把列想象成全集的一些元素,而行看作全集的一些子集; 或者我们可以把行想象成全集的一些元素,而把列 看作全集的一些子集;那么这个问题就是要求寻找一批元素,它们与每个子集恰好有一个交点。不管怎么说,这都是一个很难的问题,众所周知,当每行恰包含 3 个 1 时,这是个一个 NP-完全问题。自然,作为首选的算法就是回溯了。 解决精确覆盖问题。对于接下来的非确定性算法,由于我们没有想到更好的名字,我们将称之为 X 算法, 它能够找到由特定的 01 矩阵 A 定义的精确覆盖问题的所有解。X 算法是实现试验——错误这一显而易见的方法的一段简单的语句(确实,一般来说,我想不到别的合理的方法来完成这个工作)。 如果 A 是空的,问题解决;成功终止。否则,选择一个列 c(确定的)。 选择一个行 r,满足 A[r,c]=1 (不确定的)。把 r 包含进部分解。 对于所有满足 A[r,j]=1 的 j, 从矩阵 A 中删除第 j 列; 对于所有满足 A[i,j]=1 的 i, 从矩阵 A 中删除第 i 行。 在不断减少的矩阵 A 上递归地重复上述算法。 对 r 不确定的选择意味着这个算法本质上把自身复制给许多独立的子算法;每个子算法继承了当前的矩阵 A,但在考虑不同行r 的同时对其进行了删减。如果 列 c 全部是 0,那么就不存在子算法而且这个过程会不成功地终止。很自然地,所有的子算法搭建了一棵搜索树,其根部就是初始问题,并且第k 层的每个子算法对 应 k 个选择的行。回溯就是前序遍历这棵树的过程,即“深度优先”。 DancingLinks DancingLinks 是 Knuth 教授在近几年来写的一篇文章,是一类搜索问题的通用优化。它主要利用双向十字链表来存储稀疏矩阵,来达到搜索中的优化。在搜索问题 中,矩阵会随着递归的加深会变得越来越稀疏,这种情况下用 dancelinks 来存储矩阵,往往会达到很好的效果。 核心代码: 对于熟悉双向链表的人,一定不会陌生: 这两句话时将 x 从链表中删除。但很少有人知道下面两句: L[R[x]]=L[x] R[L[x]]=R[x] L[R[x]]=x R[L[x]]=x (借助图形和手工模拟,这些语句很容易理解 :)) 这两句会将已经删除的节点x 重新添加回双向链表中。是不是非常神奇。我们在链表中删除,只是进行一个标记,并不真正进行清空内存的操作。可能这不是好的编程习惯,你可能会认为内存泄露,但在这里,我们就是要这种效果。 给一个 0、1 矩阵,现在要选择一些(最少)行,使得每列有且仅有一个 1,即精确覆盖。或者,选择一些(最少)行,使得每列至少有一个 1,即重复覆盖。 这两个问题都是 NP 问题,可以用搜索解决,DLX 可以大大加快搜索速度。 精确覆盖: 首先选择当前要覆盖的列(含 1 最少的列),将该列和能够覆盖到该列的行全部去掉,再枚举添加的方法。枚举某一行r,假设它是解集中的一个,那么该行所能覆 盖到的所有列都不必再搜,所以删除该行覆盖到的所有列,又由于去掉的列相当于有解,所以能够覆盖到这些列的行也不用再搜,删之。 重复覆盖: 首先选择当前要覆盖的列(同上),将该列删除,枚举覆盖到该列的所有行:对于某一行 r,假设它是解集中的一个,那么该行所能覆盖到的列都不必再搜,所以删除该行覆盖到的所有列。注意此时不用删去覆盖到这些列的行,因为一列中允许有多个 1。这里有一个 A*的优化:估价函数 h 意义为从当前状态最好情况下需要添加几条边才能覆盖。 (以上两片文章均来源于网络)

文档评论(0)

hao187 + 关注
官方认证
文档贡献者

该用户很懒,什么也没介绍

认证主体武汉豪锦宏商务信息咨询服务有限公司
IP属地上海
统一社会信用代码/组织机构代码
91420100MA4F3KHG8Q

1亿VIP精品文档

相关文档