You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

119 lines
3.6 KiB

#!/usr/bin/sage
from sage.plot.colors import red, white, blue
import sys
FIGURE_SIZE = 10
POINT_SIZE = FIGURE_SIZE
def turn_direction(a,b,c):
x1,x2,x3=a[0],b[0],c[0]
y1,y2,y3=a[1],b[1],c[1]
return (x2-x1)*(y3-y1)-(y2-y1)*(x3-x1)
def angle_distance(dx,dy):
dx,dy = n(dx), n(dy)
length = sqrt(dx*dx+dy*dy)
return (dx / length, -length)
def chull_2d(points):
"""Computes the convex hull of a set of 2-dimensional points."""
points = copy(points)
# Find the point with lower y-coordinate
pivot = min(points, key=(lambda x: (x[1],x[0])))
points.remove(pivot)
# Sorts all the points according to the angle
points.sort(key=(lambda p : angle_distance(p[0]-pivot[0],p[1]-pivot[1])), reverse=True)
# Add the two first points to the stack
stack = [pivot,points[0]]
k = 1
while k < len(points):
p0 = stack[len(stack)-2]
p1 = stack[len(stack)-1]
p2 = points[k]
t = turn_direction(p0,p1,p2)
# Left turn or straight
if(t <= 0):
stack.pop()
# Right turn or straight
if(t >= 0):
stack.append(p2)
k = k+1
return stack
def read_problem_file(problem_file):
(node_count, cluster_count, edges_count) = [ int(x) for x in problem_file.readline().split(' ') ]
points = []
all_points = []
for i in range(cluster_count):
points.append([])
for i in range(node_count):
(x,y,cluster) = [ int(float(x)) for x in problem_file.readline().split(' ') ]
points[cluster].append((x,y))
all_points.append(vector([x,y]))
return node_count, cluster_count, edges_count, points, all_points
def read_solution_file(solution_file):
edges_count = int(solution_file.readline())
edges = []
for i in range(edges_count):
(start,end,weight) = solution_file.readline().split(' ')
start = int(start)
end = int(end)
weight = float(weight)
edges.append([start,end,weight])
return edges_count, edges
if(len(sys.argv) < 4):
print 'Usage: %s PROBLEM SOLUTION OUTPUT' % sys.argv[0]
print 'Draw the nodes and clusters from file PROBLEM and the tour described by SOLUTION to OUTPUT.'
print 'SOLUTION may be fractional. Acceptable OUTPUT file formats include PDF, EPS, SVG and PNG.'
else:
problem_file = open(sys.argv[1], "r")
solution_file = open(sys.argv[2], "r")
(node_count, cluster_count, edges_count, points, all_points) = read_problem_file(problem_file)
(edges_count, edges) = read_solution_file(solution_file)
plot = list_plot([])
max_x = max([p[0] for p in all_points])
text_offset = vector([0,-1]) * max_x * 0.02
print ('Drawing tour...')
for k in range(edges_count):
if edges[k][2] > 0.99:
c = blue
else:
c = white.blend(red, 0.1 + 0.9 * edges[k][2])
plot = plot + line([all_points[edges[k][0]], all_points[edges[k][1]]], color=c)
#print ('Drawing labels...')
#for i in range(node_count):
# plot = plot + text(str(i), all_points[i] + text_offset, color='gray')
print ('Drawing clusters...')
for i in range(cluster_count):
plot = plot + list_plot(points[i], color='gray', figsize=FIGURE_SIZE,
pointsize=POINT_SIZE)
if(len(points[i]) > 1):
vertices = chull_2d(list(set(points[i])))
plot = plot + sum([line([vertices[k],vertices[(k+1)%len(vertices)]],
thickness=POINT_SIZE/20, color='gray') for k in range(len(vertices))])
print("Writing file %s..." % sys.argv[3])
save(plot, sys.argv[3])