Skip to content

feat: add 10 graph algorithms with tests - #14824

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

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-keeperalgorithms-keeperBot 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-keeperalgorithms-keeperBot 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 threadgraphs/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

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



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 threadgraphs/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 threadgraphs/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 threadgraphs/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 threadgraphs/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 threadgraphs/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 threadgraphs/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 threadgraphs/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-keeperalgorithms-keeperBot added awaiting reviews This PR is ready to be reviewed tests are failing Do not merge until tests pass labels Jun 19, 2026
@gangs2314
gangs2314force-pushed the add-graph-algorithms branch from 931f735 to e2883d5CompareJune 19, 2026 07:49

@algorithms-keeperalgorithms-keeperBot 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 threadfix_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 threadfix_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 threadfix_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 threadfix_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 threadfix_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 threadgraphs/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 threadgraphs/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 threadgraphs/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 threadgraphs/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 threadgraphs/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
gangs2314force-pushed the add-graph-algorithms branch from 3e034f7 to a6ac5acCompareJune 19, 2026 07:58

@algorithms-keeperalgorithms-keeperBot 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.

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

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



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

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

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 threadgraphs/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 threadgraphs/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 threadgraphs/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 threadgraphs/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 threadgraphs/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
gangs2314force-pushed the add-graph-algorithms branch from 0a7b85e to 7972009CompareJune 19, 2026 08:40
gangs2314and 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-keeperalgorithms-keeperBot 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.

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

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



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

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

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 threadgraphs/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 threadgraphs/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 threadgraphs/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 threadgraphs/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 threadgraphs/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

@cclauss

Copy link
Copy Markdown
Member

Closing require_type_hints PRs to prepare for Hacktoberfest

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

Labels

awaiting reviewsThis PR is ready to be reviewedrequire descriptive namesThis PR needs descriptive function and/or variable namesrequire type hintshttps://docs.python.org/3/library/typing.htmltests are failingDo not merge until tests pass

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@gangs2314@cclauss@jordandunmire97-ai