【问题标题】:Random topological sorting with uniform distribution in near linear time近线性时间内均匀分布的随机拓扑排序
【发布时间】:2016-11-27 19:26:39
【问题描述】:

我想要一种拓扑排序算法,它每次都不会提供相同的排序,而是随机排序,每次排序对所有其他排序的可能性都相同。

生成所有可能的拓扑排序并随机选择一个是正确的,但太慢了。生成所有排列和过滤无效的拓扑排序也很慢;如果树/森林足够宽,第一个会退化为第二个。

将新节点插入到要检查的节点队列中的随机位置似乎会产生有偏差的结果,并将其放在最后并进行fisher-yates shuffle似乎也有偏差,因为两者都没有考虑到每个节点下“隐藏”的节点数,即有多少节点取决于正在调度的aba 可以没有孩子,而b 拥有树的其余部分。

如何在接近线性的时间内生成随机拓扑排序,每个有效排序的可能性相同?

【问题讨论】:

标签: algorithm random topological-sort uniform-distribution


【解决方案1】:

编辑:在任何合理的时间内都不可能以您想要的方式解决此问题。这样做涉及解决#P-完全问题。最好的办法是使用概率方法。

https://mathoverflow.net/questions/45875/how-can-you-compute-the-number-of-topological-sorts-in-a-dag

  1. 列出所有边的列表
  2. 确定哪些节点是“起始”节点。起始节点没有进入它们的有向边
  3. 对于每个起始节点,选择它,删除与其对应的所有有向边,然后考虑可能的下一步移动的数量。找到每个起始节点的可能移动次数后,根据概率随机选择一个节点(示例如下)。
  4. 删除起始节点指向的边。
  5. 重复步骤 2 到 4。

这类似于卡恩的算法。

https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm

只要您从所有其他起始节点中随机挑选每个起始节点,您就应该得到一个随机有效的拓扑排序,其概率与任何其他随机拓扑排序相同。

例如,如果我有一个图 {(5, 11)(7, 8)(7, 11)(3, 8)(3, 10)(8, 9)(11, 2)(11, 9)(11, 10)} 其中 (a, b) 是从 a 到 b 的有向边,我首先确定 5、7 和 3 是起始节点。我会随机选择一个 (3),然后删除以 3 开头的所有边,包括 (3,8) 和 (3, 10)。我会检查节点 8 和 10 现在是否是启动节点。他们不是。我的起始节点现在是 5 和 7。我会选择另一个随机起始节点 (7),然后删除所有带有 7 的边,即 (7, 8) 和 (7, 11)。我会检查这些是否是起始节点。 8是起始节点。我的起始节点现在是 5 和 8。我随机选择 8,用 8 删除边,其中包括 (8, 9)。我检查 9 是否是起始节点。我唯一的起始节点是 5。我选择 5,删除边 (5, 11)。 11 现在是我唯一的起始节点。我选择 11,删除边缘 (11, 2)、(11, 9) 和 (11, 10)。 2、9 和 10 现在是起始节点。我随机选择 2 个,删除所有边缘。 9 和 10 是我的起始节点。我选择 10,然后选择 9。

我的拓扑排序现在是 {3, 7, 8, 5 11, 2, 10, 9}

编辑:似乎找到有效拓扑排序的数量是#P-complete,这意味着您最好的选择是使用概率算法来确定每个元素可能的排序数量,然后根据所有起始节点的拓扑排序总数调整概率。

https://mathoverflow.net/questions/45875/how-can-you-compute-the-number-of-topological-sorts-in-a-dag

https://en.wikipedia.org/wiki/Sharp-P-complete

编辑:您可以猜测从特定起始节点开始的拓扑排序的分数,方法是选择该起始节点,删除从它出发的所有有向边,然后计算所有可能的下一步移动的数量,然后找到一个好的函数对其进行建模。例如,在我的例子中,如果我选择了 5,我接下来会有两个可能的动作,3 和 7。如果我选​​择了 3 或 7,我还有两个可能的动作。然后我会找出我还剩下多少可能的动作,然后概率性地选择一个。在这种情况下,这三个人的机会都是平等的,所以我只是随机选择一个。在这种情况下,我选择 3。然后我可以选择 5 或 7。如果我选​​择 5,我将只剩下一个可能的动作,即 7,如果我选择 7,我将剩下两个可能的动作。因此,7 有 2/3 的机会被选中,5 有 1/3 的机会。这个过程一直持续到你到达终点。这只是一种启发式方法,但它应该能让您很好地近似选择完全随机的有效拓扑排序。此外,在您给出的反例中,将每个起始节点的可能移动次数加一似乎得到了更好的近似值。

【讨论】:

  • 这并不能使每种可能的排序都具有同等的可能性。选择 X 作为第一个节点的机会需要与以 X 开头的有效排序的数量成正比。
  • @Filip Haglund 你能指定你使用的符号吗?因为看起来你必须先选择 2,否则你不能根据你的第一条边选择 3。
  • 有一个错字。反例:2->43->43->5。第一个选择是23,它们不均匀地划分所有可能的拓扑排序。 2 首先让我们无法选择5 下一个,但如果我们先选择3,我们可以选择245 下一个。
  • @Filip Haglund 首先是需要同时选择 2 和 3 才能选择 4。其次,反例中所有可能的拓扑排序都是 {2,3,4,5};{ 2,3,5,4};{3,5,2,4};{3,2,4,5};{3,2,5,4}。我设置的随机算法将随机选择 2 个或 3 个,因为它们是起始节点。如果它选择 2,那么它只能选择 3,因为 4 和 5 依赖于 3。一旦选择 3,它可以按任意顺序选择其他两个。如果它先选择 3,它可以选择 2 或 5。如果它接下来选择 2,它可以选择 4 或 5。如果它选择 5 而不是 2,它必须先选择 2,因为 4 取决于 2。
  • @Matt Timmermans 好点。这只会真正生成具有不均匀概率的随机有效拓扑排序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-08
  • 2021-12-28
  • 1970-01-01
  • 1970-01-01
  • 2020-04-04
  • 1970-01-01
相关资源
最近更新 更多