Beispiel #1
0
def reduction2(g: MultiGraph, w: set, h: MultiGraph, k: int) -> (int, int, bool):
	for v in h.nodes():
		# Check if G[W ∪ {v}] contains a cycle.
		if not is_forest(g.subgraph(w.union({v}))):
			g.remove_node(v)
			h.remove_nodes_from([v])
			return (k - 1, v, True)
	return (k, None, False)
Beispiel #2
0
def fvs_disjoint(g: MultiGraph, w: set, k: int) -> set:
	# Check that G[W] is a forest.
	# If it isn't, then a solution X not using W can't remove W's cycles.
	if not is_forest(g.subgraph(w)):
		return None

	# Apply reductions exhaustively.
	k, soln_redux = apply_reductions(g, w, k)

	# If k becomes negative, it indicates that the reductions included
	# more than k vertices, hence no solution of size <= k exists.
	if k < 0:
		return None

	# If G has been reduced to nothing and k is >= 0 then the solution generated by the reductions
	# is already optimal.
	if len(g) == 0:
		return soln_redux

	# Find an x in H of degree at most 1.
	h = graph_minus(g, w)
	x = None
	for v in h.nodes():
		if h.degree(v) <= 1:
			x = v
			break
	assert x is not None

	# Branch.
	# G is copied in the left branch (as it is modified), but passed directly in the right.
	soln_left = fvs_disjoint(graph_minus(g, {x}), w, k - 1)

	if soln_left is not None:
		return soln_redux.union(soln_left).union({x})

	soln_right = fvs_disjoint(g, w.union({x}), k)

	if soln_right is not None:
		return soln_redux.union(soln_right)

	return None
Beispiel #3
0
def is_fvs(g: MultiGraph, w) -> bool:
	h = graph_minus(g, w)
	return ((len(h) == 0) or is_forest(h))