Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
D
DSS
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Terraform modules
Analyze
Contributor analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Antoine Castillon
DSS
Commits
858ce3c3
Commit
858ce3c3
authored
3 years ago
by
Antoine Castillon
Browse files
Options
Downloads
Patches
Plain Diff
Upload New File
parent
45f28d82
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
tools.py
+436
-0
436 additions, 0 deletions
tools.py
with
436 additions
and
0 deletions
tools.py
0 → 100644
+
436
−
0
View file @
858ce3c3
import
networkx
as
nx
from
math
import
cos
,
sin
,
pi
,
ceil
import
random
as
rd
def
measure_visibility
(
S
,
all_qclqs
):
"
measure the min and average visibility of the quasi-cliques of all_qclqs with respect to S
"
def
visibility
(
Q
):
"
measure the visibility of Q with respect to S
"
maxi
=
0
for
Q2
in
S
:
vis_Q2_Q
=
len
(
set
(
Q2
)
&
set
(
Q
))
/
len
(
set
(
Q
))
# definition of the visibility
if
vis_Q2_Q
>
0.999
:
return
1
elif
vis_Q2_Q
>
maxi
:
maxi
=
vis_Q2_Q
return
maxi
if
len
(
all_qclqs
)
==
0
:
return
1
,
1
min_vis
=
1
avg_vis
=
0
for
Q
in
all_qclqs
:
vis_S_Q
=
visibility
(
Q
)
avg_vis
+=
vis_S_Q
min_vis
=
min
(
min_vis
,
vis_S_Q
)
return
avg_vis
/
len
(
all_qclqs
),
min_vis
def
load_graph
(
path2file
):
"
load a graph from a .txt file, each line of the .txt file corresponds to an edge
"
G
=
nx
.
Graph
()
file
=
open
(
path2file
,
'
r
'
)
line
=
file
.
readline
().
rstrip
(
'
\n\r
'
)
while
line
:
l
=
line
.
split
()
u
=
int
(
l
[
0
])
v
=
int
(
l
[
1
])
G
.
add_edge
(
u
,
v
)
line
=
file
.
readline
().
rstrip
(
'
\n\r
'
)
file
.
close
()
return
G
def
random_subgraph
(
G
,
n
,
n_0
):
"""
return H=(V
'
,E
'
) a random induced subgraph of G, H is generated according to the following rules:
- n_0 first vertices are added to V
'
- add vertices from the neighbours of V
'
until |V
'
|=n
rk : this function uses the random package, use rd.seed(new_seed) to modify the seed
"""
V_prime
=
list
(
G
.
nodes
)
rd
.
shuffle
(
V_prime
)
V_prime
=
set
(
V_prime
[:
n_0
])
initials
=
V_prime
.
copy
()
candidates
=
set
()
for
u
in
V_prime
:
candidates
=
candidates
|
set
(
G
[
u
])
candidates
-=
V_prime
candidates
=
list
(
candidates
)
while
len
(
V_prime
)
<
n
:
if
len
(
candidates
)
>
0
:
i
=
rd
.
randrange
(
0
,
len
(
candidates
))
v
=
candidates
[
i
]
else
:
# assuming here that V-V' is not the empty set
l
=
list
(
set
(
G
.
nodes
)
-
set
(
V_prime
))
i
=
rd
.
randrange
(
0
,
len
(
l
))
v
=
l
[
i
]
V_prime
.
add
(
v
)
neigh_v
=
set
(
G
[
v
])
-
set
(
V_prime
)
-
set
(
candidates
)
candidates
=
candidates
+
list
(
neigh_v
)
candidates
.
remove
(
v
)
H
=
G
.
subgraph
(
V_prime
)
H2
=
nx
.
Graph
()
H2
.
add_nodes_from
(
H
.
nodes
)
H2
.
add_edges_from
(
H
.
edges
)
return
H2
,
initials
def
add_rd_edges
(
G
,
n_edges
):
"
add n_edges new random edges to G
"
n
=
len
(
G
.
nodes
)
non_edges
=
[(
j
,
i
)
for
i
in
range
(
1
,
n
)
for
j
in
range
(
i
)]
for
(
u
,
v
)
in
G
.
edges
:
non_edges
.
remove
((
u
,
v
))
rd
.
shuffle
(
non_edges
)
G
.
add_edges_from
(
non_edges
[:
n_edges
])
def
rd_nodes_to_supernodes
(
G
,
min_supernode_size
=
10
,
max_supernode_size
=
10
,
proba_clique
=
1
):
"
transforme les sommets d
'
un graphe en ensemble de sommets (cliques ou anticliques)
"
n
=
len
(
G
.
nodes
)
supernodes
=
[]
last_node
=
-
1
# on a deja utilise tous les sommets de 0 a last_node
for
i
in
range
(
n
):
supernode_size
=
rd
.
randrange
(
min_supernode_size
,
max_supernode_size
+
1
)
supernodes
.
append
([
last_node
+
1
+
j
for
j
in
range
(
supernode_size
)])
last_node
+=
supernode_size
G2
=
nx
.
Graph
()
G2
.
add_nodes_from
(
range
(
last_node
+
1
))
for
i_U
in
range
(
1
,
n
):
SU
=
supernodes
[
i_U
]
for
i_V
in
range
(
i_U
):
if
G
.
has_edge
(
i_U
,
i_V
):
SV
=
supernodes
[
i_V
]
G2
.
add_edges_from
([(
u
,
v
)
for
u
in
SU
for
v
in
SV
])
if
rd
.
random
()
<=
proba_clique
:
G2
.
add_edges_from
([(
SU
[
i
],
SU
[
j
])
for
i
in
range
(
1
,
len
(
SU
))
for
j
in
range
(
i
)])
return
G2
,
supernodes
def
compare_graphe
(
G1
,
G2
):
"
renvoie la taille de la difference symetrique des arretes de G1 et G2
"
diff
=
len
(
set
(
G1
.
edges
)
-
set
(
G2
.
edges
))
+
len
(
set
(
G2
.
edges
)
-
set
(
G1
.
edges
))
return
diff
def
position_affichage
(
G
,
list_comm
):
"
calcule une position d
'
affichage pour les sommets d
'
un graphe de communautes
"
pos
=
{}
distance
=
30
distance_au_centre
=
10
angle
=
2
*
pi
/
len
(
list_comm
)
pas_encore_vu
=
set
(
G
.
nodes
)
for
i
,
C
in
enumerate
(
list_comm
):
centre_x
=
distance
*
cos
(
i
*
angle
)
centre_y
=
distance
*
sin
(
i
*
angle
)
copy_pas_encore_vu
=
pas_encore_vu
.
copy
()
for
u
in
(
copy_pas_encore_vu
&
set
(
C
)):
pas_encore_vu
.
remove
(
u
)
x
=
(
2
*
rd
.
random
()
-
1
)
*
distance_au_centre
+
centre_x
y
=
(
2
*
rd
.
random
()
-
1
)
*
distance_au_centre
+
centre_y
pos
[
u
]
=
(
x
,
y
)
for
u
in
pas_encore_vu
:
x
=
(
2
*
rd
.
random
()
-
1
)
*
distance_au_centre
y
=
(
2
*
rd
.
random
()
-
1
)
*
distance_au_centre
pos
[
u
]
=
(
x
,
y
)
return
pos
def
barycentre
(
l
):
"
calcule le barycentre d
'
une liste de points
"
if
len
(
l
)
==
0
:
return
(
0
,
0
)
S_x
=
0
S_y
=
0
for
(
x
,
y
)
in
l
:
S_x
+=
x
S_y
+=
y
return
(
S_x
/
len
(
l
),
S_y
/
len
(
l
))
def
position_affichage2
(
G
,
list_comm
):
"
calcule une position d
'
affichage pour les sommets d
'
un graphe de communautes
"
pos
=
{}
distance
=
50
distance_au_centre
=
10
angle
=
2
*
pi
/
len
(
list_comm
)
centres
=
[[]
for
i
in
range
(
len
(
G
.
nodes
))]
for
i
,
C
in
enumerate
(
list_comm
):
centre_x
=
distance
*
cos
(
i
*
angle
)
centre_y
=
distance
*
sin
(
i
*
angle
)
for
u
in
C
:
centres
[
u
].
append
((
centre_x
,
centre_y
))
for
u
in
G
.
nodes
:
(
x
,
y
)
=
barycentre
(
centres
[
u
])
dx
=
(
2
*
rd
.
random
()
-
1
)
*
distance_au_centre
dy
=
(
2
*
rd
.
random
()
-
1
)
*
distance_au_centre
pos
[
u
]
=
(
x
+
dx
,
y
+
dy
)
return
pos
def
position_affichage3
(
list_comm
):
"
calcule une position d
'
affichage pour les sommets d
'
un graphe de communautes
"
pos
=
{}
distance
=
50
distance_au_centre
=
10
angle
=
2
*
pi
/
len
(
list_comm
)
for
i
,
C
in
enumerate
(
list_comm
):
centre_x
=
distance
*
cos
(
i
*
angle
)
centre_y
=
distance
*
sin
(
i
*
angle
)
angle_2
=
2
*
pi
/
len
(
C
)
for
j
,
u
in
enumerate
(
C
):
dx
=
distance_au_centre
*
cos
(
j
*
angle_2
)
dy
=
distance_au_centre
*
sin
(
j
*
angle_2
)
pos
[
u
]
=
(
centre_x
+
dx
,
centre_y
+
dy
)
return
pos
def
position_affichage4
(
list_comm
,
pos_centres
):
"
calcule une position d
'
affichage pour les sommets d
'
un graphe de communautes
"
pos
=
{}
distance_au_centre
=
1
for
i
,
C
in
enumerate
(
list_comm
):
centre_x
=
pos_centres
[
i
][
0
]
centre_y
=
pos_centres
[
i
][
1
]
angle_2
=
2
*
pi
/
len
(
C
)
for
j
,
u
in
enumerate
(
C
):
dx
=
distance_au_centre
*
cos
(
j
*
angle_2
)
dy
=
distance_au_centre
*
sin
(
j
*
angle_2
)
pos
[
u
]
=
(
centre_x
+
dx
,
centre_y
+
dy
)
return
pos
def
node_in_comm
(
G
,
list_comm
):
dico
=
{}
for
i
in
range
(
len
(
list_comm
)):
C
=
list_comm
[
i
]
for
u
in
C
:
dico
[
u
]
=
i
return
dico
def
non_edges_inside_comms
(
G
,
list_comm
):
missing_edges
=
[]
for
C
in
list_comm
:
for
i
in
range
(
1
,
len
(
C
)):
for
j
in
range
(
i
):
u
=
C
[
i
]
v
=
C
[
j
]
#print(u,v,G[u])
if
not
(
v
in
G
[
u
]):
missing_edges
.
append
((
u
,
v
))
return
missing_edges
def
edges_outside_comms
(
G
,
list_comm
):
edges
=
[]
node_comm
=
node_in_comm
(
G
,
list_comm
)
for
(
i
,
j
)
in
G
.
edges
:
if
node_comm
[
i
]
!=
node_comm
[
j
]:
edges
.
append
((
i
,
j
))
return
edges
def
calcule_gamma
(
G
,
X
):
gamma_deg
=
1
gamma_density
=
0
for
u
in
X
:
gamma_u
=
len
(
set
(
X
)
&
set
(
G
[
u
]))
/
(
len
(
X
)
-
1
)
gamma_deg
=
min
(
gamma_deg
,
gamma_u
)
gamma_density
+=
gamma_u
gamma_density
/=
len
(
X
)
return
gamma_deg
,
gamma_density
def
est_deg_qclq
(
G
,
X
,
gamma
):
"
verifie que X est une gamma deg-qclq de G
"
for
u
in
X
:
if
len
(
set
(
X
)
&
set
(
G
[
u
]))
<
gamma
*
(
len
(
X
)
-
1
):
return
False
return
True
def
est_density_qclq
(
G
,
X
,
gamma
):
"
verifie que X est une gamma density-qclq de G
"
H
=
G
.
subgraph
(
X
)
return
(
2
*
len
(
H
.
edges
)
>
gamma
*
len
(
X
)
*
(
len
(
X
)
-
1
))
def
deleted_edges_in_comm
(
list_comm
,
edges_del
):
"
renvoie les arretes supprimees lors de edge_reduction qui sont dans une communaute
"
l
=
[]
for
(
u
,
v
)
in
edges_del
:
for
X
in
list_comm
:
if
(
u
in
X
)
and
(
v
in
X
):
l
.
append
((
u
,
v
))
return
l
def
deleted_nodes_in_comm
(
list_comm
,
nodes_del
):
"
renvoie les sommets supprimes lors de la reduction qui sont dans une communaute
"
l
=
set
()
nodes_del
=
set
(
nodes_del
)
for
X
in
list_comm
:
l
=
l
|
(
set
(
X
)
&
nodes_del
)
return
l
def
reduction
(
G
,
gamma
,
min_size
,
edge_red
=
False
):
"
delete the nodes (and edges) of G not contained in any quasi-cliques
"
def
edge_reduction
():
nb_deleted
=
0
list_edges
=
list
(
G
.
edges
).
copy
()
bound
=
ceil
(
2
*
gamma
*
(
min_size
-
1
))
-
min_size
for
(
u
,
v
)
in
list_edges
:
if
len
(
set
(
G
[
u
])
&
set
(
G
[
v
]))
<
bound
:
# condition of the lemma
G
.
remove_edge
(
u
,
v
)
nb_deleted
+=
1
edges_deleted
.
append
((
u
,
v
))
return
nb_deleted
def
node_reduction
():
nb_deleted
=
0
list_nodes
=
list
(
G
.
nodes
).
copy
()
for
u
in
list_nodes
:
if
len
(
G
[
u
])
<
ceil
(
gamma
*
(
min_size
-
1
)):
G
.
remove_node
(
u
)
nb_deleted
+=
1
nodes_deleted
.
append
(
u
)
return
nb_deleted
flag_reduction
=
True
while
flag_reduction
:
nb_edges_deleted
=
0
if
edge_red
:
nb_edges_deleted
=
edge_reduction
()
nb_nodes_deleted
=
node_reduction
()
flag_reduction
=
((
nb_edges_deleted
+
nb_nodes_deleted
)
>
0
)
def
only_maximal
(
Quasi_Cliques
):
max_Quasi_Cliques
=
[]
# If C is not maximal then there is C' before C such that C c C'
for
C
in
Quasi_Cliques
:
is_maximal
=
True
for
max_C
in
max_Quasi_Cliques
:
if
set
(
C
).
issubset
(
set
(
max_C
)):
is_maximal
=
False
break
if
is_maximal
:
max_Quasi_Cliques
.
append
(
list
(
C
))
return
max_Quasi_Cliques
def
connected_components
(
G
):
"
compute the connected components of G
"
n
=
len
(
G
.
nodes
)
nodes
=
list
(
G
.
nodes
)
colors
=
{}
for
i
in
range
(
n
):
u
=
nodes
[
i
]
colors
[
u
]
=
i
for
i
in
range
(
n
):
for
(
u
,
v
)
in
G
.
edges
:
coul
=
min
(
colors
[
u
],
colors
[
v
])
colors
[
u
]
=
coul
colors
[
v
]
=
coul
components
=
{}
comp_color
=
[]
for
u
in
G
.
nodes
:
if
colors
[
u
]
in
comp_color
:
components
[
colors
[
u
]].
append
(
u
)
else
:
comp_color
.
append
(
colors
[
u
])
components
[
colors
[
u
]]
=
[
u
]
return
list
(
components
.
values
())
edges_deleted
=
[]
nodes_deleted
=
[]
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment