import sys import scipy def segments_to_nodes( segments ): """construct a {coords:id} dictionary and returns (nodes,nb)""" nodes = {} nb = 0 for segment in segments: for coords in segment: if not nodes.has_key(coords): nodes[coords] = nb nb += 1 return nodes,nb def write_nodes_simple( nodes, fd = sys.stdout ): """write only the coordinates""" fd.write("%i\n" % len(nodes)) nodes_index = nodes.keys() nodes_index.sort() for i in nodes_index: x,y = nodes[i] fd.write( "%f %f\n" % (x,y)) 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 ): nodes,nb = segments_to_nodes(segments) 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" sorted_nodes = [0] * len(nodes) for x,y in nodes: sorted_nodes[nodes[(x,y)]] = (x,y) for i in xrange(len(sorted_nodes)): x,y = sorted_nodes[i] fd.write(fmt % (i,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_tour_EO( fd ): line = fd.readline() sol = line.split() tour = sol[2:] # 0=fitness, 1=size, 2+=tour 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, edgecolor='green', 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, edgecolor='blue', 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, edgecolor='red', lw=2) ax.add_patch(patch) ax.set_xlim(-50,50) ax.set_ylim(-50,50) plot.show() if __name__=="__main__": import sys finstance = sys.argv[1] ftour = sys.argv[2] print "Read nodes", sys.stdout.flush() with open(finstance,"r") as fd: nodes = read_nodes( fd ) print len(nodes) with open(finstance+".nodes","w") as fd: write_nodes_simple(nodes,fd) print "Read vertices", sys.stdout.flush() with open(finstance,"r") as fd: vertices = read_vertices( fd ) print len(vertices) print "Build segments", sys.stdout.flush() segments = [] for i1,i2 in vertices: #print nodes[i1],nodes[i2] segments.append( (nodes[i1],nodes[i2]) ) print len(segments) # print "Plot segments" # plot_segments( segments ) print "Read tour", sys.stdout.flush() with open(ftour,"r") as fd: #tour = read_tour_index( fd ) tour = read_tour_EO( fd ) print len(tour) #print tour print "Build tour segments", sys.stdout.flush() 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 len(tour_segments) print "Plot tour segments" plot_segments_tour( segments, tour_segments )