Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
haskell-gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
145
Issues
145
List
Board
Labels
Milestones
Merge Requests
6
Merge Requests
6
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gargantext
haskell-gargantext
Commits
5d5ea0c2
Commit
5d5ea0c2
authored
Oct 28, 2019
by
Alexandre Delanoë
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev-maxClique' into dev
parents
593df28a
db5b08df
Pipeline
#605
failed with stage
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
166 additions
and
18 deletions
+166
-18
package.yaml
package.yaml
+2
-0
Utils.hs
src/Gargantext/Prelude/Utils.hs
+7
-0
FGL.hs
src/Gargantext/Viz/Graph/FGL.hs
+18
-0
IGraph.hs
src/Gargantext/Viz/Graph/IGraph.hs
+9
-1
MaxClique.hs
src/Gargantext/Viz/Graph/MaxClique.hs
+125
-0
Proxemy.hs
src/Gargantext/Viz/Graph/Proxemy.hs
+5
-17
No files found.
package.yaml
View file @
5d5ea0c2
...
@@ -160,6 +160,8 @@ library:
...
@@ -160,6 +160,8 @@ library:
-
profunctors
-
profunctors
-
protolude
-
protolude
-
pureMD5
-
pureMD5
-
random-shuffle
-
MonadRandom
-
SHA
-
SHA
-
simple-reflect
-
simple-reflect
-
cereal
# (IGraph)
-
cereal
# (IGraph)
...
...
src/Gargantext/Prelude/Utils.hs
View file @
5d5ea0c2
...
@@ -18,17 +18,24 @@ module Gargantext.Prelude.Utils
...
@@ -18,17 +18,24 @@ module Gargantext.Prelude.Utils
import
Control.Lens
(
view
)
import
Control.Lens
(
view
)
import
Control.Monad.Reader
(
MonadReader
)
import
Control.Monad.Reader
(
MonadReader
)
import
Control.Monad.IO.Class
(
MonadIO
,
liftIO
)
import
Control.Monad.IO.Class
(
MonadIO
,
liftIO
)
import
Control.Monad.Random.Class
(
MonadRandom
)
import
Data.Text
(
Text
)
import
Data.Text
(
Text
)
import
Control.Monad.Reader
(
ask
)
import
Control.Monad.Reader
(
ask
)
import
GHC.IO
(
FilePath
)
import
GHC.IO
(
FilePath
)
import
Gargantext.Prelude
import
Gargantext.Prelude
import
Gargantext.API.Settings
import
Gargantext.API.Settings
import
System.Random
(
newStdGen
)
import
System.Random
(
newStdGen
)
import
qualified
System.Random.Shuffle
as
SRS
import
System.Directory
(
createDirectoryIfMissing
)
import
System.Directory
(
createDirectoryIfMissing
)
import
qualified
Data.ByteString.Lazy.Char8
as
Char
import
qualified
Data.ByteString.Lazy.Char8
as
Char
import
qualified
Data.Digest.Pure.SHA
as
SHA
(
sha256
,
showDigest
)
import
qualified
Data.Digest.Pure.SHA
as
SHA
(
sha256
,
showDigest
)
import
qualified
Data.Text
as
Text
import
qualified
Data.Text
as
Text
shuffle
::
MonadRandom
m
=>
[
a
]
->
m
[
a
]
shuffle
ns
=
SRS
.
shuffleM
ns
type
FolderPath
=
FilePath
type
FolderPath
=
FilePath
type
FileName
=
FilePath
type
FileName
=
FilePath
...
...
src/Gargantext/Viz/Graph/FGL.hs
View file @
5d5ea0c2
...
@@ -45,6 +45,24 @@ edges = FGL.edges
...
@@ -45,6 +45,24 @@ edges = FGL.edges
nodes
::
Graph
gr
=>
gr
a
b
->
[
Node
]
nodes
::
Graph
gr
=>
gr
a
b
->
[
Node
]
nodes
=
FGL
.
nodes
nodes
=
FGL
.
nodes
------------------------------------------------------------------------
-- | Graph Tools
filterNeighbors
::
Graph_Undirected
->
Node
->
[
Node
]
filterNeighbors
g
n
=
List
.
nub
$
neighbors
g
n
-- Q: why not D.G.I.deg ? (Int as result)
degree
::
Graph_Undirected
->
Node
->
Double
degree
g
n
=
fromIntegral
$
List
.
length
(
filterNeighbors
g
n
)
vcount
::
Graph_Undirected
->
Double
vcount
=
fromIntegral
.
List
.
length
.
List
.
nub
.
nodes
-- | TODO tests, optim and use IGraph library, fix IO ?
ecount
::
Graph_Undirected
->
Double
ecount
=
fromIntegral
.
List
.
length
.
List
.
nub
.
edges
------------------------------------------------------------------
------------------------------------------------------------------
-- | Main sugared functions
-- | Main sugared functions
...
...
src/Gargantext/Viz/Graph/IGraph.hs
View file @
5d5ea0c2
...
@@ -19,6 +19,7 @@ import Data.Serialize (Serialize)
...
@@ -19,6 +19,7 @@ import Data.Serialize (Serialize)
import
Data.Singletons
(
SingI
)
import
Data.Singletons
(
SingI
)
import
Gargantext.Prelude
import
Gargantext.Prelude
import
IGraph
hiding
(
mkGraph
,
neighbors
,
edges
,
nodes
,
Node
,
Graph
)
import
IGraph
hiding
(
mkGraph
,
neighbors
,
edges
,
nodes
,
Node
,
Graph
)
import
IGraph.Algorithms.Clique
as
IAC
import
qualified
IGraph
as
IG
import
qualified
IGraph
as
IG
import
qualified
Data.List
as
List
import
qualified
Data.List
as
List
...
@@ -46,10 +47,17 @@ edges = IG.edges
...
@@ -46,10 +47,17 @@ edges = IG.edges
nodes
::
IG
.
Graph
d
v
e
->
[
Node
]
nodes
::
IG
.
Graph
d
v
e
->
[
Node
]
nodes
=
IG
.
nodes
nodes
=
IG
.
nodes
------------------------------------------------------------------
-- | Tools
maximalCliques
::
IG
.
Graph
d
v
e
->
[[
Int
]]
maximalCliques
g
=
IAC
.
maximalCliques
g
(
min'
,
max'
)
where
min'
=
0
max'
=
0
------------------------------------------------------------------
------------------------------------------------------------------
-- | Main sugared functions
-- | Main sugared functions
mkGraphUfromEdges
::
[(
Int
,
Int
)]
->
Graph_Undirected
mkGraphUfromEdges
::
[(
Int
,
Int
)]
->
Graph_Undirected
mkGraphUfromEdges
es
=
mkGraph
(
List
.
replicate
n
()
)
$
zip
es
$
repeat
()
mkGraphUfromEdges
es
=
mkGraph
(
List
.
replicate
n
()
)
$
zip
es
$
repeat
()
where
where
...
...
src/Gargantext/Viz/Graph/MaxClique.hs
0 → 100644
View file @
5d5ea0c2
{-| Module : Gargantext.Viz.Graph.MaxClique
Description : MaxCliques function
Copyright : (c) CNRS, 2017-Present
License : AGPL + CECILL v3
Maintainer : team@gargantext.org
Stability : experimental
Portability : POSIX
- First written by Bruno Gaume in Python (see below for details)
- Then written by Alexandre Delanoë in Haskell (see below for details)
# By Bruno Gaume:
def fast_maximal_cliques(g):
def rec_maximal_cliques(g, subv):
mc = []
if subv == []: # stop condition
return [[]]
else :
for i in range(len(subv)):
newsubv = [j for j in subv[i+1:len(subv)]
if (j in g.neighbors(subv[i]))]
mci = rec_maximal_cliques(g, newsubv)
for x in mci:
x.append(subv[i])
mc.append(x)
return mc
def purge(clust):
clustset = [set(x) for x in clust]
new_clust = []
for i in range(len(clustset)):
ok = True
for j in range(len(clustset)):
if clustset[i].issubset(clustset[j]) and (not (len(clustset[i]) == len(clustset[j])) ):
ok = False
if ok and (not (clustset[i] in new_clust)):
new_clust.append(clustset[i])
return [list(x) for x in new_clust]
# to optimize : rank the vertices on the degrees
subv = [(v.index, v.degree()) for v in g.vs()]
subv.sort(key = lambda z:z[1])
subv = [x for (x, y) in subv]
return purge(rec_maximal_cliques(g, subv))
-}
{-# LANGUAGE NoImplicitPrelude #-}
module
Gargantext.Viz.Graph.MaxClique
where
import
Gargantext.Prelude
import
Data.List
(
sortOn
,
nub
,
concat
,
length
)
import
Data.Set
(
Set
)
import
Data.Set
(
fromList
,
toList
,
isSubsetOf
)
import
Data.Graph.Inductive
hiding
(
Graph
,
neighbors
,
subgraph
,
(
&
))
import
Gargantext.Viz.Graph.FGL
(
Graph_Undirected
,
degree
,
neighbors
,
mkGraphUfromEdges
)
type
Graph
=
Graph_Undirected
type
Neighbor
=
Node
maxCliques
::
Graph
->
[[
Node
]]
maxCliques
g
=
map
(
\
n
->
subMaxCliques
g
(
n
:
ns
))
ns
&
concat
&
takeMax
where
ns
::
[
Node
]
ns
=
sortOn
(
degree
g
)
$
nodes
g
subMaxCliques
::
Graph
->
[
Node
]
->
[[
Node
]]
subMaxCliques
_
[]
=
[
[]
]
subMaxCliques
g'
(
x
:
xs
)
=
add
x
$
subMaxCliques
g'
ns'
where
ns'
=
[
n
|
n
<-
xs
,
elem
n
$
neighborsOut
g'
x
]
add
::
Node
->
[[
Node
]]
->
[[
Node
]]
add
n
[]
=
[[
n
]]
add
n
(
m
:
ms
)
=
[
n
:
m
]
<>
add
n
ms
-- | Note, it is same as :
-- add n ns = map (\m -> n : m) ns
-- -- (but using pattern matching and recursivity)
-- -- (map is redefined in fact)
-- | To be sure self is not in neighbors of self
-- (out to exclude the self)
neighborsOut
::
Graph
->
Node
->
[
Node
]
neighborsOut
g''
n
=
filter
(
/=
n
)
$
neighbors
g''
n
takeMax
::
[[
Node
]]
->
[[
Node
]]
takeMax
=
map
toList
.
purge
.
map
fromList
.
sortOn
length
.
nub
where
purge
::
[
Set
Node
]
->
[
Set
Node
]
purge
[]
=
[]
purge
(
x
:
xs
)
=
x'
<>
purge
xs
where
x'
=
if
all
(
==
False
)
(
map
(
isSubsetOf
x
)
xs
)
then
[
x
]
else
[]
------------------------------------------------------------------------
test_graph
::
Graph
-- test_graph = mkGraphUfromEdges [(1,1), (2,2), (3,3)]
test_graph
=
mkGraphUfromEdges
[(
1
,
2
),
(
3
,
3
)]
test_graph'
::
Graph
test_graph'
=
mkGraphUfromEdges
[(
1
,
2
),
(
3
,
3
),
(
3
,
2
)]
test_graph''
::
Graph
test_graph''
=
mkGraphUfromEdges
[(
1
,
2
),
(
2
,
3
),
(
1
,
3
)]
test_graph'''
::
Graph
test_graph'''
=
mkGraphUfromEdges
[
(
4
,
1
)
,
(
4
,
2
)
,
(
3
,
1
)
,
(
3
,
2
)
,
(
2
,
1
)
]
src/Gargantext/Viz/Graph/Proxemy.hs
View file @
5d5ea0c2
...
@@ -95,7 +95,11 @@ prox_markov g ns l r nf = foldl' (\m _ -> spreading g m r nf) ms path
...
@@ -95,7 +95,11 @@ prox_markov g ns l r nf = foldl' (\m _ -> spreading g m r nf) ms path
_
->
Map
.
empty
_
->
Map
.
empty
spreading
::
Graph_Undirected
->
Map
Node
Double
->
FalseReflexive
->
NeighborsFilter
->
Map
Node
Double
spreading
::
Graph_Undirected
->
Map
Node
Double
->
FalseReflexive
->
NeighborsFilter
->
Map
Node
Double
spreading
g
ms
r
nf
=
Map
.
fromListWith
(
+
)
$
List
.
concat
$
map
pvalue
(
Map
.
keys
ms
)
spreading
g
ms
r
nf
=
Map
.
fromListWith
(
+
)
$
List
.
concat
$
map
pvalue
(
Map
.
keys
ms
)
where
where
-- TODO if list empty ...
-- TODO if list empty ...
...
@@ -107,22 +111,6 @@ spreading g ms r nf = Map.fromListWith (+) $ List.concat $ map pvalue (Map.keys
...
@@ -107,22 +111,6 @@ spreading g ms r nf = Map.fromListWith (+) $ List.concat $ map pvalue (Map.keys
neighborhood
=
(
nf
g
n
)
<>
(
if
r
then
[
n
]
else
[]
)
neighborhood
=
(
nf
g
n
)
<>
(
if
r
then
[
n
]
else
[]
)
------------------------------------------------------------------------
-- | Graph Tools
filterNeighbors
::
Graph_Undirected
->
Node
->
[
Node
]
filterNeighbors
g
n
=
List
.
nub
$
neighbors
g
n
degree
::
Graph_Undirected
->
Node
->
Double
degree
g
n
=
fromIntegral
$
List
.
length
(
filterNeighbors
g
n
)
vcount
::
Graph_Undirected
->
Double
vcount
=
fromIntegral
.
List
.
length
.
List
.
nub
.
nodes
-- | TODO tests, optim and use IGraph library, fix IO ?
ecount
::
Graph_Undirected
->
Double
ecount
=
fromIntegral
.
List
.
length
.
List
.
nub
.
edges
------------------------------------------------------------------------
------------------------------------------------------------------------
-- | Behavior tests
-- | Behavior tests
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment