Skip to content

Commit a54f2e0

Browse files
committed
Add Aldous-Broder algorithm. Make image demo open generated image under Linux
1 parent 7d8e24b commit a54f2e0

File tree

6 files changed

+49
-8
lines changed

6 files changed

+49
-8
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ A small remark: Code is not a 1:1 copy of the book's. For example I built render
88

99
## Implemented algorithms
1010

11+
- `AldousBroder`
1112
- `BinaryTree`
1213
- `Sidewinder`
1314

algorithms/aldous_broder.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from random import choice
2+
3+
from base.grid import Grid
4+
5+
"""
6+
Aldous-Broder algorithm works by always choosing a random neighbor of the current cell and linking them if not yet
7+
visited ("random walking"), repeating until all cells are visited once.
8+
Can take long to compute on big grids.
9+
"""
10+
11+
12+
class AldousBroder:
13+
14+
@staticmethod
15+
def on(grid: Grid) -> Grid:
16+
current_cell = grid.random_cell()
17+
unvisited_count = grid.size - 1
18+
19+
while unvisited_count > 0:
20+
neighbor = choice(current_cell.neighbors())
21+
if neighbor is None:
22+
raise ValueError("Aldous-Broder algorithm needs all cells to have at least one neighbor")
23+
if len(neighbor.links) == 0:
24+
current_cell.link(neighbor)
25+
unvisited_count -= 1
26+
current_cell = neighbor
27+
28+
return grid

base/grid.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ def rows(self) -> int:
1414
def columns(self) -> int:
1515
return self._columns
1616

17+
@property
18+
def size(self) -> int:
19+
return self.rows * self.columns
20+
1721
def __init__(self, rows: int, columns: int) -> None:
1822
if rows is None or rows < 0:
1923
raise ValueError("Rows must be a positive integer")
@@ -47,9 +51,6 @@ def random_cell(self) -> Cell:
4751
row = randint(0, self.rows - 1)
4852
return cast(Cell, self.get_cell(row, column))
4953

50-
def size(self) -> int:
51-
return self.rows * self.columns
52-
5354
def each_row(self) -> Generator:
5455
for row in range(self.rows):
5556
yield self._grid[row]

demos/demo_utils.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33

44
from algorithms.binary_tree import BinaryTree
55
from algorithms.sidewinder import Sidewinder
6+
from algorithms.aldous_broder import AldousBroder
7+
68
import renderers.ascii_renderer as ASCIIRenderer
79
import renderers.unicode_renderer as UNICODERenderer
810
import renderers.png_renderer as PNGRenderer
911

10-
ALGORITHMS = [BinaryTree, Sidewinder]
12+
ALGORITHMS = [BinaryTree, Sidewinder, AldousBroder]
1113
ALL_RENDERERS = [UNICODERenderer, ASCIIRenderer, PNGRenderer]
1214

1315

demos/image_demo.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import platform
2+
import subprocess
3+
from time import gmtime, strftime
4+
15
import args
26
from typing import cast, Union # noqa: F401
37

@@ -68,4 +72,9 @@ def get_coloring() -> bool:
6872
raise IndexError("Invalid start cell row {} column {}".format(start_row, start_column))
6973
grid.distances = start_cell.distances() # type: ignore
7074

71-
renderer.render(grid, coloring=coloring)
75+
filename = strftime("%Y%m%d%H%M%S", gmtime())
76+
77+
renderer.render(grid, coloring=coloring, filename=filename)
78+
79+
if platform.system() == "Linux":
80+
subprocess.run(["xdg-open", "{}.png".format(filename)])

test/test_grid.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,6 @@ def test_random_cell() -> None:
5959

6060

6161
def test_size() -> None:
62-
assert Grid(1, 1).size() == 1
63-
assert Grid(2, 2).size() == 4
64-
assert Grid(3, 3).size() == 9
62+
assert Grid(1, 1).size == 1
63+
assert Grid(2, 2).size == 4
64+
assert Grid(3, 3).size == 9

0 commit comments

Comments
 (0)