-
Notifications
You must be signed in to change notification settings - Fork 1
/
min_dominating_set.py
119 lines (95 loc) · 3.64 KB
/
min_dominating_set.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# -*- coding: utf-8 -*-
"""
**************************************
Minimum Vertex and Edge Dominating Set
**************************************
A dominating set for a graph G = (V, E) is a subset D of V such that every
vertex not in D is joined to at least one member of D by some edge. The
domination number gamma(G) is the number of vertices in a smallest dominating
set for G. Given a graph G = (V, E) find a minimum weight dominating set V'.
http://en.wikipedia.org/wiki/Dominating_set
An edge dominating set for a graph G = (V, E) is a subset D of E such that
every edge not in D is adjacent to at least one edge in D.
http://en.wikipedia.org/wiki/Edge_dominating_set
"""
# Copyright (C) 2011-2012 by
# Nicholas Mancuso <[email protected]>
# All rights reserved.
# BSD license.
import networkx as nx
__all__ = ["min_weighted_dominating_set",
"min_edge_dominating_set"]
__author__ = """Nicholas Mancuso ([email protected])"""
def min_weighted_dominating_set(G, weight=None):
"""Return minimum weight vertex dominating set.
Parameters
----------
G : NetworkX graph
Undirected graph
weight : None or string, optional (default = None)
If None, every edge has p/distance/weight 1. If a string, use this
edge attribute as the edge weight. Any edge attribute not present
defaults to 1.
Returns
-------
min_weight_dominating_set : set
Returns a set of vertices whose weight sum is no more than log w(V) * OPT
Notes
-----
This algorithm computes an approximate minimum weighted dominating set
for the graph G. The upper-bound on the size of the solution is
log w(V) * OPT. Runtime of the algorithm is `O(|E|)`.
References
----------
.. [1] Vazirani, Vijay Approximation Algorithms (2001)
"""
if not G:
raise ValueError("Expected non-empty NetworkX graph!")
# min cover = min dominating set
weight = None
dom_set = set([])
cost_func = dict((node, nd.get(weight, 1)) \
for node, nd in G.nodes(data=True))
vertices = set(G)
sets = dict((node, set([node]) | set(G[node])) for node in G)
def _cost(subset):
""" Our cost effectiveness function for sets given its weight
"""
cost = sum(cost_func[node] for node in subset)
return cost / float(len(subset - dom_set))
while vertices:
# find the most cost effective set, and the vertex that for that set
dom_node, min_set = min(sets.items(),
key=lambda x: _cost(x[1]))
print("cost_func: ", cost_func)
print("dom_node: ", dom_node)
print("min_set: ", min_set)
alpha = _cost(min_set)
print("alpha: ", alpha)
# reduce the cost for the rest
for node in min_set - dom_set:
cost_func[node] = alpha
# add the node to the dominating set and reduce what we must cover
dom_set.add(dom_node)
del sets[dom_node]
vertices = vertices - min_set
return dom_set
def min_edge_dominating_set(G):
"""Return minimum cardinality edge dominating set.
Parameters
----------
G : NetworkX graph
Undirected graph
Returns
-------
min_edge_dominating_set : set
Returns a set of dominating edges whose size is no more than 2 * OPT.
Notes
-----
The algorithm computes an approximate solution to the edge dominating set
problem. The result is no more than 2 * OPT in terms of size of the set.
Runtime of the algorithm is `O(|E|)`.
"""
if not G:
raise ValueError("Expected non-empty NetworkX graph!")
return nx.maximal_matching(G)