【发布时间】: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