Commit 1141e6bd authored by Alexandre Delanoë's avatar Alexandre Delanoë

[ILouvain] ok, to be qualitatively tested

parent ea8646e5
...@@ -9,13 +9,17 @@ Portability : POSIX ...@@ -9,13 +9,17 @@ Portability : POSIX
ILouvain: really inductive Graph clustering with destructives updates ILouvain: really inductive Graph clustering with destructives updates
todo FGL improvements:
- deg should have return type Maybe Int
- match should be Maybe (Context, Graph)
-} -}
module Data.Graph.Clustering.ILouvain module Data.Graph.Clustering.ILouvain
where where
import Debug.SimpleReflect import Debug.SimpleReflect
import Data.Set (fromList) import Data.Set (fromList, Set)
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Maybe (catMaybes, maybe) import Data.Maybe (catMaybes, maybe)
import Data.List (zip, cycle, null) import Data.List (zip, cycle, null)
...@@ -40,18 +44,29 @@ isFlat :: HyperGraph a b -> Bool ...@@ -40,18 +44,29 @@ isFlat :: HyperGraph a b -> Bool
isFlat g = all (isEmpty . snd) (labNodes g) isFlat g = all (isEmpty . snd) (labNodes g)
------------------------------------------------------------------------ ------------------------------------------------------------------------
type MaxIterations = Int
type MaxSize = Int
iLouvain :: (Eq a, Show a) iLouvain :: (Eq a, Show a)
=> Int -> NodePath -> HyperGraph a a -> HyperGraph a a => MaxIterations
iLouvain 0 p g = g -> MaxSize
iLouvain n p g = trace (show $ toNodes g :: Text) $ -> NodePath
iLouvain' p g (iLouvain (n-1) p g) -> HyperGraph a a
-> HyperGraph a a
iLouvain 0 s p g = g
iLouvain n s p g
| length (toNodes g') <= s = g'
| otherwise = iLouvain' p g g'
where
g' = iLouvain (n-1) s p g
------------------------------------------------------------------------
iLouvain' :: (Eq a, Show a) iLouvain' :: (Eq a, Show a)
=> NodePath => NodePath
-> HyperGraph a a -> HyperGraph a a
-> HyperGraph a a -> HyperGraph a a
-> HyperGraph a a -> HyperGraph a a
iLouvain' p g g' = trace (show ps :: Text) iLouvain' p g g' = -- trace (show ps :: Text)
iLouvain'' g g' ps -- $ filter (\n -> elem n (nodes g)) ps iLouvain'' g g' ps -- $ filter (\n -> elem n (nodes g)) ps
where where
-- quick trick to filter path but path of HyperGraph can be different -- quick trick to filter path but path of HyperGraph can be different
...@@ -67,19 +82,25 @@ iLouvain'' :: Show a ...@@ -67,19 +82,25 @@ iLouvain'' :: Show a
-> [Node] -> [Node]
-> HyperGraph a a -> HyperGraph a a
iLouvain'' g g' [ ] = g' iLouvain'' g g' [ ] = g'
iLouvain'' g g' ns = foldl' (\g1 n -> step g g1 n $ ineighbors g1 n ) g' ns iLouvain'' g g' ns = foldl' (\g1 n -> step g g1 n $ neighborhood g g1 n ) g' ns
-- | ineihbors Definition -- | Neighborhood definition
-- TODO optim sort by jackard -- TODO optim sort by jackard
ineighbors :: HyperGraph a a -> Node -> [Node] -- TODO remove first Graph
ineighbors g n = case isEmpty g of -- TODO Tests
True -> neighbors g n neighborhood :: HyperGraph a a -> HyperGraph a a -> Node -> [Node]
False -> filter (\m -> Set.null (Set.intersection (fromList $ hnodes g m) n') neighborhood g g' n = case isFlat g' of
&& m /= n) (nodes g) True -> neighbors g' n
where False -> filter (\m -> m /= n
n' = H.exclusion candidates (fromList ns) && (not . Set.null) (Set.intersection (fromList $ hnodes g m) (hood g g' n))
candidates = fromList $ concat $ map (neighbors g) ns ) (nodes g')
ns = hnodes g n
hood :: HyperGraph a a -> HyperGraph a a -> Node -> Set Node
hood g g' n = H.exclusion (fromList ns) candidates
where
candidates = fromList $ concat $ map (neighbors g) ns
ns = hnodes g' n
step :: Show a step :: Show a
=> HyperGraph a b => HyperGraph a b
...@@ -102,15 +123,15 @@ step' :: Show a ...@@ -102,15 +123,15 @@ step' :: Show a
step' g g' n1 n2 = -- trace ("step " <> show n1 <> " " <> show n2 :: Text) $ step' g g' n1 n2 = -- trace ("step " <> show n1 <> " " <> show n2 :: Text) $
if s2 > 0 && s2 >= s1 if s2 > 0 && s2 >= s1
-- if s2 >= s1 -- if s2 >= s1
then trace ("step:mv " <> show n1 <> " " <> show n2 :: Text) $ then -- trace ("step:mv " <> show n1 <> " " <> show n2 :: Text) $
mv g' [n1] [n2] mv g' [n1] [n2]
else -- trace ("step:else" :: Text) $ else -- trace ("step:else" :: Text) $
g' g'
where where
s1 = -- trace ("step:mod1" :: Text) $ s1 = -- trace ("step:mod1" :: Text) $
imodularity g [n1] imodularity g g' [n1]
s2 = -- trace ("step:mod2" :: Text) $ s2 = -- trace ("step:mod2" :: Text) $
imodularity g [n1,n2] imodularity g g' [n1,n2]
stepMax :: Show a stepMax :: Show a
=> HyperGraph a b => HyperGraph a b
...@@ -119,28 +140,28 @@ stepMax :: Show a ...@@ -119,28 +140,28 @@ stepMax :: Show a
-> [Node] -> [Node]
-> HyperGraph a a -> HyperGraph a a
stepMax g g' n ns = snd stepMax g g' n ns = snd
$ maximumBy (\(n1,g1) (n2,g2) -> compare (imodularity g [n1]) (imodularity g [n2])) gs $ maximumBy (\(n1,g1) (n2,g2) -> compare (imodularity g g1 [n1]) (imodularity g g2 [n2])) gs
where where
gs = (n, g') : map (\m -> (m, mv g' [n] [m])) ns gs = (n, g') : map (\m -> (m, mv g' [n] [m])) ns
------------------------------------------------------------------------ ------------------------------------------------------------------------
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 , _) -> []
(Just (p, n, l, s), _) -> n : nodes l (Just (p, n, l, s), _) -> n : nodes l
{- {-
hdeg :: Graph gr => gr a b -> Node -> Maybe Int hdeg :: Graph gr => gr a b -> Node -> Maybe Int
hdeg = undefined hdeg = undefined
-} -}
------------------------------------------------------------------------ ------------------------------------------------------------------------
-- TODO go depth in HyperGraph (modularity at level/depth) -- TODO go depth in HyperGraph (modularity at level/depth)
imodularity :: HyperGraph a b -> [Node] -> Double imodularity :: HyperGraph a b -> HyperGraph a a -> [Node] -> Double
imodularity g ns = -- trace ("imodul" :: Text) $ imodularity g g' ns = -- trace ("imodul" :: Text) $
H.hmodularity g H.hmodularity g
$ fromList $ fromList
$ concat $ concat
$ map (hnodes g) ns $ map (hnodes g') ns
------------------------------------------------------------------------ ------------------------------------------------------------------------
toHyperGraph :: Gr () Double -> HyperGraph Double Double toHyperGraph :: Gr () Double -> HyperGraph Double Double
......
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