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

Posted

技术标签:

【中文标题】如何使用回溯算法获得所有可能的解决方案?【英文标题】:How to get all possible solutions using backtracking algorithm? 【发布时间】:2013-03-15 16:33:15 【问题描述】:

我正在使用in this youtube video 描述的回溯算法。

现在,我应该能够获得所有可能的解决方案。我能用回溯算法做到这一点吗?如何做到的?如果不可能,我应该使用哪种其他(简单)算法?

【问题讨论】:

你试过了吗? 【参考方案1】:

这个问题不太适合这个网站,因为它似乎与实际代码无关。

但无论如何我都会试一试。

当然,您可以使用回溯算法获得所有可能的解决方案。记住回溯算法的工作原理:

while(仍有猜测可用)
    做一个猜想
    用猜测解决难题
    如果有解决方案,则记录解决方案并退出循环。
    从可能的猜测列表中划掉猜测
如果你记录了一个解决方案,那么这个难题是可以解决的。

如果您想要所有解决方案,只需将算法修改为:

while(仍有猜测可用)
    做一个猜想
    用猜测解决难题
    如果有解决方案,则记录解决方案。不要放弃。
    从可能的猜测列表中划掉猜测
如果您记录了任何解决方案,那么这个难题是可以解决的。

顺便说一句,我写了一系列关于在 C# 中使用图形着色回溯算法解决数独的博客文章;您可能会感兴趣:

https://docs.microsoft.com/en-us/archive/blogs/ericlippert/graph-colouring-with-simple-backtracking-part-one

在这段代码中你会看到这一行:

return solutions.FirstOrDefault();

“解决方案”包含一个枚举所有解决方案的查询。我只想要第一个这样的解决方案,所以这就是我要求的。如果您想要所有解决方案,只需重写程序,使其不会调用FirstOrDefault。请参阅下面的 cmets 了解一些注意事项。

【讨论】:

如果没有记错,那篇博客文章的目的是提供一种有效的解决方案,而不是全部。可以对其进行更改以返回所有解决方案,但这就是这个问题所要问的……不过,这是一个很棒的博客系列。 @Servy:正确,不过是对代码的简单修改。回想一下,我生成了一个代表所有解决方案的查询,然后调用return solutions.FirstOrDefault();——如果您想要每个解决方案,只需将FirstOrDefault 去掉,然后返回solutions 我记得当我第一次阅读该系列时,我做了修改以将所有内容作为练习返回,这并不是相当那么简单,主要是因为您不再需要@ 987654327@ 值,而是有空集合,然后需要更改依赖于空检查的算法的其他方面,并且您不想多次迭代序列,所以总而言之不是 超级很难,但也不像删除FirstOrDefault那么简单。 我没有代码了,但我会看看我是否可以重新编写它。我记得当时想知道为什么你不从一开始就写它来返回所有,因为你总是可以在最后调用FirstOrDefault 来获得第一个,但是由于你将它内置到算法中,所以它变得更加困难走另一条路。 好的,所以我只是重写了它,这里是需要对Solve进行的更改:第一个基本情况需要更改为:return new[] this.possibilities.SelectMany(x => x) ;第二个基本情况需要更改为:return Enumerable.Empty<IEnumerable<int>>();,第三个基本情况需要更改为:return solutions.SelectMany(x => x);Solve 的签名也需要改为IEnumerable<IEnumerable<int>>。现在,这并不是一个巨大的巨大变化,但我不知道我是否希望任何人都能够在没有明显时间投入的情况下做到这一点。

以上是关于如何使用回溯算法获得所有可能的解决方案?的主要内容,如果未能解决你的问题,请参考以下文章

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

部分回溯搜索的通用算法

day26 回溯算法的部分总结

深入浅出回溯算法

回溯算法

核心算法5回溯算法