Scala中的背包解决方案,带有记忆功能

时间:2017-05-30 11:08:34

标签: scala scalaz

您好我正在尝试使用Memoization在Scala中实现Knapsack解决方案。这是没有记忆的代码

// knapsack = maxWeight: Int, weights: List[Int], values: List[Int]
val knapsack: ((Int, List[Int], List[Int]) => Int) = Memo {
     case (0, _, _) | (_, Nil, _) | (_, _, Nil) => 0
     case (weight, headWt :: tailWts, _ :: tailVals) if headWt > weight => 
                                       knapsack(weight, tailWts, tailVals)
     case (weight, headWt :: tailWts, headVal :: tailVals) => math.max(
                                       headVal+knapsack(weight-headWt, tailWts, tailVals),
                                       knapsack(weight-headWt, tailWts, tailVals))  
}

println(knapsack(50, weights.sortBy(-_), values.sortBy(-_)))

以下是备忘录的定义:

case class Memo[A,B](f: A=>B) extends mutable.HashMap[A,B]{
     override def apply(a: A):B = {
          getOrElseUpdate(a, f(a))
     }
}

但是,我收到编译时错误:

  Type mismatch, expected: List[Int], actual: List[Any] 

如果我删除备忘录,它可以正常工作。

感谢。

1 个答案:

答案 0 :(得分:1)

我不确定您收到错误的哪一行

  

类型不匹配,预期:List [Int],actual:List [Any]

如果我将knapsack的类型更改为(((Int, List[Int], List[Int])) => Int),即Function1从元组(Int, List[Int], List[Int])更改为Int,则代码Memo会编译为// knapsack = maxWeight: Int, weights: List[Int], values: List[Int] val knapsack: (((Int, List[Int], List[Int])) => Int) = Memo { case (0, _, _) | (_, Nil, _) | (_, _, Nil) => 0 case (weight, headWt :: tailWts, _ :: tailVals) if headWt > weight => knapsack(weight, tailWts, tailVals) case (weight, headWt :: tailWts, headVal :: tailVals) => math.max( headVal + knapsack(weight - headWt, tailWts, tailVals), knapsack(weight - headWt, tailWts, tailVals)) } val weights: List[Int] = List(10, 20, 30) val values: List[Int] = List(2, 3, 4) println(knapsack(50, weights.sortBy(-_), values.sortBy(-_))) 我没有任何错误。

"hostname": "localhost".

产生预期的

  

7