ubergeekism/run_all.py
2014-04-03 22:17:31 +02:00

212 lines
6.6 KiB
Python
Executable file

#!/usr/bin/env python
import sys
import turtle
import argparse
import matplotlib.pyplot as plot
import ants
import utils
from utils import LOG,LOGN
import hull
import uberplot
import shortpath
import lindenmayer
import triangulation
parser = argparse.ArgumentParser()
parser.add_argument('-p', "--penrose", help="Do not compute the Penrose tiling but load it from a file",
default=None, action='store', type=str, metavar="SEGMENTS")
parser.add_argument( '-d', '--depth', help="Recursive depth of the Lindenmayer computations = size of the Penrose tiling",
default=1, type=int, metavar="DEPTH")
parser.add_argument('-t', "--notsp", help="Do not compute the TSP",
default=False, action='store_true')
parser.add_argument('-r', "--tour", help="Load several TSP tour from a file",
default=[None], action='store', type=str, nargs="*", metavar="POINTS")
parser.add_argument('-m', "--pheromones", help="Load a pheromones matrix from a file",
default=None, action='store', type=str, metavar="MATRIX")
parser.add_argument('-g', "--triangulation", help="Do not compute the Delaunay triangulation but load it from a file",
default=None, action='store', type=str, metavar="SEGMENTS")
args = parser.parse_args()
error_codes = {"NOTSP":100}
depth = args.depth
LOGN( "depth",depth )
########################################################################
# PENROSE TILING
########################################################################
penrose_segments = set()
if args.penrose:
LOGN( "Load the penrose tiling" )
penrose_segments = utils.load_segments(args.penrose)
else:
LOGN( "Draw the penrose tiling" )
segment_size = 10
float_rounding = 10
ttl = turtle.Turtle()
ttl.speed('fastest')
penrose = lindenmayer.DumpTurtleLSystem(ttl,
axiom="[X]++[X]++[X]++[X]++[X]",
rules={
'F': "",
'W': "YF++ZF----XF[-YF----WF]++",
'X': "+YF--ZF[---WF--XF]+",
'Y': "-WF++XF[+++YF++ZF]-",
'Z': "--YF++++WF[+ZF++++XF]--XF"
},
angle=36, heading=0, size=segment_size, rounding=float_rounding )
# actually do something
penrose.draw( depth )
# save this intermediate step
LOGN( "\tsegments",len(penrose.segments) )
with open("d%i_penrose.segments" % depth, "w") as fd:
fd.write( str(penrose) )
penrose_segments = penrose.segments
########################################################################
# TSP
########################################################################
trajs = []
if args.tour != [None]:
for tour in args.tour:
trajs.append( utils.load_points(tour) )
if args.notsp:
if args.tour == [None] or not args.pheromones:
LOGN( "If you do not want to solve the TSP, you must provide a solution tour (--tour) and a pheromones matrix (--pheromones)" )
sys.exit(error_codes["NO-TSP"])
if args.pheromones:
phero = utils.load_matrix(args.pheromones)
else:
LOGN( "Solve the TSP with an Ant Colony Algorithm" )
LOGN( "\tConvert the segment list into an adjacency list graph" )
G = utils.adjacency_from_set( penrose_segments )
LOGN( "\tCompute a tour" )
max_it = 10
num_ants = 10 #* depth
decay = 0.1
w_heur = 2.5
w_local_phero = 0.1
c_greed = 0.9
w_history = 1.0
best,phero = ants.search( G, max_it, num_ants, decay, w_heur, w_local_phero, w_history, c_greed, cost_func = ants.graph_distance )
LOGN( "\tTransform the resulting nodes permutation into a path on the graph" )
# by finding the shortest path between two cities.
traj = []
for start,end in utils.tour(best["permutation"]):
p,c = shortpath.astar( G, start, end )
traj += p
trajs.append(traj)
with open("d%i_tour.points" % depth, "w") as fd:
for p in traj:
fd.write("%f %f\n" % p)
with open("d%i_pheromones.mat" % depth, "w") as fd:
for row in phero:
key = "%f,%f:" % row
line = key
for k in phero[row]:
val = phero[row][k]
line += "%f,%f=%f " % (k[0],k[1],val)
fd.write( line + "\n" )
########################################################################
# TRIANGULATION
########################################################################
if args.triangulation:
triangulation_edges = utils.load_segments(args.triangulation)
else:
LOGN( "Compute the triangulation of the penrose vertices" )
points = utils.vertices_from_set(penrose_segments)
triangles = triangulation.delaunay_bowyer_watson( points, do_plot = False )
LOGN( "\tRemove triangles that have at least one edge in common with the convex hull" )
# Should convert the set into a list
hull = hull.convex_hull( list(points) )
hull_edges = list(utils.tour(hull))
LOGN( "\t\tHull",len(hull_edges),"edges" )
removed = set()
for triangle in triangles:
for edge in utils.tour(list(triangle)):
if edge in hull_edges:
removed.add( triangle )
LOGN( "\t\tRemove", len(removed), "triangles" )
for it in removed:
triangles.remove(it)
triangulation_edges = triangulation.edges_of( triangles )
with open("d%i_triangulation.segments" % depth, "w") as fd:
for p0,p1 in triangulation_edges:
fd.write("%f %f %f %f\n" % (p0[0],p0[1],p1[0],p1[1]) )
########################################################################
# PLOT
########################################################################
LOGN( "Plot the resulting tour" )
fig = plot.figure()
ax = fig.add_subplot(111)
LOGN( "\tpheromones",len(phero) )#,"x",len(phero[traj[0]]) )
maxph=0
for i in phero:
maxph = max( maxph, max(phero[i].values()))
# ant colony
# pheromones
for i in phero:
for j in phero[i]:
if i == j:
continue
nph = phero[i][j]/maxph
seg = [(i,j)]
# LOGN( nph,seg )
uberplot.plot_segments( ax, seg, edgecolor="blue", alpha=0.01*nph, linewidth=1*nph )
# uberplot.scatter_segments( ax, seg, color="red", alpha=0.5, linewidth=nph )
for traj in trajs:
LOGN( "\ttraj",len(traj) )
# best tour
uberplot.plot_segments( ax, utils.tour(traj), edgecolor="red", alpha=0.9, linewidth=3 )
LOGN( "\ttiling",len(penrose_segments) )
tcol = "black"
uberplot.plot_segments( ax, penrose_segments, edgecolor=tcol, alpha=0.9, linewidth=2 )
uberplot.scatter_segments( ax, penrose_segments, edgecolor=tcol, alpha=0.9, linewidth=1 )
# triangulation
uberplot.plot_segments( ax, triangulation_edges, edgecolor="green", alpha=0.2, linewidth=1 )
ax.set_aspect('equal')
plot.show()