visualizations

Programmatic visualizations
git clone git://git.laack.co/visualizations.git
Log | Files | Refs | README

commit fdae873b36c9fb425857063ebf4b45a5121af47f
parent ed2744af6c27869af1aa4ed17745c10ec05d367a
Author: Andrew Laack <andrew@laack.co>
Date:   Thu, 17 Sep 2026 09:34:42 -0500

Final benchmarking

Diffstat:
Agraph/benchmarking/no_render_final/bench.sh | 5+++++
Agraph/benchmarking/no_render_final/prim.py | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agraph/benchmarking/no_render_final/v200000e2000000 | 6++++++
Agraph/benchmarking/render_final/bench.sh | 5+++++
Agraph/benchmarking/render_final/prim.py | 128+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agraph/benchmarking/render_final/v10000e100000 | 6++++++
Agraph/benchmarking/render_fixed/out | 2++
Agraph/benchmarking/render_fixed/v_10000_e_100000 | 1+
Mgraph/prim.py | 42++++++++++++++++++++++++++++++------------
9 files changed, 273 insertions(+), 12 deletions(-)

diff --git a/graph/benchmarking/no_render_final/bench.sh b/graph/benchmarking/no_render_final/bench.sh @@ -0,0 +1,5 @@ +while [ 1 ]; do + /usr/bin/time -o out -f '%S,%U,%e' python3 prim.py >/dev/null 2>&1 + cat out | tee -a v200000e2000000 + sleep 1 +done diff --git a/graph/benchmarking/no_render_final/prim.py b/graph/benchmarking/no_render_final/prim.py @@ -0,0 +1,90 @@ +import heapq +import random +import math + +VERTICES = 200_000 +EDGES = 2_000_000 + +white = (255, 255, 255) +red = (255, 0, 0) +black = (0, 0, 0) +grey = (100,100,100) +light_grey = (50,50,50) + + +class Vertex(): + def __init__(self, x, y): + self.x = x + self.y = y + self.visited = False +class Edge(): + def __init__(self, v1, v2): + self.v1 = v1 + self.v2 = v2 + self.dist = math.sqrt(((v1.x - v2.x) ** 2) + ((v1.y - v2.y) ** 2)) + def __lt__(self,otr): + return self.dist < otr.dist + + +graph = {} + +for i in range(0,VERTICES): + x = random.random() * 5120 + y = random.random() * 1440 + graph[Vertex(x,y)] = [] + + +edge_list = [] +keys = list(graph.keys()) + +for i in range(0,EDGES): + k1 = None + k2 = None + while k1 == k2: + k1 = random.choice(keys) + k2 = random.choice(keys) + + edge = Edge(k1,k2) + graph[k1].append(edge) + graph[k2].append(edge) + edge_list.append(edge) + + +edge_heap = [] +visited_vertices = set() + + +start = random.choice(keys) +start.visited = True +visited_vertices.add(start) +for edge in graph[start]: + heapq.heappush(edge_heap, edge) + + +first = True + +# we still have this for consistency with the c++ variant because the c++ variant is also tracking this info. +to_draw_vert = [] +to_draw_edge = [] + +while True: + item = None + while edge_heap: + candidate = heapq.heappop(edge_heap) + if (candidate.v1 in visited_vertices) != (candidate.v2 in visited_vertices): + item = candidate + break + + if item is None: + break + + new_vertex = item.v2 if item.v1 in visited_vertices else item.v1 + visited_vertices.add(new_vertex) + new_vertex.visited = True + + to_draw_vert.append(new_vertex) + to_draw_edge.append(item) + + for edge in graph[new_vertex]: + if not edge.v1 in visited_vertices or not edge.v2 in visited_vertices: + heapq.heappush(edge_heap, edge) diff --git a/graph/benchmarking/no_render_final/v200000e2000000 b/graph/benchmarking/no_render_final/v200000e2000000 @@ -0,0 +1,6 @@ +0.12,19.95,20.18 +0.11,19.83,20.01 +0.12,20.17,20.36 +0.13,20.10,20.30 +0.13,20.12,20.33 +0.11,20.15,20.34 diff --git a/graph/benchmarking/render_final/bench.sh b/graph/benchmarking/render_final/bench.sh @@ -0,0 +1,5 @@ +while [ 1 ]; do + /usr/bin/time -o out -f '%S,%U,%e' python3 prim.py >/dev/null 2>&1 + cat out | tee -a v10000e100000 + sleep 1 +done diff --git a/graph/benchmarking/render_final/prim.py b/graph/benchmarking/render_final/prim.py @@ -0,0 +1,128 @@ +import pygame +import heapq +import random +import math + +pygame.init() + +display = pygame.display.set_mode((5120,1440)) + +VERTICES = 10000 +EDGES = 100000 + +white = (255, 255, 255) +red = (255, 0, 0) +black = (0, 0, 0) +grey = (100,100,100) +light_grey = (50,50,50) + + +class Vertex(): + def __init__(self, x, y): + self.x = x + self.y = y + self.visited = False + def draw_vertex(self,display): + if self.visited: + pygame.draw.circle(display, white, (self.x,self.y), 5) + else: + pygame.draw.circle(display, grey, (self.x,self.y), 5) +class Edge(): + def __init__(self, v1, v2): + self.v1 = v1 + self.v2 = v2 + self.dist = math.sqrt(((v1.x - v2.x) ** 2) + ((v1.y - v2.y) ** 2)) + def draw_edge(self,display, c): + pygame.draw.line(display, c, (self.v1.x,self.v1.y), (self.v2.x,self.v2.y), 1) + + def __lt__(self,otr): + return self.dist < otr.dist + + +graph = {} + +for i in range(0,VERTICES): + x = random.random() * 5120 + y = random.random() * 1440 + graph[Vertex(x,y)] = [] + + +edge_list = [] +keys = list(graph.keys()) + +for i in range(0,EDGES): + k1 = None + k2 = None + while k1 == k2: + k1 = random.choice(keys) + k2 = random.choice(keys) + + edge = Edge(k1,k2) + graph[k1].append(edge) + graph[k2].append(edge) + edge_list.append(edge) + + +edge_heap = [] +visited_vertices = set() + + +start = random.choice(keys) +start.visited = True +visited_vertices.add(start) +for edge in graph[start]: + heapq.heappush(edge_heap, edge) + + +first = True + +to_draw_vert = [] +to_draw_edge = [] + +while True: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + quit() + + if first: + display.fill(black) + + for edge in edge_list: + edge.draw_edge(display, light_grey) + first = False + + for vertex in graph: + vertex.draw_vertex(display) + + for edge in to_draw_edge: + edge.draw_edge(display, white) + for vert in to_draw_vert: + vert.draw_vertex(display) + + to_draw_vert = [] + to_draw_edge = [] + + + item = None + while edge_heap: + candidate = heapq.heappop(edge_heap) + if (candidate.v1 in visited_vertices) != (candidate.v2 in visited_vertices): + item = candidate + break + + if item is None: + break + + new_vertex = item.v2 if item.v1 in visited_vertices else item.v1 + visited_vertices.add(new_vertex) + new_vertex.visited = True + + to_draw_vert.append(new_vertex) + to_draw_edge.append(item) + + for edge in graph[new_vertex]: + if not edge.v1 in visited_vertices or not edge.v2 in visited_vertices: + heapq.heappush(edge_heap, edge) + + pygame.display.update() diff --git a/graph/benchmarking/render_final/v10000e100000 b/graph/benchmarking/render_final/v10000e100000 @@ -0,0 +1,6 @@ +1.49,52.97,59.67 +1.35,53.08,59.09 +1.37,52.48,58.43 +1.32,52.55,58.51 +1.29,52.14,58.09 +0.14,4.00,3.70 diff --git a/graph/benchmarking/render_fixed/out b/graph/benchmarking/render_fixed/out @@ -0,0 +1,2 @@ +Command terminated by signal 2 +0.07,3.66,3.09 diff --git a/graph/benchmarking/render_fixed/v_10000_e_100000 b/graph/benchmarking/render_fixed/v_10000_e_100000 @@ -0,0 +1 @@ +1.33,10730.71,10772.74 diff --git a/graph/prim.py b/graph/prim.py @@ -7,9 +7,8 @@ pygame.init() display = pygame.display.set_mode((5120,1440)) - -VERTICES = 1000 -EDGES = 10000 +VERTICES = 10000 +EDGES = 100000 white = (255, 255, 255) red = (255, 0, 0) @@ -67,28 +66,43 @@ for i in range(0,EDGES): edge_heap = [] visited_vertices = set() -mst = [] -start = random.choice(list(graph.keys())) +start = random.choice(keys) start.visited = True visited_vertices.add(start) for edge in graph[start]: heapq.heappush(edge_heap, edge) + +first = True + +to_draw_vert = [] +to_draw_edge = [] + while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() + if first: + display.fill(black) + + for edge in edge_list: + edge.draw_edge(display, light_grey) + first = False + + for vertex in graph: + vertex.draw_vertex(display) - display.fill(black) - for edge in edge_list: - edge.draw_edge(display, light_grey) - for edge in mst: + for edge in to_draw_edge: edge.draw_edge(display, white) - for vertex in graph: - vertex.draw_vertex(display) + for vert in to_draw_vert: + vert.draw_vertex(display) + + to_draw_vert = [] + to_draw_edge = [] + item = None while edge_heap: @@ -103,8 +117,12 @@ while True: new_vertex = item.v2 if item.v1 in visited_vertices else item.v1 visited_vertices.add(new_vertex) new_vertex.visited = True - mst.append(item) + + to_draw_vert.append(new_vertex) + to_draw_edge.append(item) + for edge in graph[new_vertex]: if not edge.v1 in visited_vertices or not edge.v2 in visited_vertices: heapq.heappush(edge_heap, edge) + pygame.display.update()