Compare commits

...

36 Commits

Author SHA1 Message Date
Joel John Kurien
c51d695182
Merge 81fb07bf82 into f3f32ae3ca 2024-11-19 10:28:35 +08:00
pre-commit-ci[bot]
f3f32ae3ca
[pre-commit.ci] pre-commit autoupdate (#12385)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.7.3 → v0.7.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.7.3...v0.7.4)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-11-18 22:07:12 +01:00
Christian Clauss
e3bd7721c8
validate_filenames.py Shebang python for Windows (#12371) 2024-11-15 14:59:14 +01:00
pre-commit-ci[bot]
e3f3d668be
[pre-commit.ci] pre-commit autoupdate (#12370)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.7.2 → v0.7.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.7.2...v0.7.3)
- [github.com/abravalheri/validate-pyproject: v0.22 → v0.23](https://github.com/abravalheri/validate-pyproject/compare/v0.22...v0.23)

* Update sudoku_solver.py

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
2024-11-11 21:05:50 +01:00
Joelkurien
81fb07bf82 Merge branch 'joel_graph' of https://github.com/joelkurien/Python into joel_graph 2024-10-28 14:43:33 +11:00
Joelkurien
25844732f1 Handled word length 2024-10-28 14:43:31 +11:00
pre-commit-ci[bot]
2fb5becc4d [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2024-10-28 03:36:55 +00:00
Joelkurien
3d4acaaefb Added doctests 2024-10-28 14:36:29 +11:00
Joelkurien
5fe9e9b639 Added tests 2024-10-28 14:34:33 +11:00
pre-commit-ci[bot]
39fdc021ab [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2024-10-28 03:07:06 +00:00
Joelkurien
f9bf655086 Handled names 2024-10-28 14:06:39 +11:00
Joelkurien
bcf5beda92 handled name 2024-10-28 14:02:29 +11:00
pre-commit-ci[bot]
65f0d0c804 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2024-10-28 02:57:02 +00:00
Joelkurien
debba8c7dd Handled names 2024-10-28 13:56:35 +11:00
Joelkurien
8fc681807f Merge branch 'joel_graph' of https://github.com/joelkurien/Python into joel_graph 2024-10-28 13:46:43 +11:00
Joelkurien
6269fd68d0 Handled type annotation 2024-10-28 13:46:41 +11:00
pre-commit-ci[bot]
b911a5578c [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2024-10-28 02:43:45 +00:00
Joelkurien
32b9b8f6b4 Handled doctests 2024-10-28 13:43:18 +11:00
Joelkurien
14ddb93c6b Handled type annotation and doctests 2024-10-28 13:41:22 +11:00
Joelkurien
af534ade82 Handled type annotations and added doctests 2024-10-28 13:28:21 +11:00
pre-commit-ci[bot]
a00d41c861 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2024-10-28 02:18:28 +00:00
Joelkurien
9a4e1d333f Handled type annotation 2024-10-28 13:17:56 +11:00
Joelkurien
1fca8c6fc4 Merge branch 'joel_graph' of https://github.com/joelkurien/Python into joel_graph 2024-10-26 03:26:02 +11:00
Joelkurien
8006d48cac Added type annotation changes 2024-10-26 03:25:52 +11:00
pre-commit-ci[bot]
f62921cce0 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2024-10-25 16:23:57 +00:00
Joelkurien
b8c6beae72 Merge branch 'joel_graph' of https://github.com/joelkurien/Python into joel_graph 2024-10-26 03:23:26 +11:00
Joelkurien
f80afa35a8 Added type annotation for variables 2024-10-26 03:23:20 +11:00
pre-commit-ci[bot]
4982ff01b6 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2024-10-25 16:19:06 +00:00
Joelkurien
5a87d4fe9e Added method return type and resolved merge conflics 2024-10-26 03:18:39 +11:00
Joelkurien
a1ff5c95a3 Added return types to the functions 2024-10-26 03:17:05 +11:00
pre-commit-ci[bot]
e3db05b375 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2024-10-25 16:12:55 +00:00
Joelkurien
346a955946 Resolved issues regarding ruff testing and merge conflicts 2024-10-26 03:10:30 +11:00
Joelkurien
8286b5855a Resolving ruff issues 2024-10-26 03:04:37 +11:00
pre-commit-ci[bot]
18319a8733 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2024-10-25 16:01:30 +00:00
joelkurien
da0717b9ae updating DIRECTORY.md 2024-10-25 16:00:32 +00:00
Joelkurien
11bfe18e0d Implementation of Johnson Graph Algorithm 2024-10-26 03:00:10 +11:00
5 changed files with 194 additions and 4 deletions

View File

@ -16,7 +16,7 @@ repos:
- id: auto-walrus
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.7.2
rev: v0.7.4
hooks:
- id: ruff
- id: ruff-format
@ -42,7 +42,7 @@ repos:
pass_filenames: false
- repo: https://github.com/abravalheri/validate-pyproject
rev: v0.22
rev: v0.23
hooks:
- id: validate-pyproject

View File

@ -503,6 +503,7 @@
* [Graphs Floyd Warshall](graphs/graphs_floyd_warshall.py)
* [Greedy Best First](graphs/greedy_best_first.py)
* [Greedy Min Vertex Cover](graphs/greedy_min_vertex_cover.py)
* [Johnson Graph](graphs/johnson_graph.py)
* [Kahns Algorithm Long](graphs/kahns_algorithm_long.py)
* [Kahns Algorithm Topo](graphs/kahns_algorithm_topo.py)
* [Karger](graphs/karger.py)

View File

@ -172,7 +172,7 @@ def solved(values):
def from_file(filename, sep="\n"):
"Parse a file into a list of strings, separated by sep."
return open(filename).read().strip().split(sep) # noqa: SIM115
return open(filename).read().strip().split(sep)
def random_puzzle(assignments=17):

189
graphs/johnson_graph.py Normal file
View File

@ -0,0 +1,189 @@
import heapq
import sys
# First implementation of johnson algorithm
# Steps followed to implement this algorithm is given in the below link:
# https://brilliant.org/wiki/johnsons-algorithm/
class JohnsonGraph:
def __init__(self) -> None:
"""
Initializes an empty graph with no edges.
>>> g = JohnsonGraph()
>>> g.edges
[]
>>> g.graph
{}
"""
self.edges: list[tuple[str, str, int]] = []
self.graph: dict[str, list[tuple[str, int]]] = {}
# add vertices for a graph
def add_vertices(self, vertex: str) -> None:
"""
Adds a vertex `vertex` to the graph with an empty adjacency list.
>>> g = JohnsonGraph()
>>> g.add_vertices("A")
>>> g.graph
{'A': []}
"""
self.graph[vertex] = []
# assign weights for each edges formed of the directed graph
def add_edge(self, vertex_a: str, vertex_b: str, weight: int) -> None:
"""
Adds a directed edge from vertex `vertex_a`
to vertex `vertex_b` with weight `weight`.
>>> g = JohnsonGraph()
>>> g.add_vertices("A")
>>> g.add_vertices("B")
>>> g.add_edge("A", "B", 5)
>>> g.edges
[('A', 'B', 5)]
>>> g.graph
{'A': [('B', 5)], 'B': []}
"""
self.edges.append((vertex_a, vertex_b, weight))
self.graph[vertex_a].append((vertex_b, weight))
# perform a dijkstra algorithm on a directed graph
def dijkstra(self, start: str) -> dict:
"""
Computes the shortest path from vertex `start`
to all other vertices using Dijkstra's algorithm.
>>> g = JohnsonGraph()
>>> g.add_vertices("A")
>>> g.add_vertices("B")
>>> g.add_edge("A", "B", 1)
>>> g.dijkstra("A")
{'A': 0, 'B': 1}
>>> g.add_vertices("C")
>>> g.add_edge("B", "C", 2)
>>> g.dijkstra("A")
{'A': 0, 'B': 1, 'C': 3}
"""
distances = {vertex: sys.maxsize - 1 for vertex in self.graph}
pq = [(0, start)]
distances[start] = 0
while pq:
weight, vertex = heapq.heappop(pq)
if weight > distances[vertex]:
continue
for node, node_weight in self.graph[vertex]:
if distances[vertex] + node_weight < distances[node]:
distances[node] = distances[vertex] + node_weight
heapq.heappush(pq, (distances[node], node))
return distances
# carry out the bellman ford algorithm for a node and estimate its distance vector
def bellman_ford(self, start: str) -> dict:
"""
Computes the shortest path from vertex `start` to
all other vertices using the Bellman-Ford algorithm.
>>> g = JohnsonGraph()
>>> g.add_vertices("A")
>>> g.add_vertices("B")
>>> g.add_edge("A", "B", 1)
>>> g.bellman_ford("A")
{'A': 0, 'B': 1}
>>> g.add_vertices("C")
>>> g.add_edge("B", "C", 2)
>>> g.bellman_ford("A")
{'A': 0, 'B': 1, 'C': 3}
"""
distances = {vertex: sys.maxsize - 1 for vertex in self.graph}
distances[start] = 0
for vertex_a in self.graph:
for vertex_a, vertex_b, weight in self.edges:
if (
distances[vertex_a] != sys.maxsize - 1
and distances[vertex_a] + weight < distances[vertex_b]
):
distances[vertex_b] = distances[vertex_a] + weight
return distances
# perform the johnson algorithm to handle the negative weights that
# could not be handled by either the dijkstra
# or the bellman ford algorithm efficiently
def johnson_algo(self) -> list[dict]:
"""
Computes the shortest paths between
all pairs of vertices using Johnson's algorithm
for a directed graph.
>>> g = JohnsonGraph()
>>> g.add_vertices("A")
>>> g.add_vertices("B")
>>> g.add_edge("A", "B", 1)
>>> g.add_edge("B", "A", 2)
>>> optimal_paths = g.johnson_algo()
>>> optimal_paths
[{'A': 0, 'B': 1}, {'A': 2, 'B': 0}]
"""
self.add_vertices("#")
for vertex in self.graph:
if vertex != "#":
self.add_edge("#", vertex, 0)
hash_path = self.bellman_ford("#")
for i in range(len(self.edges)):
vertex_a, vertex_b, weight = self.edges[i]
self.edges[i] = (
vertex_a,
vertex_b,
weight + hash_path[vertex_a] - hash_path[vertex_b],
)
self.edges[i] = (
vertex_a,
vertex_b,
weight + hash_path[vertex_a] - hash_path[vertex_b],
)
self.graph.pop("#")
filtered_edges = []
for vertex1, vertex2, node_weight in self.edges:
filtered_edges.append((vertex1, vertex2, node_weight))
self.edges = filtered_edges
for vertex in self.graph:
self.graph[vertex] = []
for vertex1, vertex2, node_weight in self.edges:
if vertex1 == vertex:
self.graph[vertex].append((vertex2, node_weight))
distances = []
for vertex1 in self.graph:
new_dist = self.dijkstra(vertex1)
for vertex2 in self.graph:
if new_dist[vertex2] < sys.maxsize - 1:
new_dist[vertex2] += hash_path[vertex2] - hash_path[vertex1]
for key in new_dist:
if new_dist[key] == sys.maxsize - 1:
new_dist[key] = None
distances.append(new_dist)
return distances
g = JohnsonGraph()
# this a complete connected graph
g.add_vertices("A")
g.add_vertices("B")
g.add_vertices("C")
g.add_vertices("D")
g.add_vertices("E")
g.add_edge("A", "B", 1)
g.add_edge("A", "C", 3)
g.add_edge("B", "D", 4)
g.add_edge("D", "E", 2)
g.add_edge("E", "C", -2)
optimal_paths = g.johnson_algo()
print("Print all optimal paths of a graph using Johnson Algorithm")
for i, row in enumerate(optimal_paths):
print(f"{i}: {row}")

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!python
import os
try: