@@ -49,28 +49,28 @@ def get_fvs(og_G):
4949 F = set ()
5050 stack = []
5151 G = og_G .copy ()
52+ weights = {n : 1.0 for n in G .nodes ()}
5253
5354 while len (G .nodes ) > 0 :
5455 sd_cycle = find_semidisjoint_cycle (G )
5556 if sd_cycle is not None :
5657 for node in sd_cycle :
57- G . nodes [node ][ "weight" ] = 0.0
58+ weights [node ] -= min ( weights [ node ] for node in sd_cycle )
5859
5960 else :
60- # TODO implement priority queue like mentioned in the paper to optimize this step
61- gamma = min (1 / (G .degree (node ) - 1 ) for node in G .nodes )
61+ gamma = min (weights [node ] / (G .degree (node ) - 1 ) for node in G .nodes )
6262 for node in G .nodes :
63- G . nodes [node ][ "weight" ] -= gamma * (G .degree (node ) - 1 )
63+ weights [node ] -= gamma * (G .degree (node ) - 1 )
6464
65- to_remove = [node for node in G .nodes if G . nodes [node ][ "weight" ] <= 0.0 ]
65+ to_remove = [node for node in G .nodes if weights [node ] <= 1e-9 ]
6666 F .update (to_remove )
6767 G .remove_nodes_from (to_remove )
6868 stack .extend (to_remove )
6969 G = cleanup (G )
7070
7171 while len (stack ) > 0 :
7272 node = stack .pop ()
73- sg = nx .subgraph (og_G , og_G . nodes - ( F - { node }) )
73+ sg = nx .subgraph_view (og_G , filter_node = lambda n : n not in F or n == node )
7474 # With this check, it should ensure that each call for nx.is_forest is in O(|V|) time since |E| < |V|
7575 if sg .number_of_edges () <= sg .number_of_nodes () - 1 and nx .is_forest (sg ):
7676 F .remove (node )
@@ -80,8 +80,5 @@ def get_fvs(og_G):
8080
8181def get_decycling_number_2_approx (G ):
8282 clean_G = cleanup (G .copy ())
83- for node in clean_G .nodes :
84- clean_G .nodes [node ]["weight" ] = 1.0
85-
8683 fvs = get_fvs (clean_G )
8784 return len (fvs )
0 commit comments