【问题标题】:Is it possible to create efficient recombining trees using (co)recursion?是否可以使用(共)递归创建有效的重组树?
【发布时间】:2021-04-04 10:04:15
【问题描述】:

协同递归是指展开一棵树,例如 Ed Kmett 的 recursion-schemes 中的 anamorphism@

通过重新组合树,我的意思是共享结构的图。例如,二项式 option pricing treePascal's triangle。这两者都有一定的对称性,所以为了效率,我们希望避免重新计算树的一部分,而是重新使用已经计算过的分支。

n.b.这个问题不是关于计算上述示例中的值的巧妙方法;这是一个关于递归的一般问题。

例如,对于期权定价,可以这样生成树:

data Tree x = Leaf x | Branch x (Tree x) (Tree x)
ana \(x, depth) ->
  if depth == maxDepth
    then LeafF x
    else BranchF x (p * x, depth + 1) ( (1.0 - p) * x, depth + 1)     -- p < 1.0

所以“向上”分支中的值为p * x,而“向下”分支中的值为(1-p) * x。由于这种对称性,“up”后接“down”节点的值与“down”后接“up”分支的值相同。就像整个子树一样。

我认为有可能通过 State 以某种方式传递包含已计算节点的哈希图。

或者,如果我能以某种方式访问​​已经计算好的子树,我可以将它作为 Left 传递给 apomorphism。

是否有一些现有的态射允许这样做?或者我可以自己编码吗?

【问题讨论】:

  • 在haskell中进行动态编程的典型方法是将所有(通常是无限多个)中间值存储在惰性数据结构中,利用运行时系统的状态来评估thunk,而不是显式地建模有状态。见memoization。我怀疑这可以适应递归组合器,它会很漂亮:-)

标签: haskell recursion binary-tree recursion-schemes


【解决方案1】:

ana 定义了一个递归函数x -&gt; Tree a(给定一个代数alg :: x -&gt; TreeF a x)。您可以使用专门的定点运算符定义ana 的记忆化版本(而通常的定义或多或少等同于使用fix),例如MemoTrie library

memoFix :: (...) => ((a -> b) -> (a -> b)) -> (a -> b)
-- for some constraints "(...)" depending on the implementation.
-- ana': Memoized version of ana

type Memo a b = ((a -> b) -> (a -> b)) -> a -> b

memoAna :: Memo x (Tree a) -> (x -> TreeF a x) -> x -> Tree a
memoAna memo alg = memo $ \ana_ x ->
  case alg x of
    LeafF a -> Leaf a
    BranchF a x1 x2 -> Branch a (ana_ x1) (ana_ x2)

ana' :: HasTrie x => (x -> TreeF a x) -> x -> Tree a
ana' = memoAna memoFix

这可确保从同一种子 x 生成的所有树实际上都是同一棵树。

您还必须注意种子的类型。在您的示例中,使用(Double, Int)Double 操作的不精确性使得记忆不可靠。所以你还需要修改代数。例如,由于价格始终采用p^i (1-p)^(depth-i) 的形式,您可以记住索引i

optionsAlg' :: Num a => a -> (Int, Int) -> TreeF a (Int, Int)
optionsAlg' p (ups, depth) =
  if depth >= maxDepth then
    LeafF price
  else
    BranchF price (ups+1, depth+1) (ups, depth+1)
  where
    price = p ^ ups * (1 - p) ^ (depth - ups)

memoization 的实现需要权衡取舍。根据您的特定用例,可能需要进一步优化和调整。

【讨论】:

    猜你喜欢
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多