以下代码来自Pathikrit的动态规划存储库。我对它的美丽和奇特感到困惑。
我有几个问题:
我非常喜欢Pathikrit的scalgos库。里面有很多Scala珍珠。请帮我理解这个,这样我就能欣赏Pathikrit的智慧了。谢谢。(:
def subsetSum(s: List[Int], t: Int) = {
type DP = Memo[(List[Int], Int), (Int, Int), Seq[Seq[Int]]]
implicit def encode(key: (List[Int], Int)) = (key._1.length, key._2)
lazy val f: DP = Memo {
case (Nil, 0) => Seq(Nil)
case (Nil, _) => Nil
case (a :: as, x) => (f(as, x - a) map {_ :+ a}) ++ f(as, x)
}
f(s, t)
}
Memo
类型在另一个文件中实现:
case class Memo[I <% K, K, O](f: I => O) extends (I => O) {
import collection.mutable.{Map => Dict}
val cache = Dict.empty[K, O]
override def apply(x: I) = cache getOrElseUpdate (x, f(x))
}
我有几个问题:
为什么在subsetSum中,
type K
被声明为(Int, Int)
?(Int, Int)
中的int
分别代表什么意思?
3. (List[Int], Int)
如何隐式转换为(Int, Int)
?
我没有看到implicit def foo(x:(List[Int],Int)) = (x._1.toInt,x._2)
。(即使在它导入的Implicits.scala
文件中也没有。)
*编辑:好吧,我错过了这个:
implicit def encode(key: (List[Int], Int)) = (key._1.length, key._2)
我非常喜欢Pathikrit的scalgos库。里面有很多Scala珍珠。请帮我理解这个,这样我就能欣赏Pathikrit的智慧了。谢谢。(:
implicit def encode
的行。 - pathikritf
是否真的进行了记忆化?似乎每次调用subsetSum
时,都会创建一个新的Memo实例,而不是我们想要的最后一个memo。这是真的吗? - Yun-Chih Chens
和t
,它返回一个Memo
对象。如果之前已经计算过,那么对该Memo
对象的进一步调用将是O(1)
的。您可以通过编写一个简单的斐波那契记忆化函数来验证自己,例如:lazy val factorial: Int ==> BigInt = Memo { case 0 => 1 case n => n * factorial(n - 1) }
- pathikritMemo.scala
中:cache getOrElseUpdate (x,(y)=> println(s“Cache miss:$ y”); f(y)) - pathikritf(s, t)
与返回动态程序(即对s
和t
进行记忆化的闭包)即返回f
本身是有区别的。请参见我在此处对您的回复。 - pathikrit