【问题标题】:Function call to memoization (with multiple parameters)对记忆的函数调用(带有多个参数)
【发布时间】:2018-04-16 09:25:27
【问题描述】:

我想在具有多个不同参数的函数上使用 memoization

function :: (Int, Int) -> [[Int]] -> Int

到目前为止我尝试了什么:

function :: (Int, Int) -> [[Int]] -> Int
function (s, d) matrix = inner (s, d) matrix 
  where  
    inner (i, 0) g = g !! (i-1) !! (0)
    inner (i, k) g = maximum [memo ! ((i, k-1), g)
                             ,
                              memo ! ((i-1, k), g)
                             ]
    memo = listArray bounds
                [inner (i,k) g | ((i,k), g) <- Data.Array.range bounds]
    bounds = ( ((1,1), [[1,1]]), ((n,n), [[n,n]]) )

仍然没有按预期工作 - 我收到的消息是:

没有因使用“!”而导致 (Data.Array.Ix [[Int]]) 的实例

【问题讨论】:

  • 能否请您创建一个测试用例,这是一个最小、完整和可验证的示例stackoverflow.com/help/mcve
  • 记忆一个接受[[Int]]类型参数的函数是不寻常的,并且您尝试使用的基于数组的方法可能不起作用。错误消息告诉您不能使用 [[Int]] 作为数组的索引。也许您可以改用Data.Map,但我不知道在这种情况下该推荐什么。
  • 使用(!!) 可能会导致大量开销:!! k,在 O(k) 中工作,因此对于较大的k,这将花费大量时间。
  • 请解释这段代码应该做什么(伪代码、规范、示例......)。我怀疑你真的想在[[Int]] 类型的键上记忆。
  • 基本上,代码是:inner (i, 0) g = g !! (i-1) !! (0) inner (i, k) g = maximum [inner ((i, k-1), g) , inner((i-1, k), g) ] ,没有记忆。我想将 : inner((i-1, k), g / [inner ((i, k-1), g) 的结果存储在一个数组中,使用记忆化。

标签: haskell


【解决方案1】:

我碰巧知道有一个Data.Function.Memoize 包肯定会让整个事情变得更容易。

在你的情况下,我会在这个包中使用带有类型签名的 memoize2 函数

memoize2 :: (Memoizable a, Memoizable b) => (a -> b -> v) -> a -> b -> v

a = (Int, Int), b = [[Int]]。以下实例会让您确信类型约束已得到满足:

Memoizable Int
Memoizable a => Memoizable [a]
(Memoizable a, Memoizable b) => Memoizable (a, b)

注意事项:虽然我对这个包有一些好印象,但它似乎不是很便携或不可靠(如果你要用它来构建真实的东西)。在其 Hackage 页面上可以找到以下声明:

请注意,这种风格的大多数记忆都依赖于关于实现非严格性(如惰性)的假设,而这些假设并不受语义保证。但是,它似乎可以工作。

【讨论】:

  • 谢谢。幸运的是,我在没有这个包的情况下解决了这个问题。
猜你喜欢
  • 2019-01-21
  • 2013-08-20
  • 1970-01-01
  • 1970-01-01
  • 2015-03-20
  • 2012-04-20
  • 2016-03-30
  • 2021-01-11
  • 2010-10-12
相关资源
最近更新 更多