- Haskell Knapsack
- 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
- 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: []
- 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
- import Data.List
- import Data.Function(on)
- ks = knapsack []
- knapsack :: [(Int, Int)] -> [(Int, Int)] -> Int -> [(Int, Int)]
- knapsack xs [] _ = xs
- knapsack xs ys max =
- foldr (maxOf) [] (xs: [knapsack (y:xs) (delete y ys) max
- | y <- ys, weightOf(y:xs) <= max ] ) where
- weightOf = sum . map snd
- maxOf :: [(Int, Int)] -> [(Int, Int)] -> [(Int, Int)]
- maxOf a b = maximumBy (compare `on` valueOf) [a,b] where
- valueOf = sum . map fst
- import Array
- -- creates the dynamic programming table as an array
- dynProgTable (var,cap) = a where
- a = array ((0,0),(length var,cap)) [ ((i,j), best i j)
- | i <- [0..length var] , j <- [0..cap] ] where
- best 0 _ = 0
- best _ 0 = 0
- best i j
- | snd (var !! (i-1)) > j = a!decline
- | otherwise = maximum [a!decline,value+a!accept]
- where decline = (i-1,j)
- accept = (i-1,j - snd (var !! (i-1)))
- value = fst (var !! (i-1))
- --Backtracks the solution from the dynamic programming table
- --Output on the form [Int] where i'th element equals 1 if
- --i'th variable was accepted, 0 otherwise.
- solve (var,cap) =
- let j = cap
- i = length var
- table = dynProgTable (var,cap)
- step _ 0 _ = []
- step a k 0 = step table (k-1) 0 ++ [0]
- step a k l
- | a!(k,l) == a!(k-1,l) = step a (k-1) l ++ [0]
- | otherwise = step a (k-1) (l - snd (var !! (k-1))) ++ [1]
- in step table i j