调试深度递归的实用技巧?

Jul*_*anR 10 language-agnostic debugging recursion

我正在研究一种棋盘游戏算法,其中使用递归遍历大型树,但是,它的行为并不像预期的那样.我如何处理这些以及您对这些情况的体验?

更糟糕的是,它使用alpha-beta修剪,这意味着树的整个部分永远不会被访问,并且它只是在满足某些条件时停止递归.我也无法将搜索深度更改为较低的数字,因为虽然它是确定性的,但结果确实会因搜索的深度而异,并且可能会在较低的搜索深度(和确实如此)下按预期运行.

现在,我不会问你"我的代码中的问题在哪里?" 但我正在寻找一般技巧,工具,可视化,以及调试此类代码的任何东西.就个人而言,我正在开发C#,但欢迎使用任何和所有工具.虽然我认为这可能最适用于命令式语言.

Pau*_*ier 24

日志记录.广泛登录您的代码.根据我的经验,日志记录是解决这些类型问题的方法.当很难弄清楚你的代码在做什么时,广泛记录它是一个非常好的解决方案,因为它允许你从代码中输出内部状态是什么; 它真的不是一个完美的解决方案,但就我所见,它比使用任何其他方法更好.


小智 7

我过去做过的一件事是格式化日志以反映递归深度。所以你可以为每次递归或其他一些分隔符做一个新的缩进。然后制作一个调试 dll,记录您需要了解的关于每次迭代的所有信息。在这两者之间,您应该能够读取执行路径并希望知道哪里出了问题。


kro*_*old 6

我通常会使用一个或多个具有明确定义的结果的预定义数据集对此类算法进行单元测试。我通常会按照复杂性递增的顺序进行几个这样的测试。

如果您坚持要调试,有时使用检查给定值的语句来修改代码会很有用,这样您就可以在代码中的那个时间和位置附加一个断点:

  if ( depth = X && item.id = 32) {
     // Breakpoint here
  }
Run Code Online (Sandbox Code Playgroud)

  • 好吧,此时的单元测试只会告诉我它不起作用,我已经知道了:p (4认同)

小智 6

也许您可以将递归转换为具有参数的显式堆栈的迭代.以这种方式进行测试更容易,因为您可以直接记录值,访问堆栈,而不必在每次自我评估中传递数据/变量或防止它们超出范围.

  • 这是保持理智的解决方案; 它还消除了递归解决方案的固有限制(假设一个动态结构来保存参数队列) (2认同)