-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgraphClass.py
More file actions
94 lines (78 loc) · 3.16 KB
/
graphClass.py
File metadata and controls
94 lines (78 loc) · 3.16 KB
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
import matplotlib.pyplot as plt
import networkx as nx
class Graph:
def __init__(self, directed: bool = False, weighted: bool = False) -> None:
self.directed = directed
self.weighted = weighted
self.adjacency_dict = {}
def __str__(self) -> str:
return str(self.adjacency_dict)
def add_vertex(self, key: str) -> None:
if not key:
raise ValueError("Key is empty")
if key in self.adjacency_dict:
raise ValueError("Key already exists")
self.adjacency_dict[key] = {} if self.weighted else set()
def add_edge(self, key: str, value: str, weight: float | None = None) -> None:
if not key or not value:
raise ValueError("Key/value is empty")
if key not in self.adjacency_dict:
raise ValueError(f"Key does not exist: {key}")
if value not in self.adjacency_dict:
raise ValueError(f"Value does not exist: {value}")
if self.weighted:
if weight is None:
raise ValueError("Weight is empty")
if not isinstance(weight, (int, float)):
raise ValueError("Weight must be a number")
self.adjacency_dict[key][value] = float(weight)
if not self.directed:
self.adjacency_dict[value][key] = float(weight)
else:
self.adjacency_dict[key].add(value)
if not self.directed:
self.adjacency_dict[value].add(key)
def neighbors(self, key: str) -> list:
if key not in self.adjacency_dict:
raise ValueError(f"Vertex does not exist: {key}")
return self.adjacency_dict[key]
def deg(self, key: str) -> int:
if key not in self.adjacency_dict:
raise ValueError(f"Vertex does not exist: {key}")
return len(self.adjacency_dict[key])
def visualize_graph(self) -> None:
G = nx.DiGraph() if self.directed else nx.Graph()
for vertex in self.adjacency_dict.keys():
G.add_node(vertex)
for vertex, edges in self.adjacency_dict.items():
if self.weighted:
for edge, weight in edges.items():
G.add_edge(vertex, edge, weight=weight)
else:
for edge in edges:
G.add_edge(vertex, edge)
pos = nx.spring_layout(G)
nx.draw(
G, pos,
with_labels=True,
node_color="lightblue",
node_size=700,
font_size=16,
font_color="black"
)
if self.weighted:
edge_labels = nx.get_edge_attributes(G, "weight")
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
plt.show()
class NormalGraph(Graph):
def __init__(self) -> None:
super().__init__(directed=False, weighted=False)
class DirectedGraph(Graph):
def __init__(self) -> None:
super().__init__(directed=True, weighted=False)
class WeightedGraph(Graph):
def __init__(self) -> None:
super().__init__(directed=False, weighted=True)
class DirectedWeightedGraph(Graph):
def __init__(self) -> None:
super().__init__(directed=True, weighted=True)