Commit 9ae395eb authored by Alexandre Delanoë's avatar Alexandre Delanoë

[ILouvain] HyperGraph funs before clean.

parent 7f38878d
...@@ -7,7 +7,7 @@ Maintainer : alexandre.delanoe+louvain@iscpif.fr ...@@ -7,7 +7,7 @@ Maintainer : alexandre.delanoe+louvain@iscpif.fr
Stability : experimental Stability : experimental
Portability : POSIX Portability : POSIX
ILouvain: really inductive Graph clustering with destructives updates ILouvain: inductive Graph clustering with destructives updates
metagraph (plural metagraphs) (mathematics) A representation of a set of nodes and the morphisms relating them metagraph (plural metagraphs) (mathematics) A representation of a set of nodes and the morphisms relating them
https://en.wiktionary.org/wiki/metagraph https://en.wiktionary.org/wiki/metagraph
...@@ -37,10 +37,11 @@ data NodePath = AllNodes | DfsNodes ...@@ -37,10 +37,11 @@ data NodePath = AllNodes | DfsNodes
-- MetaGraph (x,y) where x is space (hyper structure of labels), y is -- MetaGraph (x,y) where x is space (hyper structure of labels), y is
-- time like (stream structure) -- time like (stream structure)
-- (Below LabGraph definition) -- (Below LabGraph definition)
type HyperGraph' a b c = Gr (HyperGraph a b) c type HyperGraph' a b c = Gr (HyperGraph a b) c
type HyperContext' a b c = Context (HyperGraph a b) c
type HyperGraph a b = Gr (Gr () a) b type HyperGraph a b = Gr (Gr () a) b
type HyperContext a b = Context (Gr () a) b type HyperContext a b = Context (Gr () a) b
-- TODO: EdgeGraph (StreamGraph) -- TODO: EdgeGraph (StreamGraph)
-- type StreamGraph a b = Gr a (Gr () b) -- type StreamGraph a b = Gr a (Gr () b)
...@@ -49,6 +50,10 @@ type HyperContext a b = Context (Gr () a) b ...@@ -49,6 +50,10 @@ type HyperContext a b = Context (Gr () a) b
type MaxIterations = Int type MaxIterations = Int
type MaxSize = Int type MaxSize = Int
type Start a = HyperGraph' a a a
type Trans a = HyperGraph' a a a
type Final a = HyperGraph' a a a
------------------------------------------------------------------------
iLouvain :: (Eq a, Show a) iLouvain :: (Eq a, Show a)
=> MaxIterations => MaxIterations
-> MaxSize -> MaxSize
...@@ -62,6 +67,18 @@ iLouvain n s p g ...@@ -62,6 +67,18 @@ iLouvain n s p g
where where
g' = iLouvain (n-1) s p g g' = iLouvain (n-1) s p g
iLouvainH :: (Eq a, Show a)
=> MaxIterations
-> MaxSize
-> NodePath
-> Start a
-> Final a
iLouvainH 0 s p g = g
iLouvainH n s p g
| length (toNodes' g') <= s = g'
| otherwise = iLouvainH' p g g'
where
g' = iLouvainH (n-1) s p g
------------------------------------------------------------------------ ------------------------------------------------------------------------
iLouvain' :: (Eq a, Show a) iLouvain' :: (Eq a, Show a)
=> NodePath => NodePath
...@@ -78,6 +95,23 @@ iLouvain' p g g' = -- trace (show ps :: Text) ...@@ -78,6 +95,23 @@ iLouvain' p g g' = -- trace (show ps :: Text)
DfsNodes -> path' g DfsNodes -> path' g
else sortOn (length . hnodes g') (nodes g') else sortOn (length . hnodes g') (nodes g')
iLouvainH' :: (Eq a, Show a)
=> NodePath
-> Start a
-> Trans a
-> Final a
iLouvainH' p g g' = -- trace (show ps :: Text)
iLouvainH'' g g' ps -- $ filter (\n -> elem n (nodes g)) ps
where
-- quick trick to filter path but path of HyperGraph can be different
ps = if isFlat' g'
then case p of
AllNodes -> nodes g
DfsNodes -> path' g
else sortOn (length . hnodes' g') (nodes g')
------------------------------------------------------------------------
iLouvain'' :: Show a iLouvain'' :: Show a
=> HyperGraph a a => HyperGraph a a
-> HyperGraph a a -> HyperGraph a a
...@@ -87,9 +121,19 @@ iLouvain'' g g' ns = foldl' (\g1 n -> trace (show (n, toNodes g1) :: Text) ...@@ -87,9 +121,19 @@ iLouvain'' g g' ns = foldl' (\g1 n -> trace (show (n, toNodes g1) :: Text)
$ stepMax g g1 n $ stepMax g g1 n
$ neighborhood g g1 n ) g' ns $ neighborhood g g1 n ) g' ns
iLouvainH'' :: Show a
=> Start a
-> Trans a
-> [Node]
-> Final a
iLouvainH'' g g' ns = foldl' (\g1 n -> trace (show (n, toNodes' g1) :: Text)
$ stepMax' g g1 n
$ neighborhood' g g1 n ) g' ns
------------------------------------------------------------------------
-- | Neighborhood definition -- | Neighborhood definition
-- TODO optim sort by jackard -- TODO optim sort by jackard
-- TODO remove first Graph
-- TODO Tests -- TODO Tests
neighborhood :: HyperGraph a a -> HyperGraph a a -> Node -> [Node] neighborhood :: HyperGraph a a -> HyperGraph a a -> Node -> [Node]
neighborhood g g' n = case isFlat g' of neighborhood g g' n = case isFlat g' of
...@@ -98,45 +142,28 @@ neighborhood g g' n = case isFlat g' of ...@@ -98,45 +142,28 @@ neighborhood g g' n = case isFlat g' of
&& (not . Set.null) (Set.intersection (fromList $ hnodes g m) (hood g g' n)) && (not . Set.null) (Set.intersection (fromList $ hnodes g m) (hood g g' n))
) (nodes g') ) (nodes g')
neighborhood' :: HyperGraph' a a a -> HyperGraph' a a a -> Node -> [Node]
neighborhood' g g' n = case isFlat' g' of
True -> neighbors g' n
False -> filter (\m -> m /= n
&& (not . Set.null) (Set.intersection (fromList $ hnodes' g m) (hood' g g' n))
) (nodes g')
-------------------------
hood :: HyperGraph a a -> HyperGraph a a -> Node -> Set Node hood :: HyperGraph a a -> HyperGraph a a -> Node -> Set Node
hood g g' n = H.exclusion (fromList ns) candidates hood g g' n = H.exclusion (fromList ns) candidates
where where
candidates = fromList $ concat $ map (neighbors g) ns candidates = fromList $ concat $ map (neighbors g) ns
ns = hnodes g' n ns = hnodes g' n
hood' :: HyperGraph' a a a -> HyperGraph' a a a -> Node -> Set Node
step :: Show a hood' g g' n = H.exclusion (fromList ns) candidates
=> HyperGraph a b
-> HyperGraph a a
-> Node
-> [Node]
-> HyperGraph a a
step g g' n ns = -- trace ("step'" :: Text) $
foldl' (\g1 n' -> case match n g1 of
(Nothing, _) -> g1
(Just _, _ ) -> step' g g1 n n'
) g' ns
step' :: Show a
=> HyperGraph a b
-> HyperGraph a a
-> Node
-> Node
-> HyperGraph a a
step' g g' n1 n2 = -- trace ("step " <> show n1 <> " " <> show n2 :: Text) $
if s2 > 0 && s2 >= s1
-- if s2 >= s1
then -- trace ("step:mv " <> show n1 <> " " <> show n2 :: Text) $
mv g' [n1] [n2]
else -- trace ("step:else" :: Text) $
g'
where where
s1 = -- trace ("step:mod1" :: Text) $ candidates = fromList $ concat $ map (neighbors g) ns
imodularity g g' [n1] ns = hnodes' g' n
s2 = -- trace ("step:mod2" :: Text) $
imodularity g g' [n1,n2]
-- | Here we need more depth in the HyperGraph ------------------------------------------------------------------------
-- | Here we need more depth in the HyperGraph => HyperGraph'
stepMax :: Show a stepMax :: Show a
=> HyperGraph a b => HyperGraph a b
-> HyperGraph a a -> HyperGraph a a
...@@ -152,24 +179,61 @@ stepMax g g' x xs = ...@@ -152,24 +179,61 @@ stepMax g g' x xs =
) g' ) g'
$ zip (x:xs) xs $ zip (x:xs) xs
------------------------------------------------------------------------ -------------------------------------------------------------------------
class IsHyperGraph a where stepMax' :: Show a
toHyperGraph_ :: Gr () Double -> a => Start a
hnodes_ :: a -> Node -> [Node] -> Trans a
toNodes_ :: a -> [[Node]] -> Node
-> [Node]
-> Final a
stepMax' g g' x xs =
maximumBy (\(g1) (g2) -> compare (gmodularity' g g1) (gmodularity' g g2))
$ scanl (\g'' (p,n) -> trace (show (p,n) :: Text) $
if p == x
then mvH g'' [x] [n]
else mvH g'' [p,x] [n]
) g'
$ zip (x:xs) xs
mv_ :: a -> [Node] -> [Node] -> a
------------------------------------------------------------------------
class IsHyperGraph gr where
toHyperGraph_ :: Gr () a -> gr a a
-- flat is to HyperGraph what is empty to Graph -- flat is to HyperGraph what is empty to Graph
flat_ :: a isFlat_ :: gr a b -> Bool
isFlat_ :: a -> Bool
hnodes_ :: gr a b -> Node -> [Node]
toNodes_ :: gr a b -> [[Node]]
imodularity_ :: gr a b -> gr a b -> [Node] -> Double
gmodularity_ :: gr a b -> gr a b -> Double
mv_ :: gr a b -> [Node] -> [Node] -> gr a b
-- hdeg_ :: a -> Node -> Maybe Int
------------------------------------------------------------------------
{-
instance IsHyperGraph HyperGraph
where
toHyperGraph_ g = nmap (\_ -> empty) g
isFlat_ = isFlat
imodularity_ :: a -> a -> [Node] -> Double hnodes_ g n = case match n g of
gmodularity_ :: a -> a -> Double (Nothing , _) -> []
(Just (p, n, l, s), _) -> n : nodes l
toNodes_ g = map (hnodes g) (nodes g)
imodularity_ = imodularity
gmodularity_ = gmodularity
mv_ = mv
-}
hdeg_ :: a -> Node -> Maybe Int
------------------------------------------------------------------------ ------------------------------------------------------------------------
hnodes :: HyperGraph a b -> Node -> [Node] hnodes :: HyperGraph a b -> Node -> [Node]
hnodes g n = case match n g of hnodes g n = case match n g of
(Nothing , _) -> [] (Nothing , _) -> []
...@@ -288,7 +352,9 @@ mvH :: Show a ...@@ -288,7 +352,9 @@ mvH :: Show a
=> HyperGraph' a a a => HyperGraph' a a a
-> [Node] -> [Node] -> [Node] -> [Node]
-> HyperGraph' a a a -> HyperGraph' a a a
mvH = undefined mvH g [ ] [ ] = g
mvH g [_] [ ] = g
mvH g [ ] [_] = g
...@@ -298,7 +364,6 @@ mv :: Show a => HyperGraph a a ...@@ -298,7 +364,6 @@ mv :: Show a => HyperGraph a a
mv g [ ] [ ] = g mv g [ ] [ ] = g
mv g [_] [ ] = g mv g [_] [ ] = g
mv g [ ] [_] = g mv g [ ] [_] = g
mv g [a] [b] = case a == b of mv g [a] [b] = case a == b of
True -> panic "mv, impossible: from node == dest node" True -> panic "mv, impossible: from node == dest node"
False -> mv' g a b False -> mv' g a b
...@@ -309,7 +374,6 @@ mv g [a,b] [ ] = case match a g of ...@@ -309,7 +374,6 @@ mv g [a,b] [ ] = case match a g of
& ((p , n , delNode b l , s ) & ((p , n , delNode b l , s )
& g1) & g1)
(Nothing, _) -> panic "mv: snd path does not exist" (Nothing, _) -> panic "mv: snd path does not exist"
mv g [a,b] [c] = mv (mv g [a,b] []) [b] [c] mv g [a,b] [c] = mv (mv g [a,b] []) [b] [c]
mv g _ _ = panic "mv:todo long path" mv g _ _ = panic "mv:todo long path"
...@@ -319,7 +383,7 @@ mv g _ _ = panic "mv:todo long path" ...@@ -319,7 +383,7 @@ mv g _ _ = panic "mv:todo long path"
mv' :: Show a => HyperGraph a a mv' :: Show a => HyperGraph a a
-> Node -> Node -> Node -> Node
-> HyperGraph a a -> HyperGraph a a
mv' g n1 n2 = -- trace (show (c1,c2) :: Text) $ mv' g n1 n2 = -- trace (show (c1,c2) :: Text) $
(mvMContext c1 c2) & g2 (mvMContext c1 c2) & g2
where where
(c1, g1) = match n1 g (c1, g1) = match n1 g
...@@ -332,14 +396,22 @@ mvMContext (Just (a1 ,n ,l ,a2 )) ...@@ -332,14 +396,22 @@ mvMContext (Just (a1 ,n ,l ,a2 ))
(Just (a1',n',l',a2')) = (a1',n', merge l' (c & l),a2') (Just (a1',n',l',a2')) = (a1',n', merge l' (c & l),a2')
where where
c = (a1, n, (), a2) c = (a1, n, (), a2)
mvMContext _ (Just _) = panic "mvMContext: First Node does not exist" mvMContext _ (Just _) = panic "mvMContext: First Node does not exist"
mvMContext (Just _) _ = panic "mvMContext: Snd Node does not exist" mvMContext (Just _) _ = panic "mvMContext: Snd Node does not exist"
mvMContext _ _ = panic "mvMContext: Both Nodes do not exist" mvMContext _ _ = panic "mvMContext: Both Nodes do not exist"
merge :: (Graph gr, DynGraph gr) {-
=> gr a b -> gr a b -> gr a b mvMContext' :: Maybe (HyperContext' a a a)
merge = ufold (&) -> Maybe (HyperContext' a a a)
-> HyperContext' a a a
mvMContext' (Just (a1 ,n ,l ,a2 ))
(Just (a1',n',l',a2')) = (a1',n', (c & l'),a2')
where
c = (a1, n, labNodes l, a2)
mvMContext' _ (Just _) = panic "mvMContext': First Node does not exist"
mvMContext' (Just _) _ = panic "mvMContext': Snd Node does not exist"
mvMContext' _ _ = panic "mvMContext': Both Nodes do not exist"
-}
------------------------------------------------------------------------ ------------------------------------------------------------------------
test_mv :: (Ord a, Show a) => HyperGraph a a -> Node -> Node -> Bool test_mv :: (Ord a, Show a) => HyperGraph a a -> Node -> Node -> Bool
...@@ -362,5 +434,47 @@ path g' = map sortNodes cs ...@@ -362,5 +434,47 @@ path g' = map sortNodes cs
path' :: (DynGraph gr, Eq b) => gr a b -> [Node] path' :: (DynGraph gr, Eq b) => gr a b -> [Node]
path' = maybe [] identity . head . path path' = maybe [] identity . head . path
------------------------------------------------------------------------
-- FGL specific functions
merge :: (Graph gr, DynGraph gr)
=> gr a b -> gr a b -> gr a b
merge = ufold (&)
------------------------------------------------------------------------ ------------------------------------------------------------------------
------------------------------------------------------------------------ ------------------------------------------------------------------------
------------------------------------------------------------------------
-- TO DELETE
step :: Show a
=> HyperGraph a b
-> HyperGraph a a
-> Node
-> [Node]
-> HyperGraph a a
step g g' n ns = -- trace ("step'" :: Text) $
foldl' (\g1 n' -> case match n g1 of
(Nothing, _) -> g1
(Just _, _ ) -> step' g g1 n n'
) g' ns
step' :: Show a
=> HyperGraph a b
-> HyperGraph a a
-> Node
-> Node
-> HyperGraph a a
step' g g' n1 n2 = -- trace ("step " <> show n1 <> " " <> show n2 :: Text) $
if s2 > 0 && s2 >= s1
-- if s2 >= s1
then -- trace ("step:mv " <> show n1 <> " " <> show n2 :: Text) $
mv g' [n1] [n2]
else -- trace ("step:else" :: Text) $
g'
where
s1 = -- trace ("step:mod1" :: Text) $
imodularity g g' [n1]
s2 = -- trace ("step:mod2" :: Text) $
imodularity g g' [n1,n2]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment