Add more algorithms

This commit is contained in:
Vinicius Silva 2024-05-20 12:30:20 -03:00
parent 34504aaf5f
commit 1a1022845a
4 changed files with 336 additions and 3 deletions

View File

@ -1,4 +1,6 @@
import treelib
class Node():
def __init__(self, val):
@ -11,7 +13,101 @@ class BinaryTree():
def __init__(self, root):
self.root = root
def insert(self, val):
def insert_callable(self, val):
self.root = self.__insert(val, self.root)
node = self.root
def __insert(self, val, node):
if not node:
node = Node(val)
return node
elif val < node.val:
node.left = self.__insert(val, node.left)
return node
elif val > node.val:
node.right = self.__insert(val, node.right)
return node
else:
raise Exception('This element already exist!')
def search_callable(self, val):
return self.__search(val, self.root)
def set_less(self, node_left, node_right):
if not node_right:
return node_left
else:
node_right.left = self.set_less(node_left, node_right.left)
return node_right
def __search(self, val, node):
if not node:
return False
elif node.val == val:
return True
elif val < node.val:
return self.__search(val, node.left)
else:
return self.__search(val, node.right)
def remove_callable(self, val):
self.root = self.__remove(val, self.root)
def __remove(self, val, node):
if not node:
raise Exception('Value not found!')
elif node.val == val:
return self.set_less(node.left, node.right)
elif val < node.val:
node.left = self.__remove(val, node.left)
return node
else:
node.right = self.__remove(val, node.right)
return node
def show_callable(self):
tree = treelib.Tree()
tree = self.__show(tree, self.root)
tree.show()
def __show(self, tree, node):
if not node:
return tree
else:
if node.left:
tree = self.__show(tree, node.left)
tree.create_node(node.left.val, node.left.val, parent=node.val)
if node.right:
tree = self.__show(tree, node.right)
tree.create_node(node.right.val, node.right.val, parent=node.val)
return tree
if __name__ == '__main__':
tree = BinaryTree(Node(10))
tree.insert_callable(1)
tree.insert_callable(4)
tree.insert_callable(0)
tree.insert_callable(14)
tree.insert_callable(22)
tree.remove_callable(14)
print(tree.search_callable(1))
print(tree.search_callable(13))
print(tree.search_callable(4))
print(tree.search_callable(0))
print(tree.search_callable(14))
#print(tree.search_callable(22))
#print(tree.search_callable(12))
#print(tree.search_callable(15))
#print(tree.search_callable(16))
#print(tree.search_callable(-1))
#
#tree.show_callable()

Binary file not shown.

View File

@ -0,0 +1,233 @@
import math
class Vertex():
def __init__(self, vertexID):
self.ID = vertexID
class VertexPair():
def __init__(self, first_vertex: Vertex, second_vertex: Vertex):
self.first_vertex = first_vertex
self.second_vertex = second_vertex
class Edge():
def __init__(self, first_vertex: Vertex, second_vertex: Vertex):
self.vertex_pair = VertexPair(first_vertex, second_vertex)
class Graph():
def __init__(self, vertex_size: int, is_digraph=False, adjacency_flag=1):
self.graph = self.__init_graph(vertex_size)
self.is_digraph = is_digraph
self.vertex_size = vertex_size
self.adjacency_flag = adjacency_flag
def __vertex_in_graph(self, vertexID: int):
return vertexID in range(0, self.vertex_size)
def set_adjacency(self, edge: Edge, adjacency_flag=-1):
if adjacency_flag == -1:
adjacency_flag = self.adjacency_flag
first_vertexID = int(edge.vertex_pair.first_vertex.ID)
second_vertexID = int(edge.vertex_pair.second_vertex.ID)
if self.__vertex_in_graph(first_vertexID) and self.__vertex_in_graph(second_vertexID):
self.graph[first_vertexID][second_vertexID] = adjacency_flag
if not self.is_digraph:
self.graph[second_vertexID][first_vertexID] = adjacency_flag
else:
raise Exception('Vertex out of bounds')
def __init_graph(self, vertex_size: int, inital_val=0):
return [[inital_val]*vertex_size for _ in range(vertex_size)]
def __mark_as_visited(self,visited, element, graph):
for i in range(0, len(graph)):
if graph[i][element] == self.adjacency_flag:
graph[i][element] = visited
return graph
def clear(self, inital_val=0):
self.graph = self.__init_graph(self.vertex_size, inital_val)
def bfs(self, source_vertex: Vertex):
assert self.is_digraph and self.__vertex_in_graph(int(source_vertex.ID))
visited = self.adjacency_flag+1
graph = self.graph.copy()
queque = [source_vertex.ID]
while len(queque) > 0:
element = queque[0]
queque = queque[1:]
print(f"Current vertex {element}")
graph = self.__mark_as_visited(visited, element, graph)
for i in range(0, len(graph[element])):
if graph[element][i] == self.adjacency_flag:
print(f" ({element}) -> ({i})")
graph = self.__mark_as_visited(visited, i, graph)
queque.append(i)
elif graph[element][i] == visited:
print(f" ({element}) -> ({i}) - Already visited")
def get_parents(self, source_vertex, graph):
assert self.__vertex_in_graph(source_vertex)
parents = []
for i in range(0, len(graph[source_vertex])):
if self.graph[source_vertex][i] != 0:
parents.append(i)
return parents
def dfs(self, source_vertex):
graph = self.graph
visited = self.adjacency_flag+1
parents_from_source = self.get_parents(source_vertex, graph)
if len(parents_from_source) != 0:
graph = self.__mark_as_visited(visited, source_vertex, graph)
for i in range(0, len(parents_from_source)):
if graph[source_vertex][i] != visited:
print(f" ({source_vertex}) -> ({parents_from_source[i]})")
self.dfs(parents_from_source[i])
graph = self.__mark_as_visited(visited, i, graph)
else:
print(f" ({source_vertex}) -> ({parents_from_source[i]})")
def dijkstra(self, source_vertex):
assert self.is_digraph and self.__vertex_in_graph(int(source_vertex.ID))
visited = math.inf
graph = self.graph.copy()
queque = [source_vertex.ID]
visited = []
weight = [math.inf]*self.vertex_size
weight[source_vertex.ID] = 0
while len(queque) > 0:
element = queque[0]
queque = queque[1:]
print(f"Current vertex {element}")
visited.append(element)
for i in range(0, self.vertex_size):
if graph[element][i] != -1 and i not in visited:
if weight[i] > (weight[element]+graph[element][i]):
print(f" ({element}) -> ({i}) <-> Weight {(weight[element]+graph[element][i])}")
weight[i] = (weight[element]+graph[element][i])
visited.append(i)
queque.append(i)
elif graph[element][i] != -1 and i in visited:
print(f" ({element}) -> ({i}) - Already visited", end=" <-> ")
if weight[i] > (weight[element]+graph[element][i]):
print(f"New Weight {(weight[element]+graph[element][i])}")
weight[i] = (weight[element]+graph[element][i])
return weight
def show_matrix(self):
for i in range(0, self.vertex_size):
for j in range(0, self.vertex_size):
print(f'{self.graph[i][j]}', end='')
print('')
if __name__ == '__main__':
vertex_size = 6
graph = Graph(vertex_size, True)
print('================================= BFS ====================================')
graph.set_adjacency(Edge(Vertex(0),Vertex(2)))
graph.set_adjacency(Edge(Vertex(0),Vertex(4)))
graph.set_adjacency(Edge(Vertex(0),Vertex(3)))
graph.set_adjacency(Edge(Vertex(1),Vertex(2)))
graph.set_adjacency(Edge(Vertex(1),Vertex(4)))
graph.set_adjacency(Edge(Vertex(2),Vertex(4)))
graph.set_adjacency(Edge(Vertex(3),Vertex(4)))
graph.set_adjacency(Edge(Vertex(3),Vertex(5)))
graph.set_adjacency(Edge(Vertex(4),Vertex(5)))
graph.set_adjacency(Edge(Vertex(5),Vertex(1)))
graph.bfs(Vertex(0))
print('==========================================================================')
print('================================= DFS ====================================')
graph.clear()
graph.set_adjacency(Edge(Vertex(0),Vertex(2)))
graph.set_adjacency(Edge(Vertex(0),Vertex(4)))
graph.set_adjacency(Edge(Vertex(0),Vertex(3)))
graph.set_adjacency(Edge(Vertex(2),Vertex(1)))
graph.set_adjacency(Edge(Vertex(2),Vertex(4)))
graph.set_adjacency(Edge(Vertex(3),Vertex(4)))
graph.set_adjacency(Edge(Vertex(3),Vertex(5)))
graph.set_adjacency(Edge(Vertex(4),Vertex(1)))
graph.set_adjacency(Edge(Vertex(4),Vertex(5)))
graph.set_adjacency(Edge(Vertex(5),Vertex(1)))
graph.dfs(Vertex(0).ID)
print('==========================================================================')
print('============================== DIJKSTRA ==================================')
graph.clear(inital_val=-1)
graph.set_adjacency(Edge(Vertex(0),Vertex(2)), 7)
graph.set_adjacency(Edge(Vertex(0),Vertex(4)), 4)
graph.set_adjacency(Edge(Vertex(0),Vertex(3)), 2)
graph.set_adjacency(Edge(Vertex(1),Vertex(2)), 0)
graph.set_adjacency(Edge(Vertex(2),Vertex(4)), 1)
graph.set_adjacency(Edge(Vertex(3),Vertex(4)), 1)
graph.set_adjacency(Edge(Vertex(3),Vertex(5)), 3)
graph.set_adjacency(Edge(Vertex(4),Vertex(1)), 4)
graph.set_adjacency(Edge(Vertex(4),Vertex(5)), 1)
graph.set_adjacency(Edge(Vertex(5),Vertex(1)), 2)
print(graph.dijkstra(Vertex(0)))
print('==========================================================================')

View File

@ -0,0 +1,4 @@
DIJKSTRA RESULT
Vértices 0 1 2 3 4 5 6
Distancia 0 6 6 2 3 4