he escrito una respuesta al problema de la mochila acotada con uno de cada elemento de Scala, y trató de transponer a Haskell con el siguiente resultado:Haskell mochila
knapsack :: [ (Int, Int) ] -> [ (Int, Int) ] -> Int -> [ (Int, Int) ]
knapsack xs [] _ = xs
knapsack xs ys max =
foldr (maxOf) [ ] [ knapsack (y : xs) (filter (y /=) ys) max | y <- ys
, weightOf(y : xs) <= max ]
maxOf :: [ (Int, Int) ] -> [ (Int, Int) ] -> [ (Int, Int) ]
maxOf a b = if valueOf a > valueOf b then a else b
valueOf :: [ (Int, Int) ] -> Int
valueOf [ ] = 0
valueOf (x : xs) = fst x + valueOf xs
weightOf :: [ (Int, Int) ] -> Int
weightOf [ ] = 0
weightOf (x : xs) = snd x + weightOf xs
No estoy en busca de consejos sobre cómo limpiar el código, solo para que funcione. Que yo sepa, que debería estar haciendo lo siguiente:
- Para cada opción tupla (en ys)
- si el peso de la tupla actual (y) y el total de ejecución (x) combinado es menor que el capacidad
- conseguir la mochila óptima que contiene la tupla actual y el total actual (xs), utilizando las tuplas disponibles (en ys) menos la tupla actual
- Por último, conseguir el más valioso de estos resultados y de retorno es
* Editar: * Lo siento, se olvidó de decir lo que está mal ... Así que compila bien, pero da la respuesta incorrecta. Para las siguientes entradas, lo que espero y lo que produce:
knapsack [] [(1,1),(2,2)] 5
Expect: [(1,1),(2,2)]
Produces: [(1,1),(2,2)]
knapsack [] [(1,1),(2,2),(3,3)] 5
Expect: [(2,2),(3,3)]
Produces: []
knapsack [] [(2,1),(3,2),(4,3),(6,4)] 5
Expect: [(2,1),(6,4)]
Produces: []
así que me preguntaba lo que podría ser la causa de la discrepancia?
La solución, gracias a sepp2k:
ks = knapsack []
knapsack :: [ (Int, Int) ] -> [ (Int, Int) ] -> Int -> [ (Int, Int) ]
knapsack xs [] _ = xs
knapsack xs ys max =
foldr (maxOf) [ ] (xs : [ knapsack (y : xs) (ys #- y) max
| y <- ys, weightOf(y : xs) <= max ])
(#-) :: [ (Int, Int) ] -> (Int, Int) -> [ (Int, Int) ]
[ ] #- _ = [ ]
(x : xs) #- y = if x == y then xs else x : (xs #- y)
maxOf :: [ (Int, Int) ] -> [ (Int, Int) ] -> [ (Int, Int) ]
maxOf a b = if valueOf a > valueOf b then a else b
valueOf :: [ (Int, Int) ] -> Int
valueOf [ ] = 0
valueOf (x : xs) = fst x + valueOf xs
weightOf :: [ (Int, Int) ] -> Int
weightOf [ ] = 0
weightOf (x : xs) = snd x + weightOf xs
que devuelve los resultados esperados, arriba.
¿Cuál es el problema? ¿No compila? ¿Da los resultados incorrectos? Se específico. – hammar