stochastic search

main
Alexandre B A Villares 2020-08-08 17:40:26 -03:00
rodzic 91b8abb6d1
commit f6e1cae675
7 zmienionych plików z 129 dodań i 72 usunięć

Wyświetl plik

@ -44,10 +44,6 @@ def draw():
fill(0)
text(v.upper(), x - 15, y - 3)
noStroke()
fill(255, 0, 0)
x, y, _ = grid[sel_v]
circle(x, y, 10)
walker()
def walker():
@ -61,6 +57,12 @@ def walker():
t_walker += .01
else:
path_walker = []
else:
noStroke()
fill(255, 0, 0)
x, y, _ = grid[sel_v]
circle(x, y, 10)
def setup_grid(graph):
cols, rows = dimensionar_grade(len(graph))

Wyświetl plik

@ -5,6 +5,8 @@ A simple Python graph class, demonstrating the essential facts and functionaliti
based on https://www.python-course.eu/graphs_python.php and https://www.python.org/doc/essays/graphs/
"""
from random import choice
class Graph(object):
def __init__(self, graph_dict=None):
@ -67,7 +69,12 @@ class Graph(object):
else:
self.__graph_dict[vertex1] = [vertex1]
def remove_vertex(self, vert):
raise NotImplemented
def remove_edge(self, vert):
raise NotImplemented
def __generate_edges(self):
"""
@ -269,3 +276,21 @@ class Graph(object):
dist[next] = dist[at]+[next] # less efficient but nicer output
q.append(next)
return dist.get(end)
def get_random_vertex(self):
return choice(self.vertices())
@staticmethod
def random_graph(names, connect_rate=.9, allow_loops=True):
vertices = set(names)
graph = Graph()
for v in vertices:
graph.add_vertex(v)
if random(1) < connect_rate:
if allow_loops:
names = list(vertices)
else:
names = list(vertices - set(v))
graph.add_edge({v, choice(names)})
return graph

Wyświetl plik

@ -0,0 +1,57 @@
#*- coding: utf-8 -*-
def setup_grid(graph, margin=None):
margin = margin or width / 40
cols, rows = dim_grid(len(graph))
w, h = (width - margin * 2) / cols, (height - margin * 2) / rows
points = []
for i in range(cols * rows):
c = i % cols
r = i // rows
x = margin + w * 0.5 + c * w - 20 * (r % 2) + 5 * r
y = margin + h * 0.5 + r * h - 20 * (c % 2) + 5 * c
z = 0
points.append((x, y, z))
points = sorted(
points, key=lambda p: dist(p[0], p[1], width / 2, height / 2))
v_list = reversed(sorted(graph.vertices(), key=graph.vertex_degree))
# v_list = sorted(graph.vertices(), key=graph.vertex_degree)
grid = {v: p for v, p in zip(v_list, points)}
return grid
def dim_grid(n):
a = int(sqrt(n))
b = n / a
if a * b < n:
b += 1
print(u'{}: {} × {} ({})'.format(n, a, b, a * b))
return a, b
def measure_graph_grid(graph, grid):
metric = 0
for edge in graph.edges():
if len(edge) == 2:
a, b = edge
d = PVector.dist(PVector(*grid[a]),
PVector(*grid[b]))
metric += d
return metric
def grid_swap(graph, grid):
from random import sample
fail = 0
n = m = measure_graph_grid(graph, grid)
while m <= n and fail < len(graph) ** 2:
new_grid= dict(grid)
a, b = sample(graph, 2)
new_grid[a], new_grid[b] = new_grid[b], new_grid[a]
n = measure_graph_grid(graph, new_grid)
if m > n:
print("at: {}".format(fail))
return new_grid
else:
fail += 1
print("no new grid")
return grid

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 146 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 475 KiB

Wyświetl plik

@ -1,7 +1,6 @@
from random import choice
from graph import Graph
MARGIN = 10
from grid import setup_grid, measure_graph_grid, grid_swap
def setup():
size(400, 400)
@ -13,14 +12,14 @@ def setup():
def setup_graph():
global graph, grid
graph = random_graph()
grid = setup_grid(graph)
graph = Graph.random_graph("abcdefghijklmnop", allow_loops=False)
grid = setup_grid(graph, margin=10)
global sel_v
sel_v = select_random_vertex(graph)
sel_v = graph.get_random_vertex()
global path_walker, t_walker
path_walker = []
t_walker = 0
print(graph)
# print(graph)
def draw():
background(150)
@ -37,89 +36,57 @@ def draw():
else:
circle(20 + xa, ya, 30)
for v in grid.keys():
x, y, z = grid[v]
fill(255)
circle(x, y, 10)
fill(0)
text(v.upper(), x - 15, y - 3)
noStroke()
fill(255, 0, 0)
x, y, _ = grid[sel_v]
circle(x, y, 10)
walker()
walker()
def walker():
global t_walker, path_walker, sel_v
if path_walker:
if path_walker and t_walker < 1:
# print(t_walker, path_walker)
p = lerpVectors(t_walker, path_walker)
noFill()
stroke(0, 0, 255)
circle(p.x, p.y, 10)
if t_walker < 1:
t_walker += .01
else:
path_walker = []
def setup_grid(graph):
cols, rows = dimensionar_grade(len(graph))
w, h = (width - MARGIN * 2) / cols, (height - MARGIN * 2) / rows
points = []
for i in range(cols * rows):
c = i % cols
r = i // rows
x = MARGIN + w * 0.5 + c * w - 20 * (r % 2) + 5 * r
y = MARGIN + h * 0.5 + r * h - 20 * (c % 2) + 5 * c
z = 0
points.append((x, y, z))
points = sorted(
points, key=lambda p: dist(p[0], p[1], width / 2, height / 2))
v_list = reversed(sorted(graph.vertices(), key=graph.vertex_degree))
# v_list = sorted(graph.vertices(), key=graph.vertex_degree)
grid = {v: p for v, p in zip(v_list, points)}
return grid
t_walker += .03 / len(path_walker)
else:
path_walker = []
noStroke()
fill(255, 0, 0)
x, y, _ = grid[sel_v]
circle(x, y, 10)
def random_graph(names="abcdefghijklmnop"):
graph = Graph()
for v in names:
graph.add_vertex(v)
if random(100) < 90:
graph.add_edge({v, choice(names)})
return graph
def lerpVectors(amt, vecs):
""" from Jeremy Douglass """
amt = constrain(amt, 0, 1) # let's play safe
if len(vecs) == 1:
return vecs[0]
cunit = 1.0 / (len(vecs) - 1)
return PVector.lerp(vecs[floor(amt / cunit)],
vecs[ceil(amt / cunit)],
amt % cunit / cunit)
def select_random_vertex(graph):
return choice(graph.vertices())
def keyTyped():
if key == 'r':
setup_graph()
if key == 's':
global grid
grid = grid_swap(graph, grid)
print(measure_graph_grid(graph, grid))
def dimensionar_grade(n):
a = int(sqrt(n))
b = n / a
if a * b < n:
b += 1
print(u'{}: {} × {} ({})'.format(n, a, b, a * b))
return a, b
def keyPressed():
setup_graph()
# saveFrame('##_sketch_2020_08_04a.png')
def mousePressed():
global path_walker, t_walker, sel_v
for v in graph:
x, y, _ = grid[v]
if v != sel_v and dist(x, y, mouseX, mouseY) < 10:
path = graph.find_path(sel_v, v)
path = graph.find_shortest_path(sel_v, v)
if path:
path_walker = [PVector(*grid[pv]) for pv in path]
t_walker = 0
sel_v = v
def lerpVectors(amt, vecs):
""" from Jeremy Douglass """
if len(vecs) == 1:
return vecs[0]
cunit = 1.0 / (len(vecs) - 1)
return PVector.lerp(vecs[floor(amt / cunit)],
vecs[ceil(amt / cunit)],
amt % cunit / cunit)

Wyświetl plik

@ -22,6 +22,12 @@
---
![sketch_2020_08_08a](2020/sketch_2020_08_08a/sketch_2020_08_08a.gif)
[sketch_2020_08_08a](https://github.com/villares/sketch-a-day/tree/master/2020/sketch_2020_08_08a) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)]
---
![sketch_2020_08_07a](2020/sketch_2020_08_07a/sketch_2020_08_07a.gif)
[sketch_2020_08_07a](https://github.com/villares/sketch-a-day/tree/master/2020/sketch_2020_08_07a) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)]