ruby – 高效的置换树算法

ruby – 高效的置换树算法,第1张

概述我试图编写一个算法来解决任何数独.然而,我原来的方法是有缺陷的,因为我没有意识到一个结构良好的数独应该只有一个解决方案. 因此,结果算法没有针对数独求解进行优化,并且更为通用:它递归地生成当前数独布局的每个可能允许的结果/布局.因此,该算法在理论上可以找到空白数独的每个解决方案(但我/我们/人类可能不会看到输出). 我的第一个问题是:对于这种类型的搜索算法,什么是最佳方法 – 如何改进我的算法?总 我试图编写一个算法来解决任何数独.然而,我原来的方法是有缺陷的,因为我没有意识到一个结构良好的数独应该只有一个解决方案.

因此,结果算法没有针对数独求解进行优化,并且更为通用:它递归地生成当前数独布局的每个可能允许的结果/布局.因此,该算法在理论上可以找到空白数独的每个解决方案(但我/我们/人类可能不会看到输出).

我的第一个问题是:对于这种类型的搜索算法,什么是最佳方法 – 如何改进我的算法?总体战略是:

>在分支点尝试所有可能的解决方案
>如果无法解决单元格,则终止分支
>如果达到解决方案,则终止分支

结构和方法改编自为解决SICP(https://mitpress.mit.edu/sicp/full-text/book/book-Z-H-15.html)中的八皇后问题而提出的时间解耦解决方案,似乎这是一种反向跟踪算法(将“时间”状态推入机器中),在我的情况下这是真的吗?

我的第二个问题是,在处理递归算法时,如何使用Ruby> = 2.x Lazy功能生成可枚举?

期望的结果是做一些像solve(sudoku).first(x)这样的东西来检索第一个x解决方案.即解决方案存储为流/序列.我遇到的困难是递归生成嵌套的枚举,我正在努力寻找一种方法来传递整个树的强制方法.

我已在下面列出了密钥代码,但完整的方法套件可以在这里找到:https://gist.github.com/djtango/fe9322748cf8a055fc0e

def solve(sudoku)  guess(simplify_sudoku(sudoku))enddef guess(sudoku,row = 0,column = 0)  return sudoku.flatten                 if end_of_grID?(row,column)  return guess(sudoku,row + 1,0)      if end_of_column?(column)  return guess(sudoku,row,column + 1) if filled?(sudoku,column)  return nil                            if insoluble?(sudoku,column)  permissible_values(sudoku,column).map do |value|    guess(update_sudoku(sudoku,value,column),column + 1)  endenddef simplify_sudoku(sudoku)  return sudoku if no_easy_solutions?(sudoku)  simplify_sudoku(fill_in(sudoku))enddef fill_in(sudoku)  new_sudoku = copy_sudoku(sudoku)  new_sudoku.map.with_index do |row,row_index|    row.map.with_index do |column,column_index|      solution = permissible_values(new_sudoku,row_index,column_index)      easy_and_not_filled?(solution,new_sudoku,column_index) ? [solution.first] : column    end  endend

在尝试实现延迟评估时,引入惰性方法的最自然点是猜测方法,如下所示:

permissible_values(sudoku,column + 1)  end

但是在实现这个时,结果是:

solve(blank_sdk) => #<Enumerator::Lazy: #<Enumerator::Lazy: [1,2,3,4,5,6,7,8,9]>:map> solve(blank_sdk).first(10) => [#<Enumerator::Lazy: #<Enumerator::Lazy: [2,9]>:map>,#<Enumerator::Lazy: #<Enumerator::Lazy: [1,8]>:map>] solve(blank_sdk).first(1000000000000) => [#<Enumerator::Lazy: #<Enumerator::Lazy: [2,8]>:map>]
解决方法 您无需在每个分支点尝试所有可能的解决方案.您可以通过找到剩余选项数最少的单元格并尝试其中的变体来做得更好.这样,您可以快速设置仅剩下一个选项的所有单元格.当你需要尝试不同的解决方案时,你可能只会尝试一些变种(2-3),而不是所有的可能性,所以它应该更快.如果它们都不适用于该单元格,则可以停止,因为没有解决方案. 总结

以上是内存溢出为你收集整理的ruby – 高效置换树算法全部内容,希望文章能够帮你解决ruby – 高效的置换树算法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1270573.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存