alonso 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
alonso-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Frank Vega
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
alonso-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,267 @@
1
+ Metadata-Version: 2.4
2
+ Name: alonso
3
+ Version: 0.0.1
4
+ Summary: Compute an Approximate Vertex Cover for undirected graph encoded in DIMACS format.
5
+ Home-page: https://github.com/frankvegadelgado/alonso
6
+ Author: Frank Vega
7
+ Author-email: vega.frank@gmail.com
8
+ License: MIT License
9
+ Project-URL: Source Code, https://github.com/frankvegadelgado/alonso
10
+ Project-URL: Documentation Research, https://dev.to/frank_vega_987689489099bf/challenging-the-unique-games-conjecture-12mi
11
+ Classifier: Topic :: Scientific/Engineering
12
+ Classifier: Topic :: Software Development
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Environment :: Console
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: Intended Audience :: Education
19
+ Classifier: Intended Audience :: Information Technology
20
+ Classifier: Intended Audience :: Science/Research
21
+ Classifier: Natural Language :: English
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: mendive>=0.0.4
26
+ Dynamic: author
27
+ Dynamic: author-email
28
+ Dynamic: classifier
29
+ Dynamic: description
30
+ Dynamic: description-content-type
31
+ Dynamic: home-page
32
+ Dynamic: license
33
+ Dynamic: license-file
34
+ Dynamic: project-url
35
+ Dynamic: requires-dist
36
+ Dynamic: requires-python
37
+ Dynamic: summary
38
+
39
+ # Alonso: Approximate Vertex Cover Solver
40
+
41
+ ![Honoring the Memory of Alicia Alonso (a legendary Cuban ballet dancer and cultural icon)](docs/alonso.jpg)
42
+
43
+ This work builds upon [Challenging the Unique Games Conjecture](https://dev.to/frank_vega_987689489099bf/challenging-the-unique-games-conjecture-12mi).
44
+
45
+ ---
46
+
47
+ # The Minimum Vertex Cover Problem
48
+
49
+ The **Minimum Vertex Cover (MVC)** problem is a classic optimization problem in computer science and graph theory. It involves finding the smallest set of vertices in a graph that **covers** all edges, meaning at least one endpoint of every edge is included in the set.
50
+
51
+ ## Formal Definition
52
+
53
+ Given an undirected graph $G = (V, E)$, a **vertex cover** is a subset $V' \subseteq V$ such that for every edge $(u, v) \in E$, at least one of $u$ or $v$ belongs to $V'$. The MVC problem seeks the vertex cover with the smallest cardinality.
54
+
55
+ ## Importance and Applications
56
+
57
+ - **Theoretical Significance:** MVC is a well-known NP-hard problem, central to complexity theory.
58
+ - **Practical Applications:**
59
+ - **Network Security:** Identifying critical nodes to disrupt connections.
60
+ - **Bioinformatics:** Analyzing gene regulatory networks.
61
+ - **Wireless Sensor Networks:** Optimizing sensor coverage.
62
+
63
+ ## Related Problems
64
+
65
+ - **Maximum Independent Set:** The complement of a vertex cover.
66
+ - **Set Cover Problem:** A generalization of MVC.
67
+
68
+ ---
69
+
70
+ # Overview of the Algorithm and Its Running Time
71
+
72
+ The `find_vertex_cover` algorithm approximates a minimum vertex cover for an undirected graph $G = (V, E)$ by partitioning its edges into two claw-free subgraphs using the Burr-Erdős-Lovász (1976) method, computing exact vertex covers for these subgraphs with the Faenza, Oriolo, and Stauffer (2011) approach, and recursively refining the solution on residual edges. This process prevents the ratio from reaching 2, leveraging overlap between subgraphs and minimal additions in recursion. The algorithm begins by cleaning the graph (removing self-loops and isolates in $\mathcal{O}(n + m)$), partitions edges in $\mathcal{O}(m \cdot (m \cdot \Delta \cdot C + C^2))$ where $\Delta$ is the maximum degree and $C$ is the number of claws, computes vertex covers in $\mathcal{O}(n^3)$ per subgraph (total $\mathcal{O}(n^3)$), merges covers in $\mathcal{O}(n)$, and constructs the residual graph in $\mathcal{O}(m)$. The recursive nature, with a worst-case depth of $\mathcal{O}(m)$ if each step covers one edge, yields a total runtime of $\mathcal{O}(n^3 m)$, dominated by the cubic cost across levels. For sparse graphs ($m = \mathcal{O}(n)$), this simplifies to $\mathcal{O}(n^4)$.
73
+
74
+ ---
75
+
76
+ ## Problem Statement
77
+
78
+ Input: A Boolean Adjacency Matrix $M$.
79
+
80
+ Answer: Find a Minimum Vertex Cover.
81
+
82
+ ### Example Instance: 5 x 5 matrix
83
+
84
+ | | c1 | c2 | c3 | c4 | c5 |
85
+ | ------ | --- | --- | --- | --- | --- |
86
+ | **r1** | 0 | 0 | 1 | 0 | 1 |
87
+ | **r2** | 0 | 0 | 0 | 1 | 0 |
88
+ | **r3** | 1 | 0 | 0 | 0 | 1 |
89
+ | **r4** | 0 | 1 | 0 | 0 | 0 |
90
+ | **r5** | 1 | 0 | 1 | 0 | 0 |
91
+
92
+ The input for undirected graph is typically provided in [DIMACS](http://dimacs.rutgers.edu/Challenges) format. In this way, the previous adjacency matrix is represented in a text file using the following string representation:
93
+
94
+ ```
95
+ p edge 5 4
96
+ e 1 3
97
+ e 1 5
98
+ e 2 4
99
+ e 3 5
100
+ ```
101
+
102
+ This represents a 5x5 matrix in DIMACS format such that each edge $(v,w)$ appears exactly once in the input file and is not repeated as $(w,v)$. In this format, every edge appears in the form of
103
+
104
+ ```
105
+ e W V
106
+ ```
107
+
108
+ where the fields W and V specify the endpoints of the edge while the lower-case character `e` signifies that this is an edge descriptor line.
109
+
110
+ _Example Solution:_
111
+
112
+ Vertex Cover Found `3, 4, 5`: Nodes `3`, `4`, and `5` constitute an optimal solution.
113
+
114
+ ---
115
+
116
+ # Compile and Environment
117
+
118
+ ## Prerequisites
119
+
120
+ - Python ≥ 3.10
121
+
122
+ ## Installation
123
+
124
+ ```bash
125
+ pip install alonso
126
+ ```
127
+
128
+ ## Execution
129
+
130
+ 1. Clone the repository:
131
+
132
+ ```bash
133
+ git clone https://github.com/frankvegadelgado/alonso.git
134
+ cd alonso
135
+ ```
136
+
137
+ 2. Run the script:
138
+
139
+ ```bash
140
+ mvc -i ./benchmarks/testMatrix1
141
+ ```
142
+
143
+ utilizing the `mvc` command provided by Alonso's Library to execute the Boolean adjacency matrix `alonso\benchmarks\testMatrix1`. The file `testMatrix1` represents the example described herein. We also support `.xz`, `.lzma`, `.bz2`, and `.bzip2` compressed text files.
144
+
145
+ **Example Output:**
146
+
147
+ ```
148
+ testMatrix1: Vertex Cover Found 3, 4, 5
149
+ ```
150
+
151
+ This indicates nodes `3, 4, 5` form a vertex cover.
152
+
153
+ ---
154
+
155
+ ## Vertex Cover Size
156
+
157
+ Use the `-c` flag to count the nodes in the vertex cover:
158
+
159
+ ```bash
160
+ mvc -i ./benchmarks/testMatrix2 -c
161
+ ```
162
+
163
+ **Output:**
164
+
165
+ ```
166
+ testMatrix2: Vertex Cover Size 5
167
+ ```
168
+
169
+ ---
170
+
171
+ # Command Options
172
+
173
+ Display help and options:
174
+
175
+ ```bash
176
+ mvc -h
177
+ ```
178
+
179
+ **Output:**
180
+
181
+ ```bash
182
+ usage: mvc [-h] -i INPUTFILE [-a] [-b] [-c] [-v] [-l] [--version]
183
+
184
+ Compute an Approximate Vertex Cover for undirected graph encoded in DIMACS format.
185
+
186
+ options:
187
+ -h, --help show this help message and exit
188
+ -i INPUTFILE, --inputFile INPUTFILE
189
+ input file path
190
+ -a, --approximation enable comparison with a polynomial-time approximation approach within a factor of at most 2
191
+ -b, --bruteForce enable comparison with the exponential-time brute-force approach
192
+ -c, --count calculate the size of the vertex cover
193
+ -v, --verbose anable verbose output
194
+ -l, --log enable file logging
195
+ --version show program's version number and exit
196
+ ```
197
+
198
+ ---
199
+
200
+ # Batch Execution
201
+
202
+ Batch execution allows you to solve multiple graphs within a directory consecutively.
203
+
204
+ To view available command-line options for the `batch_mvc` command, use the following in your terminal or command prompt:
205
+
206
+ ```bash
207
+ batch_mvc -h
208
+ ```
209
+
210
+ This will display the following help information:
211
+
212
+ ```bash
213
+ usage: batch_mvc [-h] -i INPUTDIRECTORY [-a] [-b] [-c] [-v] [-l] [--version]
214
+
215
+ Compute an Approximate Vertex Cover for all undirected graphs encoded in DIMACS format and stored in a directory.
216
+
217
+ options:
218
+ -h, --help show this help message and exit
219
+ -i INPUTDIRECTORY, --inputDirectory INPUTDIRECTORY
220
+ Input directory path
221
+ -a, --approximation enable comparison with a polynomial-time approximation approach within a factor of at most 2
222
+ -b, --bruteForce enable comparison with the exponential-time brute-force approach
223
+ -c, --count calculate the size of the vertex cover
224
+ -v, --verbose anable verbose output
225
+ -l, --log enable file logging
226
+ --version show program's version number and exit
227
+ ```
228
+
229
+ ---
230
+
231
+ # Testing Application
232
+
233
+ A command-line utility named `test_mvc` is provided for evaluating the Algorithm using randomly generated, large sparse matrices. It supports the following options:
234
+
235
+ ```bash
236
+ usage: test_mvc [-h] -d DIMENSION [-n NUM_TESTS] [-s SPARSITY] [-a] [-b] [-c] [-w] [-v] [-l] [--version]
237
+
238
+ The Alonso Testing Application using randomly generated, large sparse matrices.
239
+
240
+ options:
241
+ -h, --help show this help message and exit
242
+ -d DIMENSION, --dimension DIMENSION
243
+ an integer specifying the dimensions of the square matrices
244
+ -n NUM_TESTS, --num_tests NUM_TESTS
245
+ an integer specifying the number of tests to run
246
+ -s SPARSITY, --sparsity SPARSITY
247
+ sparsity of the matrices (0.0 for dense, close to 1.0 for very sparse)
248
+ -a, --approximation enable comparison with a polynomial-time approximation approach within a factor of at most 2
249
+ -b, --bruteForce enable comparison with the exponential-time brute-force approach
250
+ -c, --count calculate the size of the vertex cover
251
+ -w, --write write the generated random matrix to a file in the current directory
252
+ -v, --verbose anable verbose output
253
+ -l, --log enable file logging
254
+ --version show program's version number and exit
255
+ ```
256
+
257
+ ---
258
+
259
+ # Code
260
+
261
+ - Python implementation by **Frank Vega**.
262
+
263
+ ---
264
+
265
+ # License
266
+
267
+ - MIT License.
alonso-0.0.1/README.md ADDED
@@ -0,0 +1,229 @@
1
+ # Alonso: Approximate Vertex Cover Solver
2
+
3
+ ![Honoring the Memory of Alicia Alonso (a legendary Cuban ballet dancer and cultural icon)](docs/alonso.jpg)
4
+
5
+ This work builds upon [Challenging the Unique Games Conjecture](https://dev.to/frank_vega_987689489099bf/challenging-the-unique-games-conjecture-12mi).
6
+
7
+ ---
8
+
9
+ # The Minimum Vertex Cover Problem
10
+
11
+ The **Minimum Vertex Cover (MVC)** problem is a classic optimization problem in computer science and graph theory. It involves finding the smallest set of vertices in a graph that **covers** all edges, meaning at least one endpoint of every edge is included in the set.
12
+
13
+ ## Formal Definition
14
+
15
+ Given an undirected graph $G = (V, E)$, a **vertex cover** is a subset $V' \subseteq V$ such that for every edge $(u, v) \in E$, at least one of $u$ or $v$ belongs to $V'$. The MVC problem seeks the vertex cover with the smallest cardinality.
16
+
17
+ ## Importance and Applications
18
+
19
+ - **Theoretical Significance:** MVC is a well-known NP-hard problem, central to complexity theory.
20
+ - **Practical Applications:**
21
+ - **Network Security:** Identifying critical nodes to disrupt connections.
22
+ - **Bioinformatics:** Analyzing gene regulatory networks.
23
+ - **Wireless Sensor Networks:** Optimizing sensor coverage.
24
+
25
+ ## Related Problems
26
+
27
+ - **Maximum Independent Set:** The complement of a vertex cover.
28
+ - **Set Cover Problem:** A generalization of MVC.
29
+
30
+ ---
31
+
32
+ # Overview of the Algorithm and Its Running Time
33
+
34
+ The `find_vertex_cover` algorithm approximates a minimum vertex cover for an undirected graph $G = (V, E)$ by partitioning its edges into two claw-free subgraphs using the Burr-Erdős-Lovász (1976) method, computing exact vertex covers for these subgraphs with the Faenza, Oriolo, and Stauffer (2011) approach, and recursively refining the solution on residual edges. This process prevents the ratio from reaching 2, leveraging overlap between subgraphs and minimal additions in recursion. The algorithm begins by cleaning the graph (removing self-loops and isolates in $\mathcal{O}(n + m)$), partitions edges in $\mathcal{O}(m \cdot (m \cdot \Delta \cdot C + C^2))$ where $\Delta$ is the maximum degree and $C$ is the number of claws, computes vertex covers in $\mathcal{O}(n^3)$ per subgraph (total $\mathcal{O}(n^3)$), merges covers in $\mathcal{O}(n)$, and constructs the residual graph in $\mathcal{O}(m)$. The recursive nature, with a worst-case depth of $\mathcal{O}(m)$ if each step covers one edge, yields a total runtime of $\mathcal{O}(n^3 m)$, dominated by the cubic cost across levels. For sparse graphs ($m = \mathcal{O}(n)$), this simplifies to $\mathcal{O}(n^4)$.
35
+
36
+ ---
37
+
38
+ ## Problem Statement
39
+
40
+ Input: A Boolean Adjacency Matrix $M$.
41
+
42
+ Answer: Find a Minimum Vertex Cover.
43
+
44
+ ### Example Instance: 5 x 5 matrix
45
+
46
+ | | c1 | c2 | c3 | c4 | c5 |
47
+ | ------ | --- | --- | --- | --- | --- |
48
+ | **r1** | 0 | 0 | 1 | 0 | 1 |
49
+ | **r2** | 0 | 0 | 0 | 1 | 0 |
50
+ | **r3** | 1 | 0 | 0 | 0 | 1 |
51
+ | **r4** | 0 | 1 | 0 | 0 | 0 |
52
+ | **r5** | 1 | 0 | 1 | 0 | 0 |
53
+
54
+ The input for undirected graph is typically provided in [DIMACS](http://dimacs.rutgers.edu/Challenges) format. In this way, the previous adjacency matrix is represented in a text file using the following string representation:
55
+
56
+ ```
57
+ p edge 5 4
58
+ e 1 3
59
+ e 1 5
60
+ e 2 4
61
+ e 3 5
62
+ ```
63
+
64
+ This represents a 5x5 matrix in DIMACS format such that each edge $(v,w)$ appears exactly once in the input file and is not repeated as $(w,v)$. In this format, every edge appears in the form of
65
+
66
+ ```
67
+ e W V
68
+ ```
69
+
70
+ where the fields W and V specify the endpoints of the edge while the lower-case character `e` signifies that this is an edge descriptor line.
71
+
72
+ _Example Solution:_
73
+
74
+ Vertex Cover Found `3, 4, 5`: Nodes `3`, `4`, and `5` constitute an optimal solution.
75
+
76
+ ---
77
+
78
+ # Compile and Environment
79
+
80
+ ## Prerequisites
81
+
82
+ - Python ≥ 3.10
83
+
84
+ ## Installation
85
+
86
+ ```bash
87
+ pip install alonso
88
+ ```
89
+
90
+ ## Execution
91
+
92
+ 1. Clone the repository:
93
+
94
+ ```bash
95
+ git clone https://github.com/frankvegadelgado/alonso.git
96
+ cd alonso
97
+ ```
98
+
99
+ 2. Run the script:
100
+
101
+ ```bash
102
+ mvc -i ./benchmarks/testMatrix1
103
+ ```
104
+
105
+ utilizing the `mvc` command provided by Alonso's Library to execute the Boolean adjacency matrix `alonso\benchmarks\testMatrix1`. The file `testMatrix1` represents the example described herein. We also support `.xz`, `.lzma`, `.bz2`, and `.bzip2` compressed text files.
106
+
107
+ **Example Output:**
108
+
109
+ ```
110
+ testMatrix1: Vertex Cover Found 3, 4, 5
111
+ ```
112
+
113
+ This indicates nodes `3, 4, 5` form a vertex cover.
114
+
115
+ ---
116
+
117
+ ## Vertex Cover Size
118
+
119
+ Use the `-c` flag to count the nodes in the vertex cover:
120
+
121
+ ```bash
122
+ mvc -i ./benchmarks/testMatrix2 -c
123
+ ```
124
+
125
+ **Output:**
126
+
127
+ ```
128
+ testMatrix2: Vertex Cover Size 5
129
+ ```
130
+
131
+ ---
132
+
133
+ # Command Options
134
+
135
+ Display help and options:
136
+
137
+ ```bash
138
+ mvc -h
139
+ ```
140
+
141
+ **Output:**
142
+
143
+ ```bash
144
+ usage: mvc [-h] -i INPUTFILE [-a] [-b] [-c] [-v] [-l] [--version]
145
+
146
+ Compute an Approximate Vertex Cover for undirected graph encoded in DIMACS format.
147
+
148
+ options:
149
+ -h, --help show this help message and exit
150
+ -i INPUTFILE, --inputFile INPUTFILE
151
+ input file path
152
+ -a, --approximation enable comparison with a polynomial-time approximation approach within a factor of at most 2
153
+ -b, --bruteForce enable comparison with the exponential-time brute-force approach
154
+ -c, --count calculate the size of the vertex cover
155
+ -v, --verbose anable verbose output
156
+ -l, --log enable file logging
157
+ --version show program's version number and exit
158
+ ```
159
+
160
+ ---
161
+
162
+ # Batch Execution
163
+
164
+ Batch execution allows you to solve multiple graphs within a directory consecutively.
165
+
166
+ To view available command-line options for the `batch_mvc` command, use the following in your terminal or command prompt:
167
+
168
+ ```bash
169
+ batch_mvc -h
170
+ ```
171
+
172
+ This will display the following help information:
173
+
174
+ ```bash
175
+ usage: batch_mvc [-h] -i INPUTDIRECTORY [-a] [-b] [-c] [-v] [-l] [--version]
176
+
177
+ Compute an Approximate Vertex Cover for all undirected graphs encoded in DIMACS format and stored in a directory.
178
+
179
+ options:
180
+ -h, --help show this help message and exit
181
+ -i INPUTDIRECTORY, --inputDirectory INPUTDIRECTORY
182
+ Input directory path
183
+ -a, --approximation enable comparison with a polynomial-time approximation approach within a factor of at most 2
184
+ -b, --bruteForce enable comparison with the exponential-time brute-force approach
185
+ -c, --count calculate the size of the vertex cover
186
+ -v, --verbose anable verbose output
187
+ -l, --log enable file logging
188
+ --version show program's version number and exit
189
+ ```
190
+
191
+ ---
192
+
193
+ # Testing Application
194
+
195
+ A command-line utility named `test_mvc` is provided for evaluating the Algorithm using randomly generated, large sparse matrices. It supports the following options:
196
+
197
+ ```bash
198
+ usage: test_mvc [-h] -d DIMENSION [-n NUM_TESTS] [-s SPARSITY] [-a] [-b] [-c] [-w] [-v] [-l] [--version]
199
+
200
+ The Alonso Testing Application using randomly generated, large sparse matrices.
201
+
202
+ options:
203
+ -h, --help show this help message and exit
204
+ -d DIMENSION, --dimension DIMENSION
205
+ an integer specifying the dimensions of the square matrices
206
+ -n NUM_TESTS, --num_tests NUM_TESTS
207
+ an integer specifying the number of tests to run
208
+ -s SPARSITY, --sparsity SPARSITY
209
+ sparsity of the matrices (0.0 for dense, close to 1.0 for very sparse)
210
+ -a, --approximation enable comparison with a polynomial-time approximation approach within a factor of at most 2
211
+ -b, --bruteForce enable comparison with the exponential-time brute-force approach
212
+ -c, --count calculate the size of the vertex cover
213
+ -w, --write write the generated random matrix to a file in the current directory
214
+ -v, --verbose anable verbose output
215
+ -l, --log enable file logging
216
+ --version show program's version number and exit
217
+ ```
218
+
219
+ ---
220
+
221
+ # Code
222
+
223
+ - Python implementation by **Frank Vega**.
224
+
225
+ ---
226
+
227
+ # License
228
+
229
+ - MIT License.
@@ -0,0 +1,4 @@
1
+ # Alonso: Approximate Vertex Cover Solver https://pypi.org/project/alonso
2
+ # Author: Frank Vega
3
+
4
+ __all__ = ["utils", "bipartite", "algorithm", "parser", "applogger", "test", "app", "batch"]
@@ -0,0 +1,115 @@
1
+ # Created on 21/05/2025
2
+ # Author: Frank Vega
3
+
4
+ import itertools
5
+ from . import utils
6
+
7
+ import networkx as nx
8
+ from . import partition
9
+ from . import stable
10
+ from . import merge
11
+
12
+ def find_vertex_cover(graph):
13
+ """
14
+ Compute an approximate minimum vertex cover set for an undirected graph by transforming it into a chordal graph.
15
+
16
+ Args:
17
+ graph (nx.Graph): A NetworkX Graph object representing the input graph.
18
+
19
+ Returns:
20
+ set: A set of vertex indices representing the approximate minimum vertex cover set.
21
+ Returns an empty set if the graph is empty or has no edges.
22
+ """
23
+ # Validate that the input is a valid undirected NetworkX graph
24
+ if not isinstance(graph, nx.Graph):
25
+ raise ValueError("Input must be an undirected NetworkX Graph.")
26
+
27
+ # Handle trivial cases: return empty set for graphs with no nodes or no edges
28
+ if graph.number_of_nodes() == 0 or graph.number_of_edges() == 0:
29
+ return set() # No vertices or edges mean no cover is needed
30
+
31
+ # Create a working copy to avoid modifying the original graph
32
+ working_graph = graph.copy()
33
+
34
+ # Remove self-loops as they are irrelevant for vertex cover computation
35
+ working_graph.remove_edges_from(list(nx.selfloop_edges(working_graph)))
36
+
37
+ # Remove isolated nodes (degree 0) since they don't contribute to the vertex cover
38
+ working_graph.remove_nodes_from(list(nx.isolates(working_graph)))
39
+
40
+ # Return empty set if the cleaned graph has no nodes after removals
41
+ if working_graph.number_of_nodes() == 0:
42
+ return set()
43
+
44
+ # Partition edges into two subsets (E1, E2) using the Burr-Erdős-Lovász (1976) algorithm
45
+ # This step divides the graph into two claw-free subgraphs
46
+ # Complexity: O(m * (m * Δ * C + C^2)), where m is edges, Δ is maximum degree, C is number of claws
47
+ E1, E2 = partition.partition_edges_claw_free(working_graph)
48
+
49
+ # Compute minimum vertex cover for E1 using the Faenza, Oriolo & Stauffer (2011) algorithm
50
+ # This finds the maximum weighted stable set in the claw-free graph E1, whose complement is the vertex cover
51
+ # Complexity: O(n^3), where n is the number of nodes in the subgraph induced by E1
52
+ vertex_cover_1 = stable.minimum_vertex_cover_claw_free(E1)
53
+
54
+ # Compute minimum vertex cover for E2 using the same Faenza, Oriolo & Stauffer (2011) algorithm
55
+ # Complexity: O(n^3) for the subgraph induced by E2
56
+ vertex_cover_2 = stable.minimum_vertex_cover_claw_free(E2)
57
+
58
+ # Merge the two vertex covers from E1 and E2 to approximate the minimum vertex cover of the original graph
59
+ approximate_vertex_cover = merge.merge_vertex_covers(E1, E2, vertex_cover_1, vertex_cover_2)
60
+
61
+ # Create a residual graph containing edges not covered by the current vertex cover
62
+ residual_graph = nx.Graph()
63
+ for u, v in working_graph.edges():
64
+ if u not in approximate_vertex_cover and v not in approximate_vertex_cover:
65
+ residual_graph.add_edge(u, v) # Add edge if neither endpoint is in the cover
66
+
67
+ # Recursively find vertex cover for the residual graph to handle uncovered edges
68
+ residual_vertex_cover = find_vertex_cover(residual_graph)
69
+
70
+ # Combine the approximate vertex cover with the residual cover to ensure all edges are covered
71
+ return approximate_vertex_cover.union(residual_vertex_cover)
72
+
73
+ def find_vertex_cover_brute_force(graph):
74
+ """
75
+ Computes an exact minimum vertex cover in exponential time.
76
+
77
+ Args:
78
+ graph: A NetworkX Graph.
79
+
80
+ Returns:
81
+ A set of vertex indices representing the exact vertex cover, or None if the graph is empty.
82
+ """
83
+
84
+ if graph.number_of_nodes() == 0 or graph.number_of_edges() == 0:
85
+ return None
86
+
87
+ n_vertices = len(graph.nodes())
88
+
89
+ for k in range(1, n_vertices + 1): # Iterate through all possible sizes of the cover
90
+ for candidate in itertools.combinations(graph.nodes(), k):
91
+ cover_candidate = set(candidate)
92
+ if utils.is_vertex_cover(graph, cover_candidate):
93
+ return cover_candidate
94
+
95
+ return None
96
+
97
+
98
+
99
+ def find_vertex_cover_approximation(graph):
100
+ """
101
+ Computes an approximate vertex cover in polynomial time with an approximation ratio of at most 2 for undirected graphs.
102
+
103
+ Args:
104
+ graph: A NetworkX Graph.
105
+
106
+ Returns:
107
+ A set of vertex indices representing the approximate vertex cover, or None if the graph is empty.
108
+ """
109
+
110
+ if graph.number_of_nodes() == 0 or graph.number_of_edges() == 0:
111
+ return None
112
+
113
+ #networkx doesn't have a guaranteed minimum vertex cover function, so we use approximation
114
+ vertex_cover = nx.approximation.vertex_cover.min_weighted_vertex_cover(graph)
115
+ return vertex_cover