alonso 0.0.1__py3-none-any.whl
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/__init__.py +4 -0
- alonso/algorithm.py +115 -0
- alonso/app.py +98 -0
- alonso/applogger.py +80 -0
- alonso/batch.py +53 -0
- alonso/merge.py +125 -0
- alonso/parser.py +79 -0
- alonso/partition.py +216 -0
- alonso/stable.py +186 -0
- alonso/test.py +118 -0
- alonso/utils.py +257 -0
- alonso-0.0.1.dist-info/METADATA +267 -0
- alonso-0.0.1.dist-info/RECORD +17 -0
- alonso-0.0.1.dist-info/WHEEL +5 -0
- alonso-0.0.1.dist-info/entry_points.txt +4 -0
- alonso-0.0.1.dist-info/licenses/LICENSE +21 -0
- alonso-0.0.1.dist-info/top_level.txt +1 -0
alonso/utils.py
ADDED
@@ -0,0 +1,257 @@
|
|
1
|
+
# Created on 21/05/2025
|
2
|
+
# Author: Frank Vega
|
3
|
+
|
4
|
+
import scipy.sparse as sparse
|
5
|
+
import numpy as np
|
6
|
+
import random
|
7
|
+
import string
|
8
|
+
import os
|
9
|
+
import networkx as nx
|
10
|
+
|
11
|
+
def get_file_names(directory):
|
12
|
+
"""
|
13
|
+
Gets a list of all file names within a specified directory.
|
14
|
+
|
15
|
+
Args:
|
16
|
+
directory: The path to the directory.
|
17
|
+
|
18
|
+
Returns:
|
19
|
+
A list of file names within the directory.
|
20
|
+
"""
|
21
|
+
try:
|
22
|
+
return [f for f in os.listdir(directory) if not os.path.isdir(os.path.join(directory, f))]
|
23
|
+
except FileNotFoundError:
|
24
|
+
print(f"Directory '{directory}' not found.")
|
25
|
+
return []
|
26
|
+
|
27
|
+
def get_file_name(filepath):
|
28
|
+
"""
|
29
|
+
Gets the file name from an absolute path.
|
30
|
+
|
31
|
+
Args:
|
32
|
+
filepath: The absolute path to the file.
|
33
|
+
|
34
|
+
Returns:
|
35
|
+
The file name, or None if no file is found.
|
36
|
+
"""
|
37
|
+
|
38
|
+
return os.path.basename(filepath)
|
39
|
+
|
40
|
+
def get_extension_without_dot(filepath):
|
41
|
+
"""
|
42
|
+
Gets the file extension without the dot from an absolute path.
|
43
|
+
|
44
|
+
Args:
|
45
|
+
filepath: The absolute path to the file.
|
46
|
+
|
47
|
+
Returns:
|
48
|
+
The file extension without the dot, or None if no extension is found.
|
49
|
+
"""
|
50
|
+
|
51
|
+
filename = get_file_name(filepath)
|
52
|
+
_, ext = os.path.splitext(filename)
|
53
|
+
return ext[1:] if ext else None
|
54
|
+
|
55
|
+
def has_one_on_diagonal(adjacency_matrix):
|
56
|
+
"""
|
57
|
+
Checks if there is a 1 on the diagonal of a SciPy sparse matrix.
|
58
|
+
|
59
|
+
Args:
|
60
|
+
adjacency_matrix: A SciPy sparse matrix (e.g., csc_matrix) representing the adjacency matrix.
|
61
|
+
|
62
|
+
Returns:
|
63
|
+
True if there is a 1 on the diagonal, False otherwise.
|
64
|
+
"""
|
65
|
+
diagonal = adjacency_matrix.diagonal()
|
66
|
+
return np.any(diagonal == 1)
|
67
|
+
|
68
|
+
def generate_short_hash(length=6):
|
69
|
+
"""Generates a short random alphanumeric hash string.
|
70
|
+
|
71
|
+
Args:
|
72
|
+
length: The desired length of the hash string (default is 6).
|
73
|
+
|
74
|
+
Returns:
|
75
|
+
A random alphanumeric string of the specified length.
|
76
|
+
Returns None if length is invalid.
|
77
|
+
"""
|
78
|
+
|
79
|
+
if not isinstance(length, int) or length <= 0:
|
80
|
+
print("Error: Length must be a positive integer.")
|
81
|
+
return None
|
82
|
+
|
83
|
+
characters = string.ascii_letters + string.digits # alphanumeric chars
|
84
|
+
return ''.join(random.choice(characters) for i in range(length))
|
85
|
+
|
86
|
+
def make_symmetric(matrix):
|
87
|
+
"""Makes an arbitrary sparse matrix symmetric efficiently.
|
88
|
+
|
89
|
+
Args:
|
90
|
+
matrix: A SciPy sparse matrix (e.g., csc_matrix, csr_matrix, etc.).
|
91
|
+
|
92
|
+
Returns:
|
93
|
+
scipy.sparse.csc_matrix: A symmetric sparse matrix.
|
94
|
+
Raises:
|
95
|
+
TypeError: if the input is not a sparse matrix.
|
96
|
+
"""
|
97
|
+
|
98
|
+
if not sparse.issparse(matrix):
|
99
|
+
raise TypeError("Input must be a SciPy sparse matrix.")
|
100
|
+
|
101
|
+
rows, cols = matrix.shape
|
102
|
+
if rows != cols:
|
103
|
+
raise ValueError("Matrix must be square to be made symmetric.")
|
104
|
+
|
105
|
+
# Convert to COO for efficient duplicate handling
|
106
|
+
coo = matrix.tocoo()
|
107
|
+
|
108
|
+
# Concatenate row and column indices, and data with their transposes
|
109
|
+
row_sym = np.concatenate([coo.row, coo.col])
|
110
|
+
col_sym = np.concatenate([coo.col, coo.row])
|
111
|
+
data_sym = np.concatenate([coo.data, coo.data])
|
112
|
+
|
113
|
+
# Create the symmetric matrix in CSC format
|
114
|
+
symmetric_matrix = sparse.csc_matrix((data_sym, (row_sym, col_sym)), shape=(rows, cols))
|
115
|
+
symmetric_matrix.sum_duplicates() #sum the duplicates
|
116
|
+
|
117
|
+
return symmetric_matrix
|
118
|
+
|
119
|
+
def random_matrix_tests(matrix_shape, sparsity=0.9):
|
120
|
+
"""
|
121
|
+
Performs random tests on a sparse matrix.
|
122
|
+
|
123
|
+
Args:
|
124
|
+
matrix_shape (tuple): Shape of the matrix (rows, columns).
|
125
|
+
num_tests (int): Number of random tests to perform.
|
126
|
+
sparsity (float): Sparsity of the matrix (0.0 for dense, close to 1.0 for very sparse).
|
127
|
+
|
128
|
+
Returns:
|
129
|
+
list: A list containing the results of each test.
|
130
|
+
sparse matrix: the sparse matrix that was tested.
|
131
|
+
"""
|
132
|
+
|
133
|
+
rows, cols = matrix_shape
|
134
|
+
size = rows * cols
|
135
|
+
|
136
|
+
# Generate a sparse matrix using random indices and data
|
137
|
+
num_elements = int(size * (1 - sparsity)) # Number of non-zero elements
|
138
|
+
row_indices = np.random.randint(0, rows, size=num_elements, dtype=np.int32)
|
139
|
+
col_indices = np.random.randint(0, cols, size=num_elements, dtype=np.int32)
|
140
|
+
data = np.ones(num_elements, dtype=np.int8)
|
141
|
+
|
142
|
+
sparse_matrix = sparse.csc_matrix((data, (row_indices, col_indices)), shape=(rows, cols))
|
143
|
+
|
144
|
+
# Convert sparse_matrix to a symmetric matrix
|
145
|
+
symmetric_matrix = make_symmetric(sparse_matrix)
|
146
|
+
|
147
|
+
# Set diagonal to 0
|
148
|
+
symmetric_matrix.setdiag(0)
|
149
|
+
|
150
|
+
return symmetric_matrix
|
151
|
+
|
152
|
+
def string_result_format(result, count_result=False):
|
153
|
+
"""
|
154
|
+
Returns a string indicating the vertex cover.
|
155
|
+
|
156
|
+
Args:
|
157
|
+
result: None if the graph is empty, the vertex cover otherwise.
|
158
|
+
count_result: Count the number of nodes in the vertex cover (default is False).
|
159
|
+
|
160
|
+
Returns:
|
161
|
+
- "Empty Graph" if result is None, "Vertex Cover Found a, b, c, ...." otherwise.
|
162
|
+
"""
|
163
|
+
if result:
|
164
|
+
if count_result:
|
165
|
+
return f"Vertex Cover Size {len(result)}"
|
166
|
+
else:
|
167
|
+
formatted_string = f'{", ".join(f"{x + 1}" for x in result)}'
|
168
|
+
return f"Vertex Cover Found {formatted_string}"
|
169
|
+
else:
|
170
|
+
return "Empty Graph"
|
171
|
+
|
172
|
+
def println(output, logger, file_logging=False):
|
173
|
+
""" Log and Print the Final Output Message """
|
174
|
+
if (file_logging):
|
175
|
+
logger.info(output)
|
176
|
+
print(output)
|
177
|
+
|
178
|
+
def sparse_matrix_to_graph(adj_matrix, is_directed=False):
|
179
|
+
"""
|
180
|
+
Converts a SciPy sparse adjacency matrix to a NetworkX graph.
|
181
|
+
|
182
|
+
Args:
|
183
|
+
adj_matrix: A SciPy sparse adjacency matrix.
|
184
|
+
is_directed: Whether the matrix represents a directed graph (default: False).
|
185
|
+
|
186
|
+
Returns:
|
187
|
+
A NetworkX graph.
|
188
|
+
"""
|
189
|
+
|
190
|
+
|
191
|
+
rows, cols = adj_matrix.nonzero()
|
192
|
+
if is_directed:
|
193
|
+
graph = nx.DiGraph()
|
194
|
+
for i, j in zip(rows, cols):
|
195
|
+
if not graph.has_edge(i, j): # Avoid duplicates in undirected graphs
|
196
|
+
graph.add_edge(i, j)
|
197
|
+
else:
|
198
|
+
graph = nx.Graph()
|
199
|
+
for i, j in zip(rows, cols):
|
200
|
+
if i < j: # Avoid duplicates in undirected graphs
|
201
|
+
graph.add_edge(i, j)
|
202
|
+
|
203
|
+
return graph
|
204
|
+
|
205
|
+
def is_vertex_redundant(graph, vertex, vertex_set):
|
206
|
+
"""
|
207
|
+
Check if a vertex does not cover any edge that a set of vertices does not already cover.
|
208
|
+
|
209
|
+
Parameters:
|
210
|
+
- graph: A NetworkX graph.
|
211
|
+
- vertex: The vertex to check.
|
212
|
+
- vertex_set: A set of vertices.
|
213
|
+
|
214
|
+
Returns:
|
215
|
+
- True if the vertex does not cover any additional edge, False otherwise.
|
216
|
+
"""
|
217
|
+
# Get all edges covered by the vertex set
|
218
|
+
edges_covered_by_set = set()
|
219
|
+
for v in vertex_set:
|
220
|
+
edges_covered_by_set.update(graph.edges(v))
|
221
|
+
|
222
|
+
# Get all edges covered by the vertex
|
223
|
+
edges_covered_by_vertex = set(graph.edges(vertex))
|
224
|
+
|
225
|
+
# Check if the edges covered by the vertex are a subset of the edges covered by the set
|
226
|
+
return edges_covered_by_vertex.issubset(edges_covered_by_set)
|
227
|
+
|
228
|
+
def is_vertex_cover(graph, vertex_cover):
|
229
|
+
"""
|
230
|
+
Verifies if a given set of vertices is a valid vertex cover for the graph.
|
231
|
+
|
232
|
+
Args:
|
233
|
+
graph (nx.Graph): The input graph.
|
234
|
+
vertex_cover (set): A set of vertices to check.
|
235
|
+
|
236
|
+
Returns:
|
237
|
+
bool: True if the set is a valid vertex cover, False otherwise.
|
238
|
+
"""
|
239
|
+
for u, v in graph.edges():
|
240
|
+
if u not in vertex_cover and v not in vertex_cover:
|
241
|
+
return False
|
242
|
+
return True
|
243
|
+
|
244
|
+
def is_independent_set(G, subset):
|
245
|
+
"""
|
246
|
+
Checks if a subset of nodes forms an independent set in the graph.
|
247
|
+
"""
|
248
|
+
for u in subset:
|
249
|
+
for v in subset:
|
250
|
+
if u != v and G.has_edge(u, v):
|
251
|
+
return False
|
252
|
+
return True
|
253
|
+
|
254
|
+
def compute_weight(G, nodes):
|
255
|
+
"""Compute the total weight of a set of nodes."""
|
256
|
+
return sum(G.nodes[node]['weight'] for node in nodes)
|
257
|
+
|
@@ -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
|
+

|
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.
|
@@ -0,0 +1,17 @@
|
|
1
|
+
alonso/__init__.py,sha256=vbC0ysStExEptYRA3SZVoBGFT7ysEDRPnZ9k9NqGMXI,188
|
2
|
+
alonso/algorithm.py,sha256=cVsyRQfEPOn-tHdxsTshBro6SjrJ3U0gxUIDROjlTEE,4748
|
3
|
+
alonso/app.py,sha256=0j1-pJgQfyoBwBz3AvwRa4iEW9PjTCD28QyX1rIvlKI,4320
|
4
|
+
alonso/applogger.py,sha256=fQBo51-TboX1DBqfSxX2P2eKJ5CcyiCq_IVlJTHjxAE,2624
|
5
|
+
alonso/batch.py,sha256=BlA4cs_OtmPXh1gmX4fI7Ye10Qtg9pbVgmv1CXW6nFQ,2305
|
6
|
+
alonso/merge.py,sha256=ObWIFqVhXycsjFk7pBqgxw55GrbgCysaGjjo1X58Yds,4209
|
7
|
+
alonso/parser.py,sha256=Ib4TnWdkQb6A6FA3HHEjZDBb7uD0v9Gabwewqfu4XpQ,2549
|
8
|
+
alonso/partition.py,sha256=7RgBCh6daLACnLuVYwvnIwtYARxTByUe_lIjdoDxpII,8515
|
9
|
+
alonso/stable.py,sha256=IwINwjd3F7dfoISXlWsNWRkVJzItEojgMyNwzMM7nYc,6577
|
10
|
+
alonso/test.py,sha256=8-860bd7cJCpx82T0FDbjesmzHxusi-YbhzOHK8mUyA,5472
|
11
|
+
alonso/utils.py,sha256=RmctLB8oDtjf0wKcKFaRvXiRgmtegqfbB1HFFzlpsvE,7674
|
12
|
+
alonso-0.0.1.dist-info/licenses/LICENSE,sha256=nUDh1nfa7rfEv1HocpoqPu0JaFnZKpIVh9eM0MgozpM,1067
|
13
|
+
alonso-0.0.1.dist-info/METADATA,sha256=cikJZVGVFrn2eIQWom1LEoOzx9Clzv1gGIiq_JSByjg,9396
|
14
|
+
alonso-0.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
15
|
+
alonso-0.0.1.dist-info/entry_points.txt,sha256=JSod2CWtklhiaOFW3masqrgqhXIpVRsbIiprSmS1P7g,98
|
16
|
+
alonso-0.0.1.dist-info/top_level.txt,sha256=rOo7SlpYGdic6g55rHDus2d5N2t74H9qamX4yi6z5vw,7
|
17
|
+
alonso-0.0.1.dist-info/RECORD,,
|
@@ -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.
|
@@ -0,0 +1 @@
|
|
1
|
+
alonso
|