Я написал ответ на ограниченную задачу о рюкзаке с одним из каждого пункта в Scala, и попытался перенося его на Haskell со следующим результатом:Haskell ранец
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
Я не ищу советы о как очистить код, просто чтобы он работал. Насколько мне известно, он должен делать следующее:
- Для каждого варианта кортежа (в ув)
- если вес текущего кортежа (у) и нарастающим итогом (хв) в сочетании меньше, чем емкость
- получить оптимальный ранец, который содержит текущий кортеж и текущую сумму (Xs), используя доступные наборы (в увах) меньше текущего кортеж
- и наконец, получить наиболее ценные из этих результатов и возврата его
* Редактировать: * Извините, забыли сказать, что не так ... Так что это скомпрометировано, но это дает неправильный ответ. Для следующих входов, что я ожидаю и что она производит:
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: []
Так мне было интересно, что может быть причиной расхождения?
Раствор, благодаря 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
который возвращает ожидаемые результаты, выше.
В чем проблема? Разве это не компилируется? Это дает неправильные результаты? Быть конкретной. – hammar