Source code for qlauncher.problems.optimization.vertex_cover
1from typing import Literal
2
3import matplotlib.pyplot as plt
4import networkx as nx
5from pyqubo import Array, Binary
6
7from qlauncher import models
8from qlauncher.base import Problem
9
10
[docs]
11class VertexCover(Problem):
12 """
13 Class for the Vertex Cover problem which is a combinatorial problem involving choosing a subset of graph vertices such that each edge of the graph has at least one vertex in the chosen subset.
14
15 Attributes:
16 instance (nx.Graph): The graph for which the coloring problem is to be solved.
17
18
19 """
20
21 def __init__(self, instance: nx.Graph, instance_name: str = 'unnamed') -> None:
22 """
23 Args:
24 instance (nx.Graph): Graph representing the TSP instance.
25 instance_name (str): Name of the instance.
26 """
27 super().__init__(instance=instance, instance_name=instance_name)
28
29 # method to visualize a problem and optionally a solution to it
[docs]
30 def visualize(self, solution: list[int] | None = None) -> None:
31 pos = nx.spring_layout(self.instance)
32 plt.figure(figsize=(8, 6))
33 if solution is not None:
34 solution_colors = ['red' if x else 'skyblue' for x in solution]
35 nx.draw_networkx_nodes(self.instance, pos, node_size=500, node_color=solution_colors)
36 else:
37 nx.draw_networkx_nodes(self.instance, pos, node_size=500, node_color='skyblue')
38 nx.draw_networkx_edges(self.instance, pos, edge_color='gray')
39 nx.draw_networkx_labels(self.instance, pos, font_size=10, font_weight='bold')
40 plt.title('Vertex Cover Problem Instance Visualization')
41 plt.show()
42
43 # method to load a predefined toy example
[docs]
44 @staticmethod
45 def from_preset(instance_name: Literal['default'], **kwargs) -> 'VertexCover':
46 match instance_name:
47 case 'default':
48 node_list = list(range(5))
49 edge_list = [(0, 1), (0, 2), (1, 3), (2, 3), (2, 4), (3, 4)]
50 graph = nx.Graph()
51 graph.add_nodes_from(node_list)
52 graph.add_edges_from(edge_list)
53 return VertexCover(graph, instance_name=instance_name)
54
55 # method which generates ransom problem instance
[docs]
56 @staticmethod
57 def generate_vertex_cover_instance(num_vertices: int, edge_probability: int) -> 'VertexCover':
58 graph = nx.gnp_random_graph(num_vertices, edge_probability)
59 return VertexCover(graph)
60
[docs]
61 def to_bqm(self, constraint_weight: int = 5, cost_weight: int = 1) -> models.BQM:
62 vertices = self.instance.nodes()
63 edges = self.instance.edges()
64 x = Array.create('x', shape=len(vertices), vartype='BINARY')
65
66 # penalty for number of vertices used
67 qubo: Binary = sum(cost_weight * x[v] for v in vertices)
68
69 # penalty for violating constraint, not covering all edges
70 for e in edges:
71 qubo += constraint_weight * (1 - x[e[0]] - x[e[1]] + x[e[0]] * x[e[1]])
72
73 return models.BQM(qubo.compile())