249 lines
6.7 KiB
Python
249 lines
6.7 KiB
Python
import sys
|
|
import scipy
|
|
|
|
def write_segments( segments, size, depth, rounding, fd = sys.stdout,
|
|
node_coord_section=False,
|
|
edge_data_section=False,
|
|
edge_weight_section=True,
|
|
display_data_section=True ):
|
|
|
|
# construct a {coords:id} dictionary
|
|
nodes = {}
|
|
nb = 0
|
|
for segment in segments:
|
|
for coords in segment:
|
|
if not nodes.has_key(coords):
|
|
nodes[coords] = nb
|
|
nb += 1
|
|
|
|
fd.write( "NAME : penrose3_%i\n" % depth)
|
|
fd.write("COMMENT : Rhombus Penrose tiling (type P3) as generated by a L-system, at depth %i\n" % depth)
|
|
fd.write("TYPE : TSP\n")
|
|
fd.write("DIMENSION : %i\n" % nb )
|
|
if edge_weight_section:
|
|
fd.write("EDGE_WEIGHT_TYPE : EXPLICIT\n")
|
|
fd.write("EDGE_WEIGHT_FORMAT : FULL_MATRIX\n")
|
|
if edge_data_section:
|
|
fd.write("EDGE_DATA_FORMAT : ADJ_LIST\n") # via the weight matrix?
|
|
if node_coord_section:
|
|
fd.write("NODE_COORD_TYPE : TWOD_COORDS\n") # do not work with concord
|
|
if display_data_section:
|
|
fd.write("DISPLAY_DATA_TYPE : TWOD_DISPLAY\n")
|
|
|
|
if node_coord_section:
|
|
fd.write("NODE_COORD_SECTION\n")
|
|
fmt = "%"+str(len(str(nb)))+"i %"+str(rounding)+"f %"+str(rounding)+"f\n"
|
|
for x,y in nodes:
|
|
fd.write(fmt % (nodes[(x,y)],x,y))
|
|
|
|
if edge_data_section:
|
|
fd.write("EDGE_DATA_SECTION\n")
|
|
for segment in segments:
|
|
start,end = segment
|
|
fd.write( str(nodes[start])+" "+str(nodes[end])+"\n" )
|
|
|
|
if edge_weight_section:
|
|
fd.write("EDGE_WEIGHT_SECTION\n")
|
|
# fill the weights matrix with size where necessary
|
|
weights = scipy.zeros((nb,nb), type(size))
|
|
for segment in segments:
|
|
start,end = segment
|
|
weights[nodes[start],nodes[end]] = size
|
|
weights[nodes[end],nodes[start]] = size
|
|
#fd.write(nodes[start],nodes[end]
|
|
|
|
fmt = "%"+str(len(str(size)))+"i "
|
|
for i in xrange(weights.shape[0]):
|
|
# full matrix
|
|
for j in xrange(weights.shape[1]):
|
|
fd.write(fmt % weights[i,j])
|
|
fd.write('\n')
|
|
|
|
if display_data_section:
|
|
fd.write("DISPLAY_DATA_SECTION\n")
|
|
fmt = "%"+str(len(str(nb)))+"i %"+str(rounding)+"f %"+str(rounding)+"f\n"
|
|
for x,y in nodes:
|
|
fd.write(fmt % (nodes[(x,y)],x,y))
|
|
|
|
fd.write("EOF\n")
|
|
|
|
|
|
def read_tour_index( fd ):
|
|
tour = []
|
|
nb = int(fd.readline().strip())
|
|
for line in fd:
|
|
tour += line.split()
|
|
|
|
return map(int, tour)
|
|
|
|
|
|
def read_nodes( fd ):
|
|
"""Parse a .tsp file and returns a dictionary of nodes, of the form {id:(x,y)}"""
|
|
nodes = {}
|
|
data_section = False
|
|
for line in fd:
|
|
if line.strip() == "DISPLAY_DATA_SECTION":
|
|
data_section = True
|
|
continue
|
|
|
|
data = line.strip().split()
|
|
if len(data) != 3 or ( len(data) > 1 and data[0].isalpha() ):
|
|
data_section = False
|
|
|
|
if data_section == True:
|
|
nodes[ int(data[0]) ] = ( float(data[1]),float(data[2]) )
|
|
|
|
return nodes
|
|
|
|
|
|
def read_vertices( fd ):
|
|
vertices = set()
|
|
|
|
data_section = False
|
|
i=-1
|
|
for line in fd:
|
|
if line.strip() == "EDGE_WEIGHT_SECTION":
|
|
data_section = True
|
|
i=0
|
|
continue
|
|
|
|
data = line.strip().split()
|
|
if len(data)==0 or ( len(data) >= 1 and data[0][0].isalpha() ):
|
|
data_section = False
|
|
|
|
if data_section == True:
|
|
for j in xrange(len(data)):
|
|
if float(data[j]) != 0 and (j,i) not in vertices:
|
|
vertices.add( (i,j) )
|
|
i += 1
|
|
|
|
return vertices
|
|
|
|
|
|
def plot_segments( segments ):
|
|
|
|
import matplotlib.pyplot as plot
|
|
from matplotlib.path import Path
|
|
import matplotlib.patches as patches
|
|
|
|
fig = plot.figure()
|
|
ax = fig.add_subplot(111)
|
|
|
|
for segment in segments:
|
|
start,end = segment
|
|
verts = [start,end,(0,0)]
|
|
codes = [Path.MOVETO,Path.LINETO,Path.STOP]
|
|
path = Path(verts, codes)
|
|
patch = patches.PathPatch(path, facecolor='none', lw=1)
|
|
ax.add_patch(patch)
|
|
|
|
ax.set_xlim(-50,50)
|
|
ax.set_ylim(-50,50)
|
|
|
|
plot.show()
|
|
|
|
|
|
def plot_segments_tour( segments_1, segments_2 ):
|
|
|
|
import matplotlib.pyplot as plot
|
|
from matplotlib.path import Path
|
|
import matplotlib.patches as patches
|
|
|
|
fig = plot.figure()
|
|
ax = fig.add_subplot(111)
|
|
|
|
for segment in segments_1:
|
|
start,end = segment
|
|
verts = [start,end,(0,0)]
|
|
codes = [Path.MOVETO,Path.LINETO,Path.STOP]
|
|
path = Path(verts, codes)
|
|
patch = patches.PathPatch(path, facecolor='0.5', lw=1)
|
|
ax.add_patch(patch)
|
|
|
|
for segment in segments_2:
|
|
start,end = segment
|
|
verts = [start,end,(0,0)]
|
|
codes = [Path.MOVETO,Path.LINETO,Path.STOP]
|
|
path = Path(verts, codes)
|
|
patch = patches.PathPatch(path, facecolor='1.0', lw=3)
|
|
ax.add_patch(patch)
|
|
|
|
|
|
ax.set_xlim(-50,50)
|
|
ax.set_ylim(-50,50)
|
|
|
|
plot.show()
|
|
|
|
|
|
|
|
|
|
if __name__=="__main__":
|
|
import sys
|
|
|
|
# segments = [
|
|
# ( (0,0),(0,2) ),
|
|
# ( (0,2),(2,2) ),
|
|
# ( (2,2),(2,0) ),
|
|
# ( (2,0),(0,0) )
|
|
# ]
|
|
#
|
|
# filename = "test.tsp"
|
|
# with open(filename,"w") as fd:
|
|
# write_segments( segments, fd=fd, size=1, depth=0, rounding=10 )
|
|
# write_segments( segments, fd=sys.stdout, size=1, depth=0, rounding=10 )
|
|
#
|
|
# with open(filename,"r") as fd:
|
|
# nodes = read_nodes( fd )
|
|
#
|
|
# print "Nodes: id (x, y)"
|
|
# for idx,node in nodes.items():
|
|
# print idx,node
|
|
#
|
|
# with open(filename,"r") as fd:
|
|
# vertices = read_vertices( fd )
|
|
#
|
|
# print "Segments: (x1,y1) (x2,y2)"
|
|
# segments = []
|
|
# for i1,i2 in vertices:
|
|
# print nodes[i1],nodes[i2]
|
|
# segments.append( (nodes[i1],nodes[i2]) )
|
|
#
|
|
# plot_segments( segments )
|
|
|
|
finstance = sys.argv[1]
|
|
ftour = sys.argv[2]
|
|
|
|
print "Read nodes"
|
|
with open(finstance,"r") as fd:
|
|
nodes = read_nodes( fd )
|
|
|
|
print "Read vertices"
|
|
with open(finstance,"r") as fd:
|
|
vertices = read_vertices( fd )
|
|
|
|
print "Build segments"
|
|
segments = []
|
|
for i1,i2 in vertices:
|
|
#print nodes[i1],nodes[i2]
|
|
segments.append( (nodes[i1],nodes[i2]) )
|
|
|
|
# print "Plot segments"
|
|
# plot_segments( segments )
|
|
|
|
|
|
print "Read tour"
|
|
with open(ftour,"r") as fd:
|
|
tour = read_tour_index( fd )
|
|
|
|
print "Build tour segments"
|
|
tour_segments = []
|
|
for i in xrange(0,len(tour)-1):
|
|
tour_segments.append( ( nodes[tour[i]],nodes[tour[i+1]] ) )
|
|
print tour_segments[-1]
|
|
|
|
tour_segments.append( ( nodes[tour[i+1]], nodes[tour[0]] ) )
|
|
print tour_segments[-1]
|
|
|
|
print "Plot tour segments"
|
|
plot_segments_tour( segments, tour_segments )
|
|
|