Skip to content

Commit c55969f

Browse files
committed
Implemented the rest and optimized the search for a maximal 2-3-subgraph
1 parent cb54bc8 commit c55969f

1 file changed

Lines changed: 53 additions & 55 deletions

File tree

bar_yehuda_fvs.py

Lines changed: 53 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,43 @@
22
from collections import deque
33

44

5-
def dfs_remove_below_2(H, v):
6-
# Supprime récursivement les sommets de degré inférieur à 2
7-
# Pas de visited car vu qu'on supprime des noeuds, certains noeuds peuvent changer de degré
8-
if (v in H) and (H.degree(v) < 2):
9-
nb = set(H.neighbors(v))
10-
H.remove_node(v)
5+
def dfs_construct(G, H, v, visited, edges_visited):
6+
visited.add(v)
7+
for u in G.neighbors(v):
8+
edge = (min(v, u), max(v, u))
9+
if edge in edges_visited:
10+
continue
1111

12-
for u in nb:
13-
dfs_remove_below_2(H, u)
12+
edges_visited.add(edge)
13+
deg_u = H.degree[u] if u in H else 0
14+
deg_v = H.degree[v] if v in H else 0
15+
16+
if deg_u < 3 and deg_v < 3:
17+
H.add_edge(u, v)
18+
if u not in visited:
19+
dfs_construct(G, H, u, visited, edges_visited)
1420

1521

1622
def find_maximal_2_3_subgraph(G):
17-
# Sous-graphe maximal de G avec que des degrés entre 2 et 3 dans ce sous-graphe
18-
H = G.copy()
19-
20-
while any(H.degree(node) > 3 for node in H.nodes):
21-
node = next(n for n in H.nodes if H.degree(n) > 3)
22-
node_deg = H.degree(node)
23-
if node_deg > 3:
24-
m = node_deg - 3
25-
nb = sorted(
26-
list(H.neighbors(node)), key=lambda x: H.degree(x), reverse=True
27-
)
28-
for i in range(m):
29-
H.remove_edge(node, nb[i])
30-
31-
for node in set(H.nodes):
32-
dfs_remove_below_2(H, node)
23+
H = nx.Graph()
24+
visited = set()
25+
edges_visited = set()
26+
for node in G.nodes:
27+
if node not in visited:
28+
dfs_construct(G, H, node, visited, edges_visited)
29+
30+
to_remove = {n for n in H.nodes if H.degree(n) < 2}
31+
while len(to_remove) > 0:
32+
v = to_remove.pop()
33+
if v not in H:
34+
continue
35+
36+
nb = set(H.neighbors(v))
37+
H.remove_node(v)
38+
for u in nb:
39+
if u in H and H.degree[u] < 2:
40+
to_remove.add(u)
41+
3342
return H
3443

3544

@@ -67,44 +76,33 @@ def get_critical_linkpoints(G, H):
6776
return critical_linkpoints
6877

6978

79+
def is_cycle(G):
80+
return all(G.degree(n) == 2 for n in G.nodes)
81+
82+
83+
def get_set_covering_cycles(H, X, Y):
84+
sg = nx.subgraph(H, set(H.nodes) - X - Y)
85+
cover_set = set()
86+
87+
for comp in nx.connected_components(sg):
88+
comp_sg = nx.subgraph(sg, comp)
89+
if is_cycle(comp_sg):
90+
cover_set.add(next(iter(comp)))
91+
92+
return cover_set
93+
94+
7095
def subG_2_3(G):
96+
# Complexité pas linéaire à cause de get_critical_linkpoints
7197
if nx.is_forest(G):
7298
return set()
7399

74100
H = find_maximal_2_3_subgraph(G)
75101
X = get_critical_linkpoints(G, H)
76-
Y = {n for n in H.nodes if H.degree(n) > 2}
77-
pass
102+
Y = {n for n in H.nodes if H.degree(n) >= 3}
103+
W = get_set_covering_cycles(H, X, Y)
104+
return X | Y | W
78105

79106

80107
def get_decycling_number_bar_yehuda(G):
81108
return len(subG_2_3(G))
82-
83-
84-
if __name__ == "__main__":
85-
G = nx.Graph()
86-
edges = [
87-
(1, 2),
88-
(2, 3),
89-
(3, 4),
90-
(2, 4),
91-
(3, 5),
92-
(5, 6),
93-
(6, 7),
94-
(7, 5),
95-
]
96-
G.add_edges_from(edges)
97-
98-
# ajouter des sommets de degré 1 (feuilles) au graphe G existant
99-
G.add_edge(1, 8) # 8 devient un sommet de degré 1
100-
G.add_edge(6, 9) # 9 devient un sommet de degré 1
101-
G.add_edge(7, 10) # 10 devient un sommet de degré 1
102-
103-
print("Graph G:")
104-
print("Nodes:", G.nodes())
105-
print("Edges:", G.edges())
106-
#
107-
# decycling_number = get_decycling_number_bar_yehuda(G)
108-
# print("Decycling number (Bar-Yehuda method):", decycling_number)
109-
H = find_maximal_2_3_subgraph(G)
110-
print(H)

0 commit comments

Comments
 (0)