【问题标题】:How can iterative deepening search implemented efficient in haskell?迭代深化搜索如何在haskell中高效实现?
【发布时间】:2010-09-21 06:36:49
【问题描述】:

我有一个要解决的优化问题。你有某种数据结构:

data Foo =
  { fooA :: Int
  , fooB :: Int
  , fooC :: Int
  , fooD :: Int
  , fooE :: Int
}

还有一个评分函数:

rateFoo :: myFoo -> Int

我必须通过更改结构中的值来优化rateFoo 的结果。在这种具体情况下,我决定使用迭代深化搜索来解决问题。用于最佳优化的(无限)搜索树由另一个函数创建,该函数简单地将所有可能的更改递归地应用于树:

fooTree :: Foo -> Tree

我的搜索功能如下所示:

optimize :: Int -> Foo -> Foo
optimize threshold foo = undefined

在开始之前我的问题是:

由于树可以由每个点的数据生成,是否可以只生成算法当前需要的树的部分?是否有可能释放内存并在需要时重新生成树以节省内存(可以在O(n) 中生成级别 n 的休假,并且 n 仍然很小,但不足以让整个树随着时间的推移在内存中)?

这是我可以从运行时中得到的东西吗?运行时可以unevaluate 表达式(将已评估的表达式转换为未评估的表达式)吗?或者我必须为此做些什么肮脏的黑客行为?

【问题讨论】:

  • 如果您认为需要取消评估某些内容,那么您的算法设计是错误的。
  • 运行时不会取消计算表达式。但是,请为您的树考虑类似拉链的结构。每个节点都有一个值和一个代表向下、向上等的 thunk。当您移动到下一个节点时,您可以正常移动(将前一个节点值放在相应的槽中)或忘记移动(放置一个计算结果为前一个的表达式右侧插槽中的节点)。然后,您可以控制自己保留了多少“历史”。
  • 当然可以。但是,顺便说一句,我会考虑将数据结构投影到双精度向量并使用标准数值优化技术(例如某种广义牛顿)是否足够。根据您的评级功能,它甚至可能容易受到自动区分:-)
  • 似乎有 a package 来帮助解决这个问题,不过也可以自己滚动,这是我去年为课程作业所做的。

标签: haskell tree memory-management lazy-evaluation iterative-deepening


【解决方案1】:

运行时不会取消计算表达式。

不过,有一种简单的方法可以得到你想要的。

为你的树考虑一个类似拉链的结构。每个节点都有一个值和一个代表向下、向上等的 thunk。当您移动到下一个节点时,您可以正常移动(将前一个节点值放在相应的槽中)或忘记移动(放置一个计算结果为前一个的表达式右侧插槽中的节点)。然后你就可以控制你保留了多少“历史”。

【讨论】:

  • 您能否详细说明如何使用拉链来帮助迭代深化搜索?我很好奇,但我没看到。
  • 拉链没有太多处理搜索的逻辑。相反,它只是有助于捕获保留哪些数据以及需要丢弃哪些数据并按需重新生成。
【解决方案2】:

这是我的建议:

  1. 只需在 最直接的方式。
  2. 个人资料。
  3. 如有必要,优化速度或内存使用。

我很快了解到我不够聪明和/或经验不足,无法推断 GHC 将做什么或垃圾收集将如何工作。有时,我确信在第一次运行时会出现灾难性的内存效率低下的问题,而似乎很简单的事情则需要大量的严格注释等。

profiling and optimization 上的 Real World Haskell 章节在您进行第 2 步和第 3 步后非常有帮助。


例如,这里有一个非常简单的 IDDFS 实现,其中f 扩展子级,p 是搜索谓词,x 是起点。

search :: (a -> [a]) -> (a -> Bool) -> a -> Bool
search f p x = any (\d -> searchTo f p d x) [1..]
  where
    searchTo f p d x
      | d == 0    = False
      | p x       = True
      | otherwise = any (searchTo f p $ d - 1) (f x)

我通过搜索"abbaaaaaacccaaaaabbaaccc"children x = [x ++ "a", x ++ "bb", x ++ "ccc"] 作为f 进行了测试。它看起来相当快并且需要很少的内存(我认为与深度成线性关系)。为什么不先尝试这样的事情,如果还不够好,再转向更复杂的数据结构?

【讨论】:

  • 我想做的方式(构建所有可能方式的树)实际上似乎是我能做的“最直接”的事情。另一种方法是使用本地子树,但这可能会一团糟。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-17
  • 1970-01-01
  • 2011-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多