dancing links完整中文翻译版1.pdfVIP

  • 17
  • 0
  • 约3.44万字
  • 约 28页
  • 2018-06-01 发布于江苏
  • 举报
dancing links完整中文翻译版1

Dancing Links 中文版 (DLXcn) Donald E.Knuth, Stanford University 翻译 武汉武钢三中 吴豪 更正 排版 上海交通大学 隋清宇(sqybi) 目录 正文  精确覆盖问题  解决精确覆盖问题  舞蹈步骤  效率分析  应用于六形组  一个失败的试验  应用于四形条  应用于皇后问题  结语  致谢  历史注记  程序 参考资料  补注 译者的话  译者隋清宇的话  译者吴豪的话  感谢 声明及其它 正文 我写这篇论文的目的,是觉得这个简单的程序技巧理应得到广泛认可。假设 x 指向双向链的一个节点;L[x]和 R[x]分别表示 x 的前驱节点和后继节点。每个 程序员都知道如下操作: L[R[x]] ← L[x], R[L[x]] ← R[x] (1) 是将 x 从链表删除的操作;但是只有少数程序员意识到如下操作: L[R[x]] ← x, R[L[x]] ← x (2) 是把 x 重新链接到双向链中。 当然,指出这种操作以后,这个结果是显然的。但是,当我真正认识到操作(2) 的作用以后,我突然感到了定义“啊哈”这个词语时候的感觉,因为,L[x]和 R[x]的值在x 从链表中删除以后早已没有了它原来的语义。确实,一个精心设计 的程序在x 被删除后会通过把 L[x],R[x]赋值为 x 或者赋值为空值(null)来清 理掉这些不用的数据结构。而让一个链外的对象指向链本身有时具有潜在的危险 性。例如,指针就可以干扰垃圾回收机制的运作。 那么是什么关于操作(2)的研究促使我写一整篇论文来讨论这个问题呢?当x 从链表删除以后;为什么还要把它放回链表中?嗯,我承认,数据结构的更新通 常来说是永久性的。但是非永久性的更新也时常发生。例如,在一个交互性的程 序中,用户很可能想撤销他所做的一个或一系列操作,恢复到先前的状态。另一 个典型的应用是在回溯程序 (backtrack programs ) [16]里,回溯程序枚举约束 集合里的所有解。回溯,也叫深度优先搜索 (depth-first search),在之前的 论文中曾经讨论到。 操作(2)的观点是Hitotumatu 和 Noshita [22]于 1979 年提出的。他们提出 Dijkstra 提出的著名的解决 N 皇后问题 [6,第 72-82 页]的算法在使用了这个 技巧后,程序的速度比不使用几乎快了 2 倍。 Floyd 关于回溯和非确定性算法 [11]之间关联的优雅论述中包含详细的数据结 构更新与恢复的算法(谁能够提供这句话的准确翻译?——译者)。通常来说, 回溯程序可以被认为是一种搜索,所要做的就是缩小这个任务需要搜索的范围, 同时组织好用于控制搜索流程和决策的数据。对于多步的问题,解决问题的每一 步操作,都将改变剩余需要解决的问题。 简单情况下,我们可以考虑维护一个栈,用来保存当前搜索树节点之前的所有相 关状态信息,但是这个任务的拷贝动作需要耗时太多。因此,我们通常选用全局 数据结构。这样无论搜索进行到何种程度,它都会保留相关状态信息,并且当搜 索回溯的时候它都能恢复先前状态。 例如,Dijkstra 解决 n 皇后问题的递归算法将当前状态保存在三个全局布尔 (Boolean)数组中,他们分别表示棋盘上的列和2 条对角线;Hitotumatu 和 Noshita 的程序中使用双向链表来记录所有列和对角线上的可能性。当Dijkstra 算法暂时放置一个皇后在棋盘上的时候,会把每个布尔数组里的一个数据从真改 为假;回溯后又将这个数据改回真。Hitotumatu 和 Noshita 使用(1)去删除一 列,使用(2)去恢复删除操作;这意味着他们可以不通过搜索便找到一个空列。 程序通过这种方法记录下每个状态信息,这样替换和恢复节点使得 N 皇后问题的 计算更加高效。 算法(2)的优雅之处就在于我们仅仅知道x 的值就可以恢复(1)的操作。通常 来说要恢复操作,

文档评论(0)

1亿VIP精品文档

相关文档