Skip to content

Commit aa53deb

Browse files
Prerak SinghPrerak Singh
authored andcommitted
added cpp backend for dfs and bellman ford algorithms
1 parent fc75883 commit aa53deb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+15026
-12
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from .utils import *
2+
from .linear_data_structures import *
3+
from .trees import *
4+
from .miscellaneous_data_structures import *
5+
from .graphs import *
6+
from .strings import *
7+
8+
__version__ = "1.0.1-dev"
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
__all__ = []
2+
3+
from . import graph
4+
from .graph import (
5+
Graph
6+
)
7+
__all__.extend(graph.__all__)
8+
9+
from . import algorithms
10+
from . import adjacency_list
11+
from . import adjacency_matrix
12+
13+
from .algorithms import (
14+
breadth_first_search,
15+
breadth_first_search_parallel,
16+
minimum_spanning_tree,
17+
minimum_spanning_tree_parallel,
18+
strongly_connected_components,
19+
depth_first_search,
20+
shortest_paths,
21+
all_pair_shortest_paths,
22+
topological_sort,
23+
topological_sort_parallel,
24+
max_flow,
25+
find_bridges
26+
)
27+
28+
__all__.extend(algorithms.__all__)

install/lib/python3.12/site-packages/pydatastructs/graphs/_backend/__init__.py

Whitespace-only changes.
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
from pydatastructs.graphs.graph import Graph
2+
from pydatastructs.graphs._backend.cpp import _graph
3+
from pydatastructs.utils.misc_util import (
4+
GraphEdge, Backend, raise_if_backend_is_not_python)
5+
6+
__all__ = [
7+
'AdjacencyList'
8+
]
9+
10+
class AdjacencyList(Graph):
11+
"""
12+
Adjacency list implementation of graphs.
13+
14+
See also
15+
========
16+
17+
pydatastructs.graphs.graph.Graph
18+
"""
19+
def __new__(cls, *vertices, **kwargs):
20+
21+
backend = kwargs.get('backend', Backend.PYTHON)
22+
if backend == Backend.PYTHON:
23+
obj = object.__new__(cls)
24+
for vertex in vertices:
25+
obj.__setattr__(vertex.name, vertex)
26+
obj.vertices = [vertex.name for vertex in vertices]
27+
obj.edge_weights = {}
28+
obj._impl = 'adjacency_list'
29+
return obj
30+
else:
31+
graph = _graph.AdjacencyListGraph()
32+
for vertice in vertices:
33+
graph.add_vertex(vertice)
34+
return graph
35+
36+
@classmethod
37+
def methods(self):
38+
return ['is_adjacent', 'neighbors',
39+
'add_vertex', 'remove_vertex', 'add_edge',
40+
'get_edge', 'remove_edge', '__new__']
41+
42+
def is_adjacent(self, node1, node2):
43+
node1 = self.__getattribute__(node1)
44+
return hasattr(node1, node2)
45+
46+
def num_vertices(self):
47+
return len(self.vertices)
48+
49+
def num_edges(self):
50+
return sum(len(self.neighbors(v)) for v in self.vertices)
51+
52+
def neighbors(self, node):
53+
node = self.__getattribute__(node)
54+
return [self.__getattribute__(name) for name in node.adjacent]
55+
56+
def add_vertex(self, node):
57+
if not hasattr(self, node.name):
58+
self.vertices.append(node.name)
59+
self.__setattr__(node.name, node)
60+
61+
def remove_vertex(self, name):
62+
delattr(self, name)
63+
self.vertices.remove(name)
64+
for node in self.vertices:
65+
node_obj = self.__getattribute__(node)
66+
if hasattr(node_obj, name):
67+
delattr(node_obj, name)
68+
node_obj.adjacent.remove(name)
69+
70+
def add_edge(self, source, target, cost=None):
71+
source, target = str(source), str(target)
72+
error_msg = ("Vertex %s is not present in the graph."
73+
"Call Graph.add_vertex to add a new"
74+
"vertex. Graph.add_edge is only responsible"
75+
"for adding edges and it will not add new"
76+
"vertices on its own. This is done to maintain"
77+
"clear separation between the functionality of"
78+
"these two methods.")
79+
if not hasattr(self, source):
80+
raise ValueError(error_msg % (source))
81+
if not hasattr(self, target):
82+
raise ValueError(error_msg % (target))
83+
84+
source, target = self.__getattribute__(source), \
85+
self.__getattribute__(target)
86+
source.add_adjacent_node(target.name)
87+
if cost is not None:
88+
self.edge_weights[source.name + "_" + target.name] = \
89+
GraphEdge(source, target, cost)
90+
91+
def get_edge(self, source, target):
92+
return self.edge_weights.get(
93+
source + "_" + target,
94+
None)
95+
96+
def remove_edge(self, source, target):
97+
source, target = self.__getattribute__(source), \
98+
self.__getattribute__(target)
99+
source.remove_adjacent_node(target.name)
100+
self.edge_weights.pop(source.name + "_" + target.name,
101+
None)
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
from pydatastructs.graphs.graph import Graph
2+
from pydatastructs.graphs._backend.cpp import _graph
3+
from pydatastructs.utils.misc_util import (
4+
GraphEdge, raise_if_backend_is_not_python,
5+
Backend)
6+
7+
__all__ = [
8+
'AdjacencyMatrix'
9+
]
10+
11+
class AdjacencyMatrix(Graph):
12+
"""
13+
Adjacency matrix implementation of graphs.
14+
15+
See also
16+
========
17+
18+
pydatastructs.graphs.graph.Graph
19+
"""
20+
def __new__(cls, *vertices, **kwargs):
21+
backend = kwargs.get('backend', Backend.PYTHON)
22+
if backend == Backend.PYTHON:
23+
obj = object.__new__(cls)
24+
obj.vertices = [vertex.name for vertex in vertices]
25+
for vertex in vertices:
26+
obj.__setattr__(vertex.name, vertex)
27+
obj.matrix = {}
28+
for vertex in vertices:
29+
obj.matrix[vertex.name] = {}
30+
obj.edge_weights = {}
31+
obj._impl = 'adjacency_matrix'
32+
return obj
33+
else:
34+
return _graph.AdjacencyMatrixGraph(vertices)
35+
36+
@classmethod
37+
def methods(self):
38+
return ['is_adjacent', 'neighbors',
39+
'add_edge', 'get_edge', 'remove_edge',
40+
'__new__']
41+
42+
def is_adjacent(self, node1, node2):
43+
node1, node2 = str(node1), str(node2)
44+
row = self.matrix.get(node1, {})
45+
return row.get(node2, False) is not False
46+
47+
def num_vertices(self):
48+
return len(self.vertices)
49+
50+
def num_edges(self):
51+
return sum(len(v) for v in self.matrix.values())
52+
53+
def neighbors(self, node):
54+
node = str(node)
55+
neighbors = []
56+
row = self.matrix.get(node, {})
57+
for node, presence in row.items():
58+
if presence:
59+
neighbors.append(self.__getattribute__(
60+
str(node)))
61+
return neighbors
62+
63+
def add_vertex(self, node):
64+
raise NotImplementedError("Currently we allow "
65+
"adjacency matrix for static graphs only")
66+
67+
def remove_vertex(self, node):
68+
raise NotImplementedError("Currently we allow "
69+
"adjacency matrix for static graphs only.")
70+
71+
def add_edge(self, source, target, cost=None):
72+
source, target = str(source), str(target)
73+
error_msg = ("Vertex %s is not present in the graph."
74+
"Call Graph.add_vertex to add a new"
75+
"vertex. Graph.add_edge is only responsible"
76+
"for adding edges and it will not add new"
77+
"vertices on its own. This is done to maintain"
78+
"clear separation between the functionality of"
79+
"these two methods.")
80+
if source not in self.matrix:
81+
raise ValueError(error_msg % (source))
82+
if target not in self.matrix:
83+
raise ValueError(error_msg % (target))
84+
85+
self.matrix[source][target] = True
86+
if cost is not None:
87+
self.edge_weights[source + "_" + target] = \
88+
GraphEdge(self.__getattribute__(source),
89+
self.__getattribute__(target),
90+
cost)
91+
92+
def get_edge(self, source, target):
93+
return self.edge_weights.get(
94+
str(source) + "_" + str(target),
95+
None)
96+
97+
def remove_edge(self, source, target):
98+
source, target = str(source), str(target)
99+
self.matrix[source][target] = False
100+
self.edge_weights.pop(str(source) + "_" + str(target), None)

0 commit comments

Comments
 (0)