blob: c588e18a09471607ce03d63372fc6e9abfe1b8e7 [file] [log] [blame]
# -*- coding: utf-8 -*-
"""
************
Vertex Cover
************
Given an undirected graph `G = (V, E)` and a function w assigning nonnegative
weights to its vertices, find a minimum weight subset of V such that each edge
in E is incident to at least one vertex in the subset.
http://en.wikipedia.org/wiki/Vertex_cover
"""
# Copyright (C) 2011-2012 by
# Nicholas Mancuso <nick.mancuso@gmail.com>
# All rights reserved.
# BSD license.
from networkx.utils import *
__all__ = ["min_weighted_vertex_cover"]
__author__ = """Nicholas Mancuso (nick.mancuso@gmail.com)"""
@not_implemented_for('directed')
def min_weighted_vertex_cover(G, weight=None):
r"""2-OPT Local Ratio for Minimum Weighted Vertex Cover
Find an approximate minimum weighted vertex cover of a graph.
Parameters
----------
G : NetworkX graph
Undirected graph
weight : None or string, optional (default = None)
If None, every edge has weight/distance/cost 1. If a string, use this
edge attribute as the edge weight. Any edge attribute not present
defaults to 1.
Returns
-------
min_weighted_cover : set
Returns a set of vertices whose weight sum is no more than 2 * OPT.
Notes
-----
Local-Ratio algorithm for computing an approximate vertex cover.
Algorithm greedily reduces the costs over edges and iteratively
builds a cover. Worst-case runtime is `O(|E|)`.
References
----------
.. [1] Bar-Yehuda, R., & Even, S. (1985). A local-ratio theorem for
approximating the weighted vertex cover problem.
Annals of Discrete Mathematics, 25, 27–46
http://www.cs.technion.ac.il/~reuven/PDF/vc_lr.pdf
"""
weight_func = lambda nd: nd.get(weight, 1)
cost = dict((n, weight_func(nd)) for n, nd in G.nodes(data=True))
# while there are edges uncovered, continue
for u,v in G.edges_iter():
# select some uncovered edge
min_cost = min([cost[u], cost[v]])
cost[u] -= min_cost
cost[v] -= min_cost
return set(u for u in cost if cost[u] == 0)