{-# LANGUAGE LambdaCase #-}
module Algebra.Graph.Bipartite.AdjacencyMap.Algorithm (
OddCycle, detectParts,
Matching, pairOfLeft, pairOfRight, matching, isMatchingOf, matchingSize,
maxMatching,
VertexCover, isVertexCoverOf, vertexCoverSize, minVertexCover,
IndependentSet, isIndependentSetOf, independentSetSize, maxIndependentSet,
augmentingPath, consistentMatching
) where
import Algebra.Graph.Bipartite.AdjacencyMap
import Control.Monad (guard, when)
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Maybe (MaybeT(..))
import Control.Monad.Trans.State (State, runState, get, put, modify)
import Control.Monad.ST (ST, runST)
import Data.Either (fromLeft)
import Data.Foldable (asum, foldl')
import Data.Functor (($>))
import Data.List (sort)
import Data.Maybe (fromJust)
import Data.STRef (STRef, newSTRef, readSTRef, writeSTRef, modifySTRef)
import GHC.Generics
import qualified Algebra.Graph.AdjacencyMap as AM
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import qualified Data.Sequence as Seq
import Data.Map.Strict (Map)
import Data.Set (Set)
import Data.Sequence (Seq, ViewL (..), (|>))
type OddCycle a = [a]
data Part = LeftPart | RightPart deriving (Int -> Part -> ShowS
[Part] -> ShowS
Part -> String
(Int -> Part -> ShowS)
-> (Part -> String) -> ([Part] -> ShowS) -> Show Part
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Part -> ShowS
showsPrec :: Int -> Part -> ShowS
$cshow :: Part -> String
show :: Part -> String
$cshowList :: [Part] -> ShowS
showList :: [Part] -> ShowS
Show, Part -> Part -> Bool
(Part -> Part -> Bool) -> (Part -> Part -> Bool) -> Eq Part
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Part -> Part -> Bool
== :: Part -> Part -> Bool
$c/= :: Part -> Part -> Bool
/= :: Part -> Part -> Bool
Eq)
otherPart :: Part -> Part
otherPart :: Part -> Part
otherPart Part
LeftPart = Part
RightPart
otherPart Part
RightPart = Part
LeftPart
detectParts :: Ord a => AM.AdjacencyMap a -> Either (OddCycle a) (AdjacencyMap a a)
detectParts :: forall a.
Ord a =>
AdjacencyMap a -> Either (OddCycle a) (AdjacencyMap a a)
detectParts AdjacencyMap a
x = case State (Map a Part) (Maybe (OddCycle a))
-> Map a Part -> (Maybe (OddCycle a), Map a Part)
forall s a. State s a -> s -> (a, s)
runState (MaybeT (StateT (Map a Part) Identity) (OddCycle a)
-> State (Map a Part) (Maybe (OddCycle a))
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT MaybeT (StateT (Map a Part) Identity) (OddCycle a)
dfs) Map a Part
forall k a. Map k a
Map.empty of
(Maybe (OddCycle a)
Nothing, Map a Part
partMap) -> AdjacencyMap a a -> Either (OddCycle a) (AdjacencyMap a a)
forall a b. b -> Either a b
Right (AdjacencyMap a a -> Either (OddCycle a) (AdjacencyMap a a))
-> AdjacencyMap a a -> Either (OddCycle a) (AdjacencyMap a a)
forall a b. (a -> b) -> a -> b
$ (a -> Either a a) -> AdjacencyMap a -> AdjacencyMap a a
forall a b c.
(Ord a, Ord b, Ord c) =>
(a -> Either b c) -> AdjacencyMap a -> AdjacencyMap b c
toBipartiteWith (Map a Part -> a -> Either a a
forall {b}. Ord b => Map b Part -> b -> Either b b
toEither Map a Part
partMap) AdjacencyMap a
g
(Just OddCycle a
c , Map a Part
_ ) -> OddCycle a -> Either (OddCycle a) (AdjacencyMap a a)
forall a b. a -> Either a b
Left (OddCycle a -> Either (OddCycle a) (AdjacencyMap a a))
-> OddCycle a -> Either (OddCycle a) (AdjacencyMap a a)
forall a b. (a -> b) -> a -> b
$ OddCycle a -> OddCycle a
forall {a}. Eq a => [a] -> [a]
oddCycle OddCycle a
c
where
g :: AdjacencyMap a
g = AdjacencyMap a -> AdjacencyMap a
forall a. Ord a => AdjacencyMap a -> AdjacencyMap a
AM.symmetricClosure AdjacencyMap a
x
dfs :: MaybeT (StateT (Map a Part) Identity) (OddCycle a)
dfs = [MaybeT (StateT (Map a Part) Identity) (OddCycle a)]
-> MaybeT (StateT (Map a Part) Identity) (OddCycle a)
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum [ a -> MaybeT (StateT (Map a Part) Identity) (OddCycle a)
processVertex a
v | a
v <- AdjacencyMap a -> OddCycle a
forall a. AdjacencyMap a -> [a]
AM.vertexList AdjacencyMap a
g ]
processVertex :: a -> MaybeT (StateT (Map a Part) Identity) (OddCycle a)
processVertex a
v = do partMap <- StateT (Map a Part) Identity (Map a Part)
-> MaybeT (StateT (Map a Part) Identity) (Map a Part)
forall (m :: * -> *) a. Monad m => m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift StateT (Map a Part) Identity (Map a Part)
forall (m :: * -> *) s. Monad m => StateT s m s
get
guard (Map.notMember v partMap)
inVertex LeftPart v
inVertex :: Part -> a -> MaybeT (StateT (Map a Part) Identity) (OddCycle a)
inVertex Part
vertexPart a
v = (a
v a -> OddCycle a -> OddCycle a
forall a. a -> [a] -> [a]
:) (OddCycle a -> OddCycle a)
-> MaybeT (StateT (Map a Part) Identity) (OddCycle a)
-> MaybeT (StateT (Map a Part) Identity) (OddCycle a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> do
StateT (Map a Part) Identity ()
-> MaybeT (StateT (Map a Part) Identity) ()
forall (m :: * -> *) a. Monad m => m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (StateT (Map a Part) Identity ()
-> MaybeT (StateT (Map a Part) Identity) ())
-> StateT (Map a Part) Identity ()
-> MaybeT (StateT (Map a Part) Identity) ()
forall a b. (a -> b) -> a -> b
$ (Map a Part -> Map a Part) -> StateT (Map a Part) Identity ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify (a -> Part -> Map a Part -> Map a Part
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert a
v Part
vertexPart)
let otherVertexPart :: Part
otherVertexPart = Part -> Part
otherPart Part
vertexPart
[MaybeT (StateT (Map a Part) Identity) (OddCycle a)]
-> MaybeT (StateT (Map a Part) Identity) (OddCycle a)
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum [ Part -> a -> MaybeT (StateT (Map a Part) Identity) (OddCycle a)
onEdge Part
otherVertexPart a
u | a
u <- Set a -> OddCycle a
forall a. Set a -> [a]
Set.toAscList (a -> AdjacencyMap a -> Set a
forall a. Ord a => a -> AdjacencyMap a -> Set a
AM.postSet a
v AdjacencyMap a
g) ]
{-# INLINE onEdge #-}
onEdge :: Part -> a -> MaybeT (StateT (Map a Part) Identity) (OddCycle a)
onEdge Part
vertexPart a
v = do partMap <- StateT (Map a Part) Identity (Map a Part)
-> MaybeT (StateT (Map a Part) Identity) (Map a Part)
forall (m :: * -> *) a. Monad m => m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift StateT (Map a Part) Identity (Map a Part)
forall (m :: * -> *) s. Monad m => StateT s m s
get
case Map.lookup v partMap of
Maybe Part
Nothing -> Part -> a -> MaybeT (StateT (Map a Part) Identity) (OddCycle a)
inVertex Part
vertexPart a
v
Just Part
part -> do Bool -> MaybeT (StateT (Map a Part) Identity) ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Part
vertexPart Part -> Part -> Bool
forall a. Eq a => a -> a -> Bool
/= Part
part)
OddCycle a -> MaybeT (StateT (Map a Part) Identity) (OddCycle a)
forall a. a -> MaybeT (StateT (Map a Part) Identity) a
forall (m :: * -> *) a. Monad m => a -> m a
return [a
v]
toEither :: Map b Part -> b -> Either b b
toEither Map b Part
partMap b
v = case Maybe Part -> Part
forall a. HasCallStack => Maybe a -> a
fromJust (b -> Map b Part -> Maybe Part
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup b
v Map b Part
partMap) of
Part
LeftPart -> b -> Either b b
forall a b. a -> Either a b
Left b
v
Part
RightPart -> b -> Either b b
forall a b. b -> Either a b
Right b
v
oddCycle :: [a] -> [a]
oddCycle [a]
pathToCycle = [a] -> [a]
forall a. HasCallStack => [a] -> [a]
init ([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
lastVertex) [a]
pathToCycle
where
lastVertex :: a
lastVertex = [a] -> a
forall a. HasCallStack => [a] -> a
last [a]
pathToCycle
data Matching a b = Matching {
forall a b. Matching a b -> Map a b
pairOfLeft :: Map a b,
forall a b. Matching a b -> Map b a
pairOfRight :: Map b a
} deriving (forall x. Matching a b -> Rep (Matching a b) x)
-> (forall x. Rep (Matching a b) x -> Matching a b)
-> Generic (Matching a b)
forall x. Rep (Matching a b) x -> Matching a b
forall x. Matching a b -> Rep (Matching a b) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a b x. Rep (Matching a b) x -> Matching a b
forall a b x. Matching a b -> Rep (Matching a b) x
$cfrom :: forall a b x. Matching a b -> Rep (Matching a b) x
from :: forall x. Matching a b -> Rep (Matching a b) x
$cto :: forall a b x. Rep (Matching a b) x -> Matching a b
to :: forall x. Rep (Matching a b) x -> Matching a b
Generic
instance (Show a, Show b) => Show (Matching a b) where
showsPrec :: Int -> Matching a b -> ShowS
showsPrec Int
_ Matching a b
m = String -> ShowS
showString String
"matching " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(a, b)] -> ShowS
forall a. Show a => [a] -> ShowS
showList (Map a b -> [(a, b)]
forall k a. Map k a -> [(k, a)]
Map.toAscList (Map a b -> [(a, b)]) -> Map a b -> [(a, b)]
forall a b. (a -> b) -> a -> b
$ Matching a b -> Map a b
forall a b. Matching a b -> Map a b
pairOfLeft Matching a b
m)
instance (Eq a, Eq b) => Eq (Matching a b) where
Matching a b
x == :: Matching a b -> Matching a b -> Bool
== Matching a b
y = Matching a b -> Map a b
forall a b. Matching a b -> Map a b
pairOfLeft Matching a b
x Map a b -> Map a b -> Bool
forall a. Eq a => a -> a -> Bool
== Matching a b -> Map a b
forall a b. Matching a b -> Map a b
pairOfLeft Matching a b
y
instance (Ord a, Ord b) => Ord (Matching a b) where
compare :: Matching a b -> Matching a b -> Ordering
compare Matching a b
x Matching a b
y = Map a b -> Map a b -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Matching a b -> Map a b
forall a b. Matching a b -> Map a b
pairOfLeft Matching a b
x) (Matching a b -> Map a b
forall a b. Matching a b -> Map a b
pairOfLeft Matching a b
y)
addEdgeUnsafe :: (Ord a, Ord b) => a -> b -> Matching a b -> Matching a b
addEdgeUnsafe :: forall a b.
(Ord a, Ord b) =>
a -> b -> Matching a b -> Matching a b
addEdgeUnsafe a
a b
b (Matching Map a b
ab Map b a
ba) = Map a b -> Map b a -> Matching a b
forall a b. Map a b -> Map b a -> Matching a b
Matching (a -> b -> Map a b -> Map a b
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert a
a b
b Map a b
ab) (b -> a -> Map b a -> Map b a
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert b
b a
a Map b a
ba)
addEdge :: (Ord a, Ord b) => a -> b -> Matching a b -> Matching a b
addEdge :: forall a b.
(Ord a, Ord b) =>
a -> b -> Matching a b -> Matching a b
addEdge a
a b
b (Matching Map a b
ab Map b a
ba) = a -> b -> Matching a b -> Matching a b
forall a b.
(Ord a, Ord b) =>
a -> b -> Matching a b -> Matching a b
addEdgeUnsafe a
a b
b (Map a b -> Map b a -> Matching a b
forall a b. Map a b -> Map b a -> Matching a b
Matching Map a b
ab' Map b a
ba')
where
ab' :: Map a b
ab' = case b
b b -> Map b a -> Maybe a
forall k a. Ord k => k -> Map k a -> Maybe a
`Map.lookup` Map b a
ba of
Maybe a
Nothing -> a -> Map a b -> Map a b
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete a
a Map a b
ab
Just a
a' -> a -> Map a b -> Map a b
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete a
a (a -> Map a b -> Map a b
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete a
a' Map a b
ab)
ba' :: Map b a
ba' = case a
a a -> Map a b -> Maybe b
forall k a. Ord k => k -> Map k a -> Maybe a
`Map.lookup` Map a b
ab of
Maybe b
Nothing -> b -> Map b a -> Map b a
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete b
b Map b a
ba
Just b
b' -> b -> Map b a -> Map b a
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete b
b (b -> Map b a -> Map b a
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete b
b' Map b a
ba)
leftCovered :: Ord a => a -> Matching a b -> Bool
leftCovered :: forall a b. Ord a => a -> Matching a b -> Bool
leftCovered a
a = a -> Map a b -> Bool
forall k a. Ord k => k -> Map k a -> Bool
Map.member a
a (Map a b -> Bool)
-> (Matching a b -> Map a b) -> Matching a b -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matching a b -> Map a b
forall a b. Matching a b -> Map a b
pairOfLeft
matching :: (Ord a, Ord b) => [(a, b)] -> Matching a b
matching :: forall a b. (Ord a, Ord b) => [(a, b)] -> Matching a b
matching = (Matching a b -> (a, b) -> Matching a b)
-> Matching a b -> [(a, b)] -> Matching a b
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (((a, b) -> Matching a b -> Matching a b)
-> Matching a b -> (a, b) -> Matching a b
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((a -> b -> Matching a b -> Matching a b)
-> (a, b) -> Matching a b -> Matching a b
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry a -> b -> Matching a b -> Matching a b
forall a b.
(Ord a, Ord b) =>
a -> b -> Matching a b -> Matching a b
addEdge)) (Map a b -> Map b a -> Matching a b
forall a b. Map a b -> Map b a -> Matching a b
Matching Map a b
forall k a. Map k a
Map.empty Map b a
forall k a. Map k a
Map.empty)
isMatchingOf :: (Ord a, Ord b) => Matching a b -> AdjacencyMap a b -> Bool
isMatchingOf :: forall a b.
(Ord a, Ord b) =>
Matching a b -> AdjacencyMap a b -> Bool
isMatchingOf m :: Matching a b
m@(Matching Map a b
ab Map b a
_) AdjacencyMap a b
g = Matching a b -> Bool
forall a b. (Ord a, Ord b) => Matching a b -> Bool
consistentMatching Matching a b
m
Bool -> Bool -> Bool
&& [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and [ a -> b -> AdjacencyMap a b -> Bool
forall a b. (Ord a, Ord b) => a -> b -> AdjacencyMap a b -> Bool
hasEdge a
a b
b AdjacencyMap a b
g | (a
a, b
b) <- Map a b -> [(a, b)]
forall k a. Map k a -> [(k, a)]
Map.toList Map a b
ab ]
matchingSize :: Matching a b -> Int
matchingSize :: forall a b. Matching a b -> Int
matchingSize = Map a b -> Int
forall k a. Map k a -> Int
Map.size (Map a b -> Int)
-> (Matching a b -> Map a b) -> Matching a b -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matching a b -> Map a b
forall a b. Matching a b -> Map a b
pairOfLeft
maxMatching :: (Ord a, Ord b) => AdjacencyMap a b -> Matching a b
maxMatching :: forall a b. (Ord a, Ord b) => AdjacencyMap a b -> Matching a b
maxMatching AdjacencyMap a b
graph = (forall s. ST s (Matching a b)) -> Matching a b
forall a. (forall s. ST s a) -> a
runST (AdjacencyMap a b -> ST s (Matching a b)
forall a b s.
(Ord a, Ord b) =>
AdjacencyMap a b -> ST s (Matching a b)
maxMatchingHK AdjacencyMap a b
graph)
data HKState s a b = HKState
{ forall s a b. HKState s a b -> STRef s (Map a Int)
distance :: STRef s (Map a Int)
, forall s a b. HKState s a b -> STRef s (Matching a b)
curMatching :: STRef s (Matching a b)
, forall s a b. HKState s a b -> STRef s (Seq a)
queue :: STRef s (Seq a)
, forall s a b. HKState s a b -> STRef s (Set a)
visited :: STRef s (Set a) }
maxMatchingHK :: forall a b s. (Ord a, Ord b) => AdjacencyMap a b -> ST s (Matching a b)
maxMatchingHK :: forall a b s.
(Ord a, Ord b) =>
AdjacencyMap a b -> ST s (Matching a b)
maxMatchingHK AdjacencyMap a b
g = do
distance <- Map a Int -> ST s (STRef s (Map a Int))
forall a s. a -> ST s (STRef s a)
newSTRef Map a Int
forall k a. Map k a
Map.empty
curMatching <- newSTRef (Matching Map.empty Map.empty)
queue <- newSTRef Seq.empty
visited <- newSTRef Set.empty
runHK (HKState distance curMatching queue visited)
readSTRef curMatching
where
runHK :: HKState s a b -> ST s ()
runHK :: HKState s a b -> ST s ()
runHK HKState s a b
state = do STRef s (Map a Int) -> Map a Int -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef (HKState s a b -> STRef s (Map a Int)
forall s a b. HKState s a b -> STRef s (Map a Int)
distance HKState s a b
state) Map a Int
forall k a. Map k a
Map.empty
foundAugmentingPath <- HKState s a b -> ST s Bool
bfs HKState s a b
state
when foundAugmentingPath $ do
writeSTRef (visited state) Set.empty
dfs state
runHK state
currentlyUncovered :: HKState s a b -> ST s [a]
currentlyUncovered :: HKState s a b -> ST s [a]
currentlyUncovered HKState s a b
state = do
m <- STRef s (Matching a b) -> ST s (Matching a b)
forall s a. STRef s a -> ST s a
readSTRef (HKState s a b -> STRef s (Matching a b)
forall s a b. HKState s a b -> STRef s (Matching a b)
curMatching HKState s a b
state)
return [ v | v <- leftVertexList g, not (leftCovered v m) ]
bfs :: HKState s a b -> ST s Bool
bfs :: HKState s a b -> ST s Bool
bfs HKState s a b
state = do
uncovered <- HKState s a b -> ST s [a]
currentlyUncovered HKState s a b
state
mapM_ (enqueue state 1) uncovered
bfsLoop state
enqueue :: HKState s a b -> Int -> a -> ST s ()
enqueue :: HKState s a b -> Int -> a -> ST s ()
enqueue HKState s a b
state Int
d a
v = do STRef s (Map a Int) -> (Map a Int -> Map a Int) -> ST s ()
forall s a. STRef s a -> (a -> a) -> ST s ()
modifySTRef (HKState s a b -> STRef s (Map a Int)
forall s a b. HKState s a b -> STRef s (Map a Int)
distance HKState s a b
state) (a -> Int -> Map a Int -> Map a Int
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert a
v Int
d)
STRef s (Seq a) -> (Seq a -> Seq a) -> ST s ()
forall s a. STRef s a -> (a -> a) -> ST s ()
modifySTRef (HKState s a b -> STRef s (Seq a)
forall s a b. HKState s a b -> STRef s (Seq a)
queue HKState s a b
state) (Seq a -> a -> Seq a
forall a. Seq a -> a -> Seq a
|> a
v)
dequeue :: HKState s a b -> ST s (Maybe a)
dequeue :: HKState s a b -> ST s (Maybe a)
dequeue HKState s a b
state = do q <- STRef s (Seq a) -> ST s (Seq a)
forall s a. STRef s a -> ST s a
readSTRef (HKState s a b -> STRef s (Seq a)
forall s a b. HKState s a b -> STRef s (Seq a)
queue HKState s a b
state)
case Seq.viewl q of
a
a :< Seq a
q -> STRef s (Seq a) -> Seq a -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef (HKState s a b -> STRef s (Seq a)
forall s a b. HKState s a b -> STRef s (Seq a)
queue HKState s a b
state) Seq a
q ST s () -> Maybe a -> ST s (Maybe a)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> a -> Maybe a
forall a. a -> Maybe a
Just a
a
ViewL a
EmptyL -> Maybe a -> ST s (Maybe a)
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing
bfsLoop :: HKState s a b -> ST s Bool
bfsLoop :: HKState s a b -> ST s Bool
bfsLoop HKState s a b
state = HKState s a b -> ST s (Maybe a)
dequeue HKState s a b
state ST s (Maybe a) -> (Maybe a -> ST s Bool) -> ST s Bool
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Just a
v -> do p <- HKState s a b -> a -> ST s Bool
bfsVertex HKState s a b
state a
v
q <- bfsLoop state
return (p || q)
Maybe a
Nothing -> Bool -> ST s Bool
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
bfsVertex :: HKState s a b -> a -> ST s Bool
bfsVertex :: HKState s a b -> a -> ST s Bool
bfsVertex HKState s a b
state a
v = do dist <- STRef s (Map a Int) -> ST s (Map a Int)
forall s a. STRef s a -> ST s a
readSTRef (HKState s a b -> STRef s (Map a Int)
forall s a b. HKState s a b -> STRef s (Map a Int)
distance HKState s a b
state)
let d = Maybe Int -> Int
forall a. HasCallStack => Maybe a -> a
fromJust (a
v a -> Map a Int -> Maybe Int
forall k a. Ord k => k -> Map k a -> Maybe a
`Map.lookup` Map a Int
dist) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
or <$> mapM (bfsEdge state d) (neighbours v)
checkEnqueue :: HKState s a b -> Int -> a -> ST s ()
checkEnqueue :: HKState s a b -> Int -> a -> ST s ()
checkEnqueue HKState s a b
state Int
d a
v = do dist <- STRef s (Map a Int) -> ST s (Map a Int)
forall s a. STRef s a -> ST s a
readSTRef (HKState s a b -> STRef s (Map a Int)
forall s a b. HKState s a b -> STRef s (Map a Int)
distance HKState s a b
state)
when (v `Map.notMember` dist) (enqueue state d v)
bfsEdge :: HKState s a b -> Int -> b -> ST s Bool
bfsEdge :: HKState s a b -> Int -> b -> ST s Bool
bfsEdge HKState s a b
state Int
d b
u = do m <- STRef s (Matching a b) -> ST s (Matching a b)
forall s a. STRef s a -> ST s a
readSTRef (HKState s a b -> STRef s (Matching a b)
forall s a b. HKState s a b -> STRef s (Matching a b)
curMatching HKState s a b
state)
case u `Map.lookup` pairOfRight m of
Just a
v -> HKState s a b -> Int -> a -> ST s ()
checkEnqueue HKState s a b
state Int
d a
v ST s () -> Bool -> ST s Bool
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Bool
False
Maybe a
Nothing -> Bool -> ST s Bool
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
dfs :: HKState s a b -> ST s ()
dfs :: HKState s a b -> ST s ()
dfs HKState s a b
state = HKState s a b -> ST s [a]
currentlyUncovered HKState s a b
state ST s [a] -> ([a] -> ST s ()) -> ST s ()
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (a -> ST s Bool) -> [a] -> ST s ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (HKState s a b -> Int -> a -> ST s Bool
dfsVertex HKState s a b
state Int
0)
dfsVertex :: HKState s a b -> Int -> a -> ST s Bool
dfsVertex :: HKState s a b -> Int -> a -> ST s Bool
dfsVertex HKState s a b
state Int
d a
v = do dist <- STRef s (Map a Int) -> ST s (Map a Int)
forall s a. STRef s a -> ST s a
readSTRef (HKState s a b -> STRef s (Map a Int)
forall s a b. HKState s a b -> STRef s (Map a Int)
distance HKState s a b
state)
vis <- readSTRef (visited state)
let dv = Maybe Int -> Int
forall a. HasCallStack => Maybe a -> a
fromJust (a
v a -> Map a Int -> Maybe Int
forall k a. Ord k => k -> Map k a -> Maybe a
`Map.lookup` Map a Int
dist)
case (d + 1 == dv) && (v `Set.notMember` vis) of
Bool
False -> Bool -> ST s Bool
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
Bool
True -> do STRef s (Set a) -> (Set a -> Set a) -> ST s ()
forall s a. STRef s a -> (a -> a) -> ST s ()
modifySTRef (HKState s a b -> STRef s (Set a)
forall s a b. HKState s a b -> STRef s (Set a)
visited HKState s a b
state) (a -> Set a -> Set a
forall a. Ord a => a -> Set a -> Set a
Set.insert a
v)
HKState s a b -> Int -> a -> [b] -> ST s Bool
dfsEdges HKState s a b
state Int
dv a
v (a -> [b]
neighbours a
v)
dfsEdges :: HKState s a b -> Int -> a -> [b] -> ST s Bool
dfsEdges :: HKState s a b -> Int -> a -> [b] -> ST s Bool
dfsEdges HKState s a b
_ Int
_ a
_ [] = Bool -> ST s Bool
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
dfsEdges HKState s a b
state Int
d a
a (b
b:[b]
bs) = do m <- STRef s (Matching a b) -> ST s (Matching a b)
forall s a. STRef s a -> ST s a
readSTRef (HKState s a b -> STRef s (Matching a b)
forall s a b. HKState s a b -> STRef s (Matching a b)
curMatching HKState s a b
state)
case b `Map.lookup` pairOfRight m of
Maybe a
Nothing -> HKState s a b -> a -> b -> ST s ()
addEdge HKState s a b
state a
a b
b ST s () -> Bool -> ST s Bool
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Bool
True
Just a
w -> HKState s a b -> Int -> a -> ST s Bool
dfsVertex HKState s a b
state Int
d a
w ST s Bool -> (Bool -> ST s Bool) -> ST s Bool
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Bool
True -> HKState s a b -> a -> b -> ST s ()
addEdge HKState s a b
state a
a b
b ST s () -> Bool -> ST s Bool
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Bool
True
Bool
False -> HKState s a b -> Int -> a -> [b] -> ST s Bool
dfsEdges HKState s a b
state Int
d a
a [b]
bs
addEdge :: HKState s a b -> a -> b -> ST s ()
addEdge :: HKState s a b -> a -> b -> ST s ()
addEdge HKState s a b
state a
a b
b = STRef s (Matching a b) -> (Matching a b -> Matching a b) -> ST s ()
forall s a. STRef s a -> (a -> a) -> ST s ()
modifySTRef (HKState s a b -> STRef s (Matching a b)
forall s a b. HKState s a b -> STRef s (Matching a b)
curMatching HKState s a b
state) (a -> b -> Matching a b -> Matching a b
forall a b.
(Ord a, Ord b) =>
a -> b -> Matching a b -> Matching a b
addEdgeUnsafe a
a b
b)
neighbours :: a -> [b]
neighbours :: a -> [b]
neighbours a
a = Set b -> [b]
forall a. Set a -> [a]
Set.toAscList (Set b -> [b]) -> Set b -> [b]
forall a b. (a -> b) -> a -> b
$ Maybe (Set b) -> Set b
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (Set b) -> Set b) -> Maybe (Set b) -> Set b
forall a b. (a -> b) -> a -> b
$ a -> Map a (Set b) -> Maybe (Set b)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup a
a (Map a (Set b) -> Maybe (Set b)) -> Map a (Set b) -> Maybe (Set b)
forall a b. (a -> b) -> a -> b
$ AdjacencyMap a b -> Map a (Set b)
forall a b. AdjacencyMap a b -> Map a (Set b)
leftAdjacencyMap AdjacencyMap a b
g
type VertexCover a b = (Set a, Set b)
isVertexCoverOf :: (Ord a, Ord b) => (Set a, Set b) -> AdjacencyMap a b -> Bool
isVertexCoverOf :: forall a b.
(Ord a, Ord b) =>
(Set a, Set b) -> AdjacencyMap a b -> Bool
isVertexCoverOf (Set a
as, Set b
bs) AdjacencyMap a b
g = Set a
as Set a -> Set a -> Bool
forall a. Ord a => Set a -> Set a -> Bool
`Set.isSubsetOf` AdjacencyMap a b -> Set a
forall a b. AdjacencyMap a b -> Set a
leftVertexSet AdjacencyMap a b
g
Bool -> Bool -> Bool
&& Set b
bs Set b -> Set b -> Bool
forall a. Ord a => Set a -> Set a -> Bool
`Set.isSubsetOf` AdjacencyMap a b -> Set b
forall a b. AdjacencyMap a b -> Set b
rightVertexSet AdjacencyMap a b
g
Bool -> Bool -> Bool
&& [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and [ a
a a -> Set a -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set a
as Bool -> Bool -> Bool
|| b
b b -> Set b -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set b
bs | (a
a, b
b) <- AdjacencyMap a b -> [(a, b)]
forall a b. AdjacencyMap a b -> [(a, b)]
edgeList AdjacencyMap a b
g ]
vertexCoverSize :: VertexCover a b -> Int
vertexCoverSize :: forall a b. VertexCover a b -> Int
vertexCoverSize (Set a
as, Set b
bs) = Set a -> Int
forall a. Set a -> Int
Set.size Set a
as Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Set b -> Int
forall a. Set a -> Int
Set.size Set b
bs
minVertexCover :: (Ord a, Ord b) => AdjacencyMap a b -> VertexCover a b
minVertexCover :: forall a b. (Ord a, Ord b) => AdjacencyMap a b -> VertexCover a b
minVertexCover AdjacencyMap a b
g = VertexCover a b
-> Either (VertexCover a b) (List a b) -> VertexCover a b
forall a b. a -> Either a b -> a
fromLeft VertexCover a b
forall {a}. a
panic (Either (VertexCover a b) (List a b) -> VertexCover a b)
-> Either (VertexCover a b) (List a b) -> VertexCover a b
forall a b. (a -> b) -> a -> b
$ Matching a b
-> AdjacencyMap a b -> Either (VertexCover a b) (List a b)
forall a b.
(Ord a, Ord b) =>
Matching a b
-> AdjacencyMap a b -> Either (VertexCover a b) (List a b)
augmentingPath (AdjacencyMap a b -> Matching a b
forall a b. (Ord a, Ord b) => AdjacencyMap a b -> Matching a b
maxMatching AdjacencyMap a b
g) AdjacencyMap a b
g
where
panic :: a
panic = String -> a
forall a. HasCallStack => String -> a
error String
"minVertexCover: internal error (found augmenting path)"
type IndependentSet a b = (Set a, Set b)
isIndependentSetOf :: (Ord a, Ord b) => (Set a, Set b) -> AdjacencyMap a b -> Bool
isIndependentSetOf :: forall a b.
(Ord a, Ord b) =>
(Set a, Set b) -> AdjacencyMap a b -> Bool
isIndependentSetOf (Set a
as, Set b
bs) AdjacencyMap a b
g = Set a
as Set a -> Set a -> Bool
forall a. Ord a => Set a -> Set a -> Bool
`Set.isSubsetOf` AdjacencyMap a b -> Set a
forall a b. AdjacencyMap a b -> Set a
leftVertexSet AdjacencyMap a b
g
Bool -> Bool -> Bool
&& Set b
bs Set b -> Set b -> Bool
forall a. Ord a => Set a -> Set a -> Bool
`Set.isSubsetOf` AdjacencyMap a b -> Set b
forall a b. AdjacencyMap a b -> Set b
rightVertexSet AdjacencyMap a b
g
Bool -> Bool -> Bool
&& [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and [ Bool -> Bool
not (a
a a -> Set a -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set a
as Bool -> Bool -> Bool
&& b
b b -> Set b -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set b
bs) | (a
a, b
b) <- AdjacencyMap a b -> [(a, b)]
forall a b. AdjacencyMap a b -> [(a, b)]
edgeList AdjacencyMap a b
g ]
independentSetSize :: IndependentSet a b -> Int
independentSetSize :: forall a b. VertexCover a b -> Int
independentSetSize (Set a
as, Set b
bs) = Set a -> Int
forall a. Set a -> Int
Set.size Set a
as Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Set b -> Int
forall a. Set a -> Int
Set.size Set b
bs
maxIndependentSet :: (Ord a, Ord b) => AdjacencyMap a b -> IndependentSet a b
maxIndependentSet :: forall a b. (Ord a, Ord b) => AdjacencyMap a b -> VertexCover a b
maxIndependentSet AdjacencyMap a b
g =
(AdjacencyMap a b -> Set a
forall a b. AdjacencyMap a b -> Set a
leftVertexSet AdjacencyMap a b
g Set a -> Set a -> Set a
forall a. Ord a => Set a -> Set a -> Set a
`Set.difference` Set a
as, AdjacencyMap a b -> Set b
forall a b. AdjacencyMap a b -> Set b
rightVertexSet AdjacencyMap a b
g Set b -> Set b -> Set b
forall a. Ord a => Set a -> Set a -> Set a
`Set.difference` Set b
bs)
where
(Set a
as, Set b
bs) = AdjacencyMap a b -> (Set a, Set b)
forall a b. (Ord a, Ord b) => AdjacencyMap a b -> VertexCover a b
minVertexCover AdjacencyMap a b
g
augmentingPath :: (Ord a, Ord b) => Matching a b -> AdjacencyMap a b -> Either (VertexCover a b) (List a b)
augmentingPath :: forall a b.
(Ord a, Ord b) =>
Matching a b
-> AdjacencyMap a b -> Either (VertexCover a b) (List a b)
augmentingPath = Matching a b
-> AdjacencyMap a b -> Either (VertexCover a b) (List a b)
forall a b.
(Ord a, Ord b) =>
Matching a b
-> AdjacencyMap a b -> Either (VertexCover a b) (List a b)
augmentingPathImpl
type AugPathMonad a b = MaybeT (State (VertexCover a b)) (List a b)
augmentingPathImpl :: forall a b. (Ord a, Ord b) => Matching a b -> AdjacencyMap a b -> Either (VertexCover a b) (List a b)
augmentingPathImpl :: forall a b.
(Ord a, Ord b) =>
Matching a b
-> AdjacencyMap a b -> Either (VertexCover a b) (List a b)
augmentingPathImpl Matching a b
m AdjacencyMap a b
g = case State (VertexCover a b) (Maybe (List a b))
-> VertexCover a b -> (Maybe (List a b), VertexCover a b)
forall s a. State s a -> s -> (a, s)
runState (MaybeT (State (VertexCover a b)) (List a b)
-> State (VertexCover a b) (Maybe (List a b))
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT MaybeT (State (VertexCover a b)) (List a b)
dfs) (AdjacencyMap a b -> Set a
forall a b. AdjacencyMap a b -> Set a
leftVertexSet AdjacencyMap a b
g, Set b
forall a. Set a
Set.empty) of
(Maybe (List a b)
Nothing , VertexCover a b
cover) -> VertexCover a b -> Either (VertexCover a b) (List a b)
forall a b. a -> Either a b
Left VertexCover a b
cover
(Just List a b
path, VertexCover a b
_ ) -> List a b -> Either (VertexCover a b) (List a b)
forall a b. b -> Either a b
Right List a b
path
where
dfs :: AugPathMonad a b
dfs :: MaybeT (State (VertexCover a b)) (List a b)
dfs = [MaybeT (State (VertexCover a b)) (List a b)]
-> MaybeT (State (VertexCover a b)) (List a b)
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum [ a -> MaybeT (State (VertexCover a b)) (List a b)
inVertex a
v | a
v <- AdjacencyMap a b -> [a]
forall a b. AdjacencyMap a b -> [a]
leftVertexList AdjacencyMap a b
g, Bool -> Bool
not (a -> Matching a b -> Bool
forall a b. Ord a => a -> Matching a b -> Bool
leftCovered a
v Matching a b
m) ]
inVertex :: a -> AugPathMonad a b
inVertex :: a -> MaybeT (State (VertexCover a b)) (List a b)
inVertex a
a = do (as, bs) <- State (VertexCover a b) (VertexCover a b)
-> MaybeT (State (VertexCover a b)) (VertexCover a b)
forall (m :: * -> *) a. Monad m => m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift State (VertexCover a b) (VertexCover a b)
forall (m :: * -> *) s. Monad m => StateT s m s
get
guard (a `Set.member` as)
lift $ put (Set.delete a as, bs)
asum [ onEdge a b | b <- neighbours a ]
onEdge :: a -> b -> AugPathMonad a b
onEdge :: a -> b -> MaybeT (State (VertexCover a b)) (List a b)
onEdge a
a b
b = a -> b -> List a b -> List a b
addEdge a
a b
b (List a b -> List a b)
-> MaybeT (State (VertexCover a b)) (List a b)
-> MaybeT (State (VertexCover a b)) (List a b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> do (as, bs) <- State (VertexCover a b) (VertexCover a b)
-> MaybeT (State (VertexCover a b)) (VertexCover a b)
forall (m :: * -> *) a. Monad m => m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift State (VertexCover a b) (VertexCover a b)
forall (m :: * -> *) s. Monad m => StateT s m s
get
lift $ put (as, Set.insert b bs)
case b `Map.lookup` pairOfRight m of
Just a
a -> a -> MaybeT (State (VertexCover a b)) (List a b)
inVertex a
a
Maybe a
Nothing -> List a b -> MaybeT (State (VertexCover a b)) (List a b)
forall a. a -> MaybeT (State (VertexCover a b)) a
forall (m :: * -> *) a. Monad m => a -> m a
return List a b
forall a b. List a b
Nil
addEdge :: a -> b -> List a b -> List a b
addEdge :: a -> b -> List a b -> List a b
addEdge a
a b
b = a -> List b a -> List a b
forall a b. a -> List b a -> List a b
Cons a
a (List b a -> List a b)
-> (List a b -> List b a) -> List a b -> List a b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> List a b -> List b a
forall a b. a -> List b a -> List a b
Cons b
b
neighbours :: a -> [b]
neighbours :: a -> [b]
neighbours a
a = Set b -> [b]
forall a. Set a -> [a]
Set.toAscList (Set b -> [b]) -> Set b -> [b]
forall a b. (a -> b) -> a -> b
$ Maybe (Set b) -> Set b
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (Set b) -> Set b) -> Maybe (Set b) -> Set b
forall a b. (a -> b) -> a -> b
$ a -> Map a (Set b) -> Maybe (Set b)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup a
a (Map a (Set b) -> Maybe (Set b)) -> Map a (Set b) -> Maybe (Set b)
forall a b. (a -> b) -> a -> b
$ AdjacencyMap a b -> Map a (Set b)
forall a b. AdjacencyMap a b -> Map a (Set b)
leftAdjacencyMap AdjacencyMap a b
g
consistentMatching :: (Ord a, Ord b) => Matching a b -> Bool
consistentMatching :: forall a b. (Ord a, Ord b) => Matching a b -> Bool
consistentMatching (Matching Map a b
ab Map b a
ba) =
Map a b -> [(a, b)]
forall k a. Map k a -> [(k, a)]
Map.toAscList Map a b
ab [(a, b)] -> [(a, b)] -> Bool
forall a. Eq a => a -> a -> Bool
== [(a, b)] -> [(a, b)]
forall a. Ord a => [a] -> [a]
sort [ (a
a, b
b) | (b
b, a
a) <- Map b a -> [(b, a)]
forall k a. Map k a -> [(k, a)]
Map.toAscList Map b a
ba ]