Skip to content

Commit b8c7870

Browse files
authored
Merge pull request #10 from SebVde/bar_yehuda_fvs
Bar yehuda fvs
2 parents 2cfa476 + c55969f commit b8c7870

1 file changed

Lines changed: 108 additions & 0 deletions

File tree

bar_yehuda_fvs.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import networkx as nx
2+
from collections import deque
3+
4+
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
11+
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)
20+
21+
22+
def find_maximal_2_3_subgraph(G):
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+
42+
return H
43+
44+
45+
def cycle_exists_with_node(G, n):
46+
queue = deque()
47+
queue.append((n, None))
48+
visited = set()
49+
visited.add(n)
50+
51+
while queue:
52+
current, parent = queue.popleft()
53+
for nb in G.neighbors(current):
54+
if nb == parent:
55+
continue
56+
57+
if nb == n:
58+
return True
59+
60+
if nb not in visited:
61+
visited.add(nb)
62+
queue.append((nb, current))
63+
64+
return False
65+
66+
67+
def get_critical_linkpoints(G, H):
68+
linkpoints = {n for n in H.nodes if H.degree(n) == 2}
69+
critical_linkpoints = set()
70+
71+
for n in linkpoints:
72+
sg = nx.subgraph(G, set(G.nodes) - (set(H.nodes) - {n}))
73+
if cycle_exists_with_node(sg, n):
74+
critical_linkpoints.add(n)
75+
76+
return critical_linkpoints
77+
78+
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+
95+
def subG_2_3(G):
96+
# Complexité pas linéaire à cause de get_critical_linkpoints
97+
if nx.is_forest(G):
98+
return set()
99+
100+
H = find_maximal_2_3_subgraph(G)
101+
X = get_critical_linkpoints(G, H)
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
105+
106+
107+
def get_decycling_number_bar_yehuda(G):
108+
return len(subG_2_3(G))

0 commit comments

Comments
 (0)