kopia lustrzana https://github.com/villares/sketch-a-day
stochastic search
rodzic
91b8abb6d1
commit
f6e1cae675
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 |
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,12 @@
|
|||
|
||||
---
|
||||
|
||||

|
||||
|
||||
[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](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)]
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue