packages feed

obdd 0.4.0 → 0.5.0

raw patch · 3 files changed

+94/−2 lines, 3 filesdep ~basedep ~containersPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base, containers

API changes (from Hackage documentation)

+ OBDD.Linopt: add :: (Ord v, Num w) => Map v w -> v -> Item v w -> Item v w
+ OBDD.Linopt: fill :: (Ord v, Num w) => Map v w -> v -> Item v w -> Item v w
+ OBDD.Linopt: linopt :: (Ord v, Num w, Ord w) => OBDD v -> Map v w -> Maybe (w, Map v Bool)
+ OBDD.Linopt: noadd :: (Ord v, Num w) => Map v w -> v -> Item v w -> Item v w
+ OBDD.Linopt: type Item v w = (w, [(v, Bool)])

Files

+ examples/Weight.hs view
@@ -0,0 +1,45 @@+{-++The minimal number of knights needed to occupy or attack+every square on an n×n chessboard+(i.e., domination numbers for the n×n knight graphs)++http://mathworld.wolfram.com/KnightsProblem.html++-}++import Prelude hiding ((&&),(||),not,and,or)+import OBDD +import OBDD.Linopt++import Control.Monad ( guard )+import System.Environment ( getArgs )+import Data.List (sort)+import qualified Data.Map.Strict as M++type Position = (Int,Int)++positions :: Int -> [ Position ]+positions n = (,) <$> [1..n] <*> [1..n]++knight (a,b) (c,d) = 5 == (a-c)^2 + (b-d)^2++board :: Int -> OBDD Position+board n = and $ do+  p <- positions n ; q <- positions n+  guard $ p < q ; guard $ knight p q+  return $ not (variable p) || not (variable q)++main = do+    args <- getArgs+    case map read args :: [Int] of+        [] -> mainf 9+        [arg] -> mainf arg++mainf n = do+    let d :: OBDD Position+        d = board n+        a = linopt d $ M.fromList $ zip (positions n) $ repeat 1+    putStrLn $ unwords [ "board size", show n ]+    putStrLn $ unwords [ "BDD size", show $ OBDD.size d ]+    putStrLn $ show a
obdd.cabal view
@@ -1,5 +1,5 @@ Name:                obdd-Version:             0.4.0+Version:             0.5.0 Cabal-Version:       >= 1.8 Build-type: Simple Synopsis:            Ordered Reduced Binary Decision Diagrams@@ -19,7 +19,7 @@ Library     Build-Depends:       base==4.*, random, mtl, containers>=0.5, array, process     Hs-Source-Dirs:	     src-    Exposed-Modules:     OBDD OBDD.Data OBDD.Make OBDD.Operation OBDD.Property+    Exposed-Modules:     OBDD OBDD.Data OBDD.Make OBDD.Operation OBDD.Property, OBDD.Linopt     Other-Modules:	     OBDD.IntIntMap, OBDD.VarIntIntMap     ghc-options: -funbox-strict-fields @@ -33,12 +33,19 @@     Hs-Source-Dirs : examples     Type: exitcode-stdio-1.0     Main-Is: Queens.hs+    ghc-options: -threaded -rtsopts     Build-Depends: base, containers, obdd  test-suite obdd-queens2     Hs-Source-Dirs : examples     Type: exitcode-stdio-1.0     Main-Is: Queens2.hs+    Build-Depends: base, containers, obdd++test-suite obdd-weight+    Hs-Source-Dirs : examples+    Type: exitcode-stdio-1.0+    Main-Is: Weight.hs     Build-Depends: base, containers, obdd      test-suite obdd-sort
+ src/OBDD/Linopt.hs view
@@ -0,0 +1,40 @@+module OBDD.Linopt where++import OBDD (OBDD, fold)++import qualified Data.Map.Strict as M++type Item v w = (w, [(v,Bool)])++-- | solve the constrained linear optimisation problem:+-- returns an assignment that is a model of the BDD+-- and maximises the sum of weights of variables.+linopt :: ( Ord v , Num w, Ord w ) +       => OBDD v +       -> M.Map v w +       -> Maybe (w, M.Map v Bool)+linopt d m = ( \(w,kvs) -> (w,M.fromList kvs) ) <$>+   fold ( \ leaf  -> if leaf then Just (0, []) else Nothing )+       ( \ v ml mr -> case (ml,mr) of+          (Nothing, Just r) -> Just $   add m v $ fill m v r+          (Just l, Nothing) -> Just $ noadd m v $ fill m v l+          (Just l,  Just r) -> Just $+                  let l' = noadd m v $ fill m v l +                      r' =   add m v $ fill m v r+                  in  if fst l' >= fst r' then l' else r'+       )+       d++fill :: (Ord v, Num w) => M.Map v w -> v -> Item v w -> Item v w+fill m v (w, xs) = +    let vs = (case xs of+               [] -> id+               (u,_):_ -> takeWhile (\(k,v) -> k > u) ) +           $ dropWhile (\(k,_) -> k >= v) +           $ M.toDescList m+    in  foldr (add m) (w, xs) $ map fst vs++noadd, add :: (Ord v, Num w) => M.Map v w -> v -> Item v w -> Item v w+noadd m v (w,xs) = (w          , (v,False) : xs)+add   m v (w,xs) = (w + m M.! v, (v, True) : xs)+