WeightedGraph API Interface
This tutorial provides a complete guide to the WeightedGraph API interface, covering initialization, weighted edge operations, graph construction, and utility methods.
Overview
The WeightedGraph class extends the Graph structure by associating
a weight (float) with each edge.
It is commonly used in applications involving costs, distances, or priorities.
Note
Nodes are indexed from
0toV-1Edge weights are stored as floating-point values
Supports both directed and undirected graphs
Initialization
1. Initialize weighted graph
from paragon import WeightedGraph
wg = WeightedGraph(vertices=4)
print(wg)
Output:
WeightedGraph(vertices=4, edges=0, directed=False)
2. Directed weighted graph
from paragon import WeightedGraph
wg = WeightedGraph(vertices=3, directed=True)
wg.add_edge(u=0, v=1, w=2.5)
print(wg.get_adj())
Output:
[[(1, 2.5)], [], []]
Warning
Vertices must be a positive integer
Invalid node indices raise
ValueErrorInvalid weight types raise
TypeError
Edge Operations
add_edge(u, v, w)
Adds a weighted edge.
from paragon import WeightedGraph
wg = WeightedGraph(vertices=3)
wg.add_edge(u=0, v=1, w=2.5)
wg.add_edge(u=1, v=2, w=1.2)
print(wg.get_adj())
Output:
[[(1, 2.5)], [(0, 2.5), (2, 1.2)], [(1, 1.2)]]
Parameters:
u: int — source vertexv: int — destination vertexw: float — edge weight
Warning
Weight must be numeric (int or float)
Negative indices are not allowed
Out-of-range indices raise
ValueError
add_edges(edges)
Add multiple weighted edges.
from paragon import WeightedGraph
wg = WeightedGraph(vertices=4)
wg.add_edges(edges=[
(0, 1, 2.5),
(1, 2, 1.0),
(2, 3, 3.2)
])
print(wg.get_adj())
Output:
[[(1, 2.5)], [(0, 2.5), (2, 1.0)], [(1, 1.0), (3, 3.2)], [(2, 3.2)]]
add_vertex()
Add a new vertex.
from paragon import WeightedGraph
wg = WeightedGraph(vertices=2)
wg.add_vertex()
print(wg.vertices())
Output:
3
Graph Construction
build_from_adj_list(adjacency)
Build graph using weighted adjacency list.
from paragon import WeightedGraph
wg = WeightedGraph(vertices=3)
adjacency = [
[(1, 2.5)],
[(0, 2.5), (2, 1.2)],
[(1, 1.2)]
]
wg.build_from_adj_list(adjacency=adjacency)
print(wg.get_adj())
Output:
[[(1, 2.5)], [(0, 2.5), (2, 1.2)], [(1, 1.2)]]
build_from_adj_matrix(matrix)
Build graph using weighted adjacency matrix.
from paragon import WeightedGraph
wg = WeightedGraph(vertices=3)
matrix = [
[0, 2.5, 0],
[2.5, 0, 1.2],
[0, 1.2, 0]
]
wg.build_from_adj_matrix(matrix=matrix)
print(wg.get_adj())
Output:
[[(1, 2.5), (1, 2.5)], [(0, 2.5), (0, 2.5), (2, 1.2), (2, 1.2)], [(1, 1.2), (1, 1.2)]]
Tip
Use adjacency lists for sparse graphs and matrices for dense graphs.
Graph Information
vertices()
Returns number of vertices.
from paragon import WeightedGraph
wg = WeightedGraph(vertices=4)
print(wg.vertices())
Output:
4
is_directed()
Check if graph is directed.
wg = WeightedGraph(vertices=3, directed=True)
print(wg.is_directed())
Output:
True
get_adj()
Returns weighted adjacency list.
wg = WeightedGraph(vertices=3)
wg.add_edge(u=0, v=1, w=2.5)
print(wg.get_adj())
Output:
[[(1, 2.5)], [(0, 2.5)], []]
degree(u)
Returns degree of vertex.
wg = WeightedGraph(vertices=3)
wg.add_edges(edges=[
(0, 1, 2.5),
(1, 2, 1.0)
])
print(wg.degree(u=1))
Output:
2
has_edge(u, v)
Checks if edge exists.
wg = WeightedGraph(vertices=3)
wg.add_edge(u=0, v=1, w=2.5)
print(wg.has_edge(u=0, v=1))
print(wg.has_edge(u=1, v=2))
Output:
True
False
Warning
Invalid node indices will raise ValueError.
Debug Utilities
print_graph()
Print graph.
wg = WeightedGraph(vertices=3)
wg.add_edges(edges=[
(0, 1, 2.5),
(1, 2, 1.0)
])
wg.print_graph()
Output:
0 : (1, 2.5)
1 : (0, 2.5) (2, 1)
2 : (1, 1)
Representation & Dunder Methods
__repr__()
Returns developer-friendly representation.
wg = WeightedGraph(vertices=3)
print(wg)
Output:
WeightedGraph(vertices=3, edges=0, directed=False)
__len__()
Returns number of vertices.
wg = WeightedGraph(vertices=4)
print(len(wg))
Output:
4
__contains__()
Checks if node exists.
wg = WeightedGraph(vertices=3)
print(1 in wg)
print(5 in wg)
Output:
True
False
__getitem__()
Returns neighbors with weights.
wg = WeightedGraph(vertices=3)
wg.add_edges(edges=[
(0, 1, 2.5),
(1, 2, 1.2)
])
print(wg[1])
Output:
[(0, 2.5), (2, 1.2)]
__iter__()
Iterates over nodes.
wg = WeightedGraph(vertices=3)
for node in wg:
print(node)
Output:
0
1
2
__eq__ / __ne__()
Compares graphs.
wg1 = WeightedGraph(vertices=3)
wg2 = WeightedGraph(vertices=3)
print(wg1 == wg2)
wg2.add_edge(u=0, v=1, w=2.0)
print(wg1 != wg2)
Output:
True
True
__copy__ / __deepcopy__()
Creates copies of the graph.
import copy
wg = WeightedGraph(vertices=3)
wg.add_edge(u=0, v=1, w=2.5)
wg2 = copy.copy(wg)
wg3 = copy.deepcopy(wg)
print(wg2.get_adj())
print(wg3.get_adj())
Output:
[[], [], []]
[[(1, 2.5)], [(0, 2.5)], []]
Note
copy.copy creates a shallow copy (structure only), while
copy.deepcopy creates a fully independent copy including edges.
Complete Dunder Methods Example
The following example demonstrates how all dunder methods work together.
from paragon import WeightedGraph
import copy
wg = WeightedGraph(vertices=4)
wg.add_edges(edges=[
(0, 1, 2.5),
(1, 2, 1.0),
(2, 3, 3.2)
])
# Length
print(len(wg))
# Contains
print(2 in wg)
# Indexing
print(wg[1])
# Iteration
for node in wg:
print(node)
# String representation
print(wg)
# Equality
wg2 = copy.deepcopy(wg)
print(wg == wg2)
Output:
4
True
[(0, 2.5), (2, 1.0)]
0
1
2
3
WeightedGraph(vertices=4, edges=6, directed=False)
True
Tip
Dunder methods make the WeightedGraph behave like native Python collections, improving readability and usability.
Complete Example
from paragon import WeightedGraph
wg = WeightedGraph(vertices=4)
wg.add_edges(edges=[
(0, 1, 2.5),
(1, 2, 1.0),
(2, 3, 3.2)
])
print("Vertices:", wg.vertices())
print("Adjacency:", wg.get_adj())
print("Degree:", wg.degree(u=1))
print("Has edge:", wg.has_edge(u=0, v=1))
Output:
Vertices: 4
Adjacency: [[(1, 2.5)], [(0, 2.5), (2, 1.0)], [(1, 1.0), (3, 3.2)], [(2, 3.2)]]
Degree: 2
Has edge: True
0 : (1, 2.5)
1 : (0, 2.5) (2, 1)
2 : (1, 1) (3, 3.2)
3 : (2, 3.2)
Best Practices
Use
add_edgesfor batch insertionUse adjacency list for performance
Validate weights before insertion
Tip
Weighted graphs are ideal for shortest path algorithms like Dijkstra.