Skip to content

feat: add 10 graph algorithms with tests#14824

Open
gangs2314 wants to merge 2 commits into
TheAlgorithms:masterfrom
gangs2314:add-graph-algorithms
Open

feat: add 10 graph algorithms with tests#14824
gangs2314 wants to merge 2 commits into
TheAlgorithms:masterfrom
gangs2314:add-graph-algorithms

Conversation

@gangs2314

Copy link
Copy Markdown

Description

Implements 10 advanced graph algorithms with comprehensive tests.

Algorithms Added

  1. Floyd-Warshall - O(V³)
  2. Johnson's Algorithm - O(V² log V + VE)
  3. Hopcroft-Karp - O(E√V)
  4. Ford-Fulkerson (Edmonds-Karp) - O(VE²)
  5. Push-Relabel - O(V²√E)
  6. 2-SAT Solver - O(V + E)
  7. Chinese Postman - O(V³ + 2^k k²)
  8. Traveling Salesman (Held-Karp) - O(n² 2ⁿ)
  9. Heavy-Light Decomposition - O(n log² n)
  10. Maximum Bipartite Independent Set - O(E√V)

Checklist

  • Read CONTRIBUTING.md
  • Type hints for all functions
  • Docstrings with complexity analysis
  • Doctests with examples
  • pytest tests added and passing
  • ruff checks passing
  • Did NOT edit README or DIRECTORY.md

@algorithms-keeper algorithms-keeper Bot added require descriptive names This PR needs descriptive function and/or variable names require type hints https://docs.python.org/3/library/typing.html labels Jun 19, 2026

@algorithms-keeper algorithms-keeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Click here to look at the relevant links ⬇️

🔗 Relevant Links

Repository:

Python:

Automated review generated by algorithms-keeper. If there's any problem regarding this review, please open an issue about it.

algorithms-keeper commands and options

algorithms-keeper actions can be triggered by commenting on this PR:

  • @algorithms-keeper review to trigger the checks for only added pull request files
  • @algorithms-keeper review-all to trigger the checks for all the pull request files, including the modified files. As we cannot post review comments on lines not part of the diff, this command will post all the messages in one comment.

NOTE: Commands are in beta and so this feature is restricted only to a member or owner of the organization.

Comment thread graphs/chinese_postman.py Outdated
Solve Chinese Postman Problem for weighted undirected graphs.
"""

def __init__(self, n: int):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide return type hint for the function: __init__. If the function does not return a value, please provide the type hint as: def function() -> None:

Please provide descriptive name for the parameter: n

Comment thread graphs/chinese_postman.py
self.adj: list[list[tuple[int, int]]] = [[] for _ in range(n)]
self.total_weight = 0

def add_edge(self, u: int, v: int, w: int) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: u

Please provide descriptive name for the parameter: v

Please provide descriptive name for the parameter: w

Comment thread graphs/chinese_postman.py


def chinese_postman(
n: int, edges: list[tuple[int, int, int]]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: n

Comment thread graphs/floyd_warshall.py Outdated
import random
import time

def benchmark():

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide return type hint for the function: benchmark. If the function does not return a value, please provide the type hint as: def function() -> None:

Comment thread graphs/ford_fulkerson.py Outdated
Maximum flow using Ford-Fulkerson with Edmonds-Karp (BFS).
"""

def __init__(self, n: int):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide return type hint for the function: __init__. If the function does not return a value, please provide the type hint as: def function() -> None:

Please provide descriptive name for the parameter: n

Comment thread graphs/two_sat.py
self.rev_graph[b].append(not_a)
self.rev_graph[a].append(not_b)

def add_implication(self, i: int, val_i: bool, j: int, val_j: bool) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: i

Please provide descriptive name for the parameter: j

Comment thread graphs/two_sat.py
self.graph[a].append(b)
self.rev_graph[b].append(a)

def add_nand(self, i: int, val_i: bool, j: int, val_j: bool) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: i

Please provide descriptive name for the parameter: j

Comment thread graphs/two_sat.py Outdated
visited = [False] * n
order = []

def dfs1(u: int):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide return type hint for the function: dfs1. If the function does not return a value, please provide the type hint as: def function() -> None:

Please provide descriptive name for the parameter: u

Comment thread graphs/two_sat.py Outdated
component = [-1] * n
current_comp = 0

def dfs2(u: int):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide return type hint for the function: dfs2. If the function does not return a value, please provide the type hint as: def function() -> None:

Please provide descriptive name for the parameter: u

Comment thread graphs/two_sat.py
return assignment


def solve_2sat(n: int, clauses: list[tuple[int, bool, int, bool]]) -> list[bool] | None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: n

@algorithms-keeper algorithms-keeper Bot added awaiting reviews This PR is ready to be reviewed tests are failing Do not merge until tests pass labels Jun 19, 2026
@gangs2314 gangs2314 force-pushed the add-graph-algorithms branch from 931f735 to e2883d5 Compare June 19, 2026 07:49

@algorithms-keeper algorithms-keeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Click here to look at the relevant links ⬇️

🔗 Relevant Links

Repository:

Python:

Automated review generated by algorithms-keeper. If there's any problem regarding this review, please open an issue about it.

algorithms-keeper commands and options

algorithms-keeper actions can be triggered by commenting on this PR:

  • @algorithms-keeper review to trigger the checks for only added pull request files
  • @algorithms-keeper review-all to trigger the checks for all the pull request files, including the modified files. As we cannot post review comments on lines not part of the diff, this command will post all the messages in one comment.

NOTE: Commands are in beta and so this feature is restricted only to a member or owner of the organization.

Comment thread fix_minimal.py Outdated


def fix_chinese_postman():
p = Path("graphs/chinese_postman.py")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide return type hint for the function: fix_chinese_postman. If the function does not return a value, please provide the type hint as: def function() -> None:

Comment thread fix_minimal.py Outdated
def fix_ford_fulkerson():
p = Path("graphs/ford_fulkerson.py")
text = p.read_text()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide return type hint for the function: fix_ford_fulkerson. If the function does not return a value, please provide the type hint as: def function() -> None:

Comment thread fix_minimal.py Outdated
text = p.read_text()

text = text.replace(' def benchmark():', ' def benchmark() -> None:')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide return type hint for the function: fix_floyd_warshall. If the function does not return a value, please provide the type hint as: def function() -> None:

Comment thread fix_minimal.py Outdated
text = p.read_text()

text = text.replace('def dfs1(u: int):', 'def dfs1(u: int) -> None:')
text = text.replace('def dfs2(u: int):', 'def dfs2(u: int) -> None:')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide return type hint for the function: fix_two_sat. If the function does not return a value, please provide the type hint as: def function() -> None:

Comment thread fix_minimal.py Outdated
text = p.read_text()

# Fix johnson test expectation
text = text.replace('assert dist[0][4] == -1', 'assert dist[0][4] == 0')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide return type hint for the function: fix_test_graph_algorithms. If the function does not return a value, please provide the type hint as: def function() -> None:

Comment thread graphs/two_sat.py
self.rev_graph[b].append(not_a)
self.rev_graph[a].append(not_b)

def add_implication(self, i: int, val_i: bool, j: int, val_j: bool) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: i

Please provide descriptive name for the parameter: j

Comment thread graphs/two_sat.py
self.graph[a].append(b)
self.rev_graph[b].append(a)

def add_nand(self, i: int, val_i: bool, j: int, val_j: bool) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: i

Please provide descriptive name for the parameter: j

Comment thread graphs/two_sat.py
visited = [False] * n
order = []

def dfs1(u: int) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: u

Comment thread graphs/two_sat.py
component = [-1] * n
current_comp = 0

def dfs2(u: int) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: u

Comment thread graphs/two_sat.py
return assignment


def solve_2sat(n: int, clauses: list[tuple[int, bool, int, bool]]) -> list[bool] | None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: n

@gangs2314 gangs2314 force-pushed the add-graph-algorithms branch from 3e034f7 to a6ac5ac Compare June 19, 2026 07:58

@algorithms-keeper algorithms-keeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Click here to look at the relevant links ⬇️

🔗 Relevant Links

Repository:

Python:

Automated review generated by algorithms-keeper. If there's any problem regarding this review, please open an issue about it.

algorithms-keeper commands and options

algorithms-keeper actions can be triggered by commenting on this PR:

  • @algorithms-keeper review to trigger the checks for only added pull request files
  • @algorithms-keeper review-all to trigger the checks for all the pull request files, including the modified files. As we cannot post review comments on lines not part of the diff, this command will post all the messages in one comment.

NOTE: Commands are in beta and so this feature is restricted only to a member or owner of the organization.

Comment thread graphs/chinese_postman.py
Solve Chinese Postman Problem for weighted undirected graphs.
"""

def __init__(self, n: int) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: n

Comment thread graphs/chinese_postman.py
self.adj: list[list[tuple[int, int]]] = [[] for _ in range(n)]
self.total_weight = 0

def add_edge(self, u: int, v: int, w: int) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: u

Please provide descriptive name for the parameter: v

Please provide descriptive name for the parameter: w

Comment thread graphs/chinese_postman.py


def chinese_postman(
n: int, edges: list[tuple[int, int, int]]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: n

Comment thread graphs/ford_fulkerson.py
Maximum flow using Ford-Fulkerson with Edmonds-Karp (BFS).
"""

def __init__(self, n: int) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: n

Comment thread graphs/ford_fulkerson.py
self.capacity: list[list[int]] = [[0] * n for _ in range(n)]
self.flow: list[list[int]] = [[0] * n for _ in range(n)]

def add_edge(self, u: int, v: int, cap: int) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: u

Please provide descriptive name for the parameter: v

Comment thread graphs/two_sat.py
self.rev_graph[b].append(not_a)
self.rev_graph[a].append(not_b)

def add_implication(self, i: int, val_i: bool, j: int, val_j: bool) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: i

Please provide descriptive name for the parameter: j

Comment thread graphs/two_sat.py
self.graph[a].append(b)
self.rev_graph[b].append(a)

def add_nand(self, i: int, val_i: bool, j: int, val_j: bool) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: i

Please provide descriptive name for the parameter: j

Comment thread graphs/two_sat.py
visited = [False] * n
order = []

def dfs1(u: int) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: u

Comment thread graphs/two_sat.py
component = [-1] * n
current_comp = 0

def dfs2(u: int) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: u

Comment thread graphs/two_sat.py
return assignment


def solve_2sat(n: int, clauses: list[tuple[int, bool, int, bool]]) -> list[bool] | None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: n

@gangs2314 gangs2314 force-pushed the add-graph-algorithms branch from 0a7b85e to 7972009 Compare June 19, 2026 08:40
gangs2314 and others added 2 commits June 19, 2026 14:10
Implemented algorithms:
- Floyd-Warshall (all-pairs shortest path)
- Johnson's Algorithm (sparse graph all-pairs)
- Hopcroft-Karp (maximum bipartite matching)
- Ford-Fulkerson with Edmonds-Karp (max flow)
- Push-Relabel (max flow)
- 2-SAT Solver
- Chinese Postman Problem
- Traveling Salesman (Held-Karp)
- Heavy-Light Decomposition
- Maximum Bipartite Independent Set

All include:
- Type hints and docstrings with complexity analysis
- Doctests with examples
- Comprehensive pytest test suite

@algorithms-keeper algorithms-keeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Click here to look at the relevant links ⬇️

🔗 Relevant Links

Repository:

Python:

Automated review generated by algorithms-keeper. If there's any problem regarding this review, please open an issue about it.

algorithms-keeper commands and options

algorithms-keeper actions can be triggered by commenting on this PR:

  • @algorithms-keeper review to trigger the checks for only added pull request files
  • @algorithms-keeper review-all to trigger the checks for all the pull request files, including the modified files. As we cannot post review comments on lines not part of the diff, this command will post all the messages in one comment.

NOTE: Commands are in beta and so this feature is restricted only to a member or owner of the organization.

Comment thread graphs/chinese_postman.py
Solve Chinese Postman Problem for weighted undirected graphs.
"""

def __init__(self, n: int) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: n

Comment thread graphs/chinese_postman.py
self.adj: list[list[tuple[int, int]]] = [[] for _ in range(n)]
self.total_weight = 0

def add_edge(self, u: int, v: int, w: int) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: u

Please provide descriptive name for the parameter: v

Please provide descriptive name for the parameter: w

Comment thread graphs/chinese_postman.py


def chinese_postman(
n: int, edges: list[tuple[int, int, int]]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: n

Comment thread graphs/ford_fulkerson.py
Maximum flow using Ford-Fulkerson with Edmonds-Karp (BFS).
"""

def __init__(self, n: int) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: n

Comment thread graphs/ford_fulkerson.py
self.capacity: list[list[int]] = [[0] * n for _ in range(n)]
self.flow: list[list[int]] = [[0] * n for _ in range(n)]

def add_edge(self, u: int, v: int, cap: int) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: u

Please provide descriptive name for the parameter: v

Comment thread graphs/two_sat.py
self.rev_graph[b].append(not_a)
self.rev_graph[a].append(not_b)

def add_implication(self, i: int, val_i: bool, j: int, val_j: bool) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: i

Please provide descriptive name for the parameter: j

Comment thread graphs/two_sat.py
self.graph[a].append(b)
self.rev_graph[b].append(a)

def add_nand(self, i: int, val_i: bool, j: int, val_j: bool) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: i

Please provide descriptive name for the parameter: j

Comment thread graphs/two_sat.py
visited = [False] * n
order = []

def dfs1(u: int) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: u

Comment thread graphs/two_sat.py
component = [-1] * n
current_comp = 0

def dfs2(u: int) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: u

Comment thread graphs/two_sat.py
return assignment


def solve_2sat(n: int, clauses: list[tuple[int, bool, int, bool]]) -> list[bool] | None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: n

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting reviews This PR is ready to be reviewed require descriptive names This PR needs descriptive function and/or variable names require type hints https://docs.python.org/3/library/typing.html tests are failing Do not merge until tests pass

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant