【问题标题】:Question about Knuth's "Dancing Links" / DLX algorithm (in Python)关于 Knuth 的“Dancing Links”/DLX 算法(在 Python 中)的问题
【发布时间】:2020-06-30 15:16:18
【问题描述】:

我已经阅读了很多关于“精确覆盖”问题和 Knuth 使用重链表的解决方案的文章。我想我理解了其中的 70%,但仍然对链表“cover”和“uncover”应该如何工作感到困惑。

Knuth 的论文:https://www.ocf.berkeley.edu/~jchu/publicportal/sudoku/0011047.pdf

我理解/已经编码的内容:

  • 72 位宽。 12 列用于该片的列中具有 1 位的片,然后 60 列 1 和(大部分)0 代表片的形状。所以 72 位宽(作为单个 Python int)乘 1,928 行(每块对每个正方形的每一次有效移动)

  • 所有带 0 的节点都已被移除并调整剩余的链接指针

  • 按照 Knuth 的说法,完全链表。我的数据结构看起来就像 Knuth 论文第 5 页上的那样:我有常规数据节点、列标题节点、主“h”节点,并且所有内容都是交叉链接的,左/右,上/下等,所以我完成了稀疏矩阵双向链表,左/右和上/下。

  • 对于节点,我已经编写了删除节点并添加回一个节点。

我被困在哪里:

  • 当他们说要“覆盖”一列时,我有点困惑。我是否从列标题节点列表中仅删除(取消链接)该列的列标题节点?还是删除该列中的所有节点?

  • 我对 Rows 更加困惑。当他们说“覆盖一行”时,我不确定要对我的数据结构进行哪些更改。没有像列那样调整“行”标题,我很确定这不是遗漏。没有任何“行标题”,只有列标题。所以如果我想暂时删除一行,我应该改变什么?我是否循环遍历该行中的所有节点并将它们全部删除?如果我回溯,然后将它们全部添加回来?似乎有很多要删除和添加的内容,所以我很确定这是我不理解的部分。

很高兴回答/编辑以使问题更清楚。由于我的代码很长而且很乱,我现在不打算发布它(除非人们真的认为它会有所帮助,但它是链表,就像 Knuth 展示的那样,所以我认为代码会分散注意力。

那么,当使用 Knuth 的链表(带有列标题)时,如何“覆盖”一列,更重要的是,如何“覆盖”一行??

谢谢, 标记

【问题讨论】:

    标签: python algorithm linked-list cover knuth


    【解决方案1】:

    当他们说要“覆盖”一列时,我有点困惑。我是否从列标题节点列表中仅删除(取消链接)该列的列标题节点?还是删除该列中的所有节点?

    后者——每一列必须恰好有一个属于精确覆盖的事件行,因此这些节点不能在当前子树中使用。

    我对 Rows 更加困惑。当他们说“覆盖一行”时

    我在 Knuth 的文章中找不到该文本。大概意思是,当您通过选择要添加到封面的行来下降解决方案树时,您需要覆盖其所有事件列。

    也许更简洁的说法是,当你选择一行时,你需要删除二分图中与关联矩阵对应的距离为 2 的所有其他行。

    【讨论】:

    • 好的,这很有帮助;所以除了双重链接的东西之外,标题节点中没有“魔法”。澄清:是的,当我在所有这些情况下说“覆盖”时,我的意思是“删除”,或从未来的级别中删除,等等。我认为我现在有“白板级别”的理解,但仍然是确切的代码有点模糊。我决定暂时从我的 Pentominoes 代码中休息一下,并通过 Wikipedia 中更小的一般示例来工作 - 我认为这将为我提供详细信息;这是一个非常好的例子,非常详尽,en.wikipedia.org/wiki/Knuth%27s_Algorithm_X#Example
    猜你喜欢
    • 2012-07-26
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    • 2020-09-29
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 2014-02-21
    相关资源
    最近更新 更多