如何为回溯算法获得更严格的界限?

Posted

技术标签:

【中文标题】如何为回溯算法获得更严格的界限?【英文标题】:How to get tighter bounds for Backtracking algorithms? 【发布时间】:2016-01-19 04:42:07 【问题描述】:

最近,我使用回溯解决了一些问题(数独求解器,N 皇后问题)。虽然我可以直观地理解回溯比蛮力更好,但我无法从数学/渐近上推理出来。例如,假设我们正在为 N * N 网格实现数独求解器,其中有 K 个空槽要填充。这里:

    N * N 网格有 NK 个结束状态。 在填充每个插槽结束时,我们检查它是否仍然有效,并且此验证需要 O(N) 时间。

[蛮力方法是使用任何 N 个数字填充所有 K 个插槽,然后检查最终状态是否为有效网格。]

总而言之,我们推断它需要 O(NK*NK) = O(KNK+1)

嗯,这对于蛮力算法来说是一个足够公平的界限,但是在回溯算法中,我们在填充过程的更早的时候就删除了很多无效状态。显然,与蛮力实现相比,回溯算法在实践中非常快。我搜索了类似的问题,发现了这个one,但它使用与蛮力相同的界限。我们如何渐近地证明这种回溯算法优于蛮力算法?

编辑: 由于人们投票以“太宽泛”来结束这个问题,因此我重申我正在寻找上述数独求解器的具体案例。 但是,您可以分享您通常用来渐近推断给定回溯问题比蛮力方法更快的任何想法。

【问题讨论】:

你可以谈谈应用于数独问题的回溯算法。 @SelçukCihan:回溯算法只是用 1 到 9 的数字填充一个空槽,然后尝试继续填充其他空槽,看看是否有效。如果它不起作用,我们会回滚我们所做的条目,并在该空槽中尝试不同的数字并重试。 【参考方案1】:

渐近回溯通常与蛮力相同。

这样做的原因是,在最坏的情况下您将在实践中看到的优化很难争论。对于数独,您可能会争辩说,在最坏的情况下(空板),您的表现将是 O(N! * N-1! * N-2! ...) (因为您不会尝试明显错误的选项) .然而,这与平均情况相去甚远,可能很多位置只有一个合格值,您只需在几个插槽中尝试几个合格值(少于空插槽的数量)。所以对于一个 20*20 的谜题,你只有 10 个插槽,每个插槽有 3 个合格值,你的表现看起来更像 3^10 而不是 20!*19!*18!... 不能保证,但实际上它更快对于大多数情况。

这类似于其他算法,其中最坏情况可能非常糟糕,但平均情况非常好。例如 QSort 是 O(N^2) ,因为您总是可以选择最差的支点。然而这不太可能,所以平均性能更像 NlogN。

【讨论】:

在快速排序中,我们能够得出 O(NlogN) 的平均性能界限。当您说“无法保证,但实际上在大多数情况下它更快”时,我确实理解。就像我们为快速排序所做的那样,是否有 任何事情 我们可以在数学上做(无需过多假设输入数独网格)来提出一些更严格的界限?比方说,我正在参加一个编程比赛,我如何说服自己这个程序在编码之前会及时运行? 复杂性分析中没有任何内容可以告诉您它是否会及时运行。在大多数情况下,QSort 和 HeapSort 都是 O(NlogN),但实际上,对于 int,QSort 将比 HeapSort 快得多。当范围足够小时(O(N ^ 2))时,排序的一些实现也会进行插入排序,因为实际上它比 QSort 对于那个小数据更快。如果您正在参与编程环境并且您已经说服自己问题是 NP,请确保您尽早消除不良的部分解决方案。 当然,这是有道理的。谢谢。

以上是关于如何为回溯算法获得更严格的界限?的主要内容,如果未能解决你的问题,请参考以下文章

漫谈回溯(未完待续)

如何使用回溯算法获得所有可能的解决方案?

算法学习笔记

算法学习笔记

算法学习笔记

五大常用算法:分治动态规划贪心回溯和分支界定