def sa_algorithm(nodes): # Create an initial solution that we can improve upon. number_of_nodes = len(nodes) solution = [n for n in nodes] # The temperature t. This is the most important parameter of the SA # algorithm. It starts at a high temperature and is then slowly decreased. # Both rate of decrease and initial values are parameters that need to be # tuned to get a good solution. # The initial temperature. This should be high enough to allow the # algorithm to explore many sections of the search space. Set too high it # will waste a lot of computation time randomly bouncing around the search # space. t = 100 # Length of the best solution so far. l_min = total_length(nodes, solution) best_solution = [] i = 0 while t > 0.1: i = i + 1 # Given a solution we create a new solution solution = sa_optimize_step(nodes, solution, number_of_nodes, t) # every ~200 steps if i >= 200: i = 0 # Compute the length of the solution l = total_length(nodes, solution) #print " ", l, t, nn # Lower the temperature. # The slower we do this, the better then final solution # but also the more times it takes. t = t * 0.9995 # See if current solution is a better solution then the previous # best one. if l_min is None: # TODO: This can be removed, as l_min is set above. l_min = l elif l < l_min: # Yup it is, remember it. l_min = l #print "++", l, t best_solution = solution[:] else: pass return best_solution
def read_problem(problem_file_name): global xmax, ymax, xmin, ymin nodes = [] with open(problem_file_name) as inpf: first_line = inpf.readline() node_count = int(first_line) i = 0 for line in inpf: parts = line.split() x = float(parts[0]) y = float(parts[1]) if x > xmax: xmax = x if y > ymax: ymax = y if x < xmin: xmin = x if y < ymin: ymin = y nodes.append(Node(i, x, y)) i = i + 1 optfile = problem_file_name + ".opt" if osp.exists(optfile): with open(optfile) as f: opttour = np.fromfile(f, dtype=int, sep='\n') - 1 print opttour, len(opttour) s = np.array(nodes)[opttour] if anim: frame0(s, nodes, total_length(nodes, s), "opt") return nodes
def sa_algorithm(nodes, number_of_nodes): # Create an initial solution that we can improve upon. solution = [n for n in nodes] # The temperature t. This is the most important parameter of the SA # algorithm. It starts at a high temperature and is then slowly decreased. # Both rate of decrease and initial values are parameters that need to be # tuned to get a good solution. # The initial temperature. This should be high enough to allow the # algorithm to explore many sections of the search space. Set too high it # will waste a lot of computation time randomly bouncing around the search # space. t = 100 # Length of the best solution so far. l_min = total_length( nodes, solution ) best_solution = [] i = 0 while t > 0.1: i = i + 1 # Given a solution we create a new solution solution = sa_optimize_step(nodes, solution, number_of_nodes, t) # every ~200 steps if i >= 200: i = 0 # Compute the length of the solution l = total_length( nodes, solution ) print " ", l, t, nn # Lower the temperature. # The slower we do this, the better then final solution # but also the more times it takes. t = t*0.9995 # See if current solution is a better solution then the previous # best one. if l_min is None: # TODO: This can be removed, as l_min is set above. l_min = l elif l < l_min: # Yup it is, remember it. l_min = l print "++", l, t best_solution = solution[:] else: pass return best_solution
def solve(problem_file_name): # This it to make sure we get the same answer each time. random.seed(8111142) solution_string = None nodes = read_problem(problem_file_name) solution = create_animation(nodes) objective = total_length(nodes, solution) solution_string = str(objective) + ' 0\n' solution_string += ' '.join(map(lambda x: str(x.id), solution)) return solution_string
def solve( input_data ): # This it to make sure we get the same anwser each time. random.seed(8111142) lines = input_data.split('\n') node_count = int(lines[0]) nodes = [] for i in range(1, node_count+1): line = lines[i] parts = line.split() nodes.append( Node( i-1, float(parts[0]), float(parts[1]) ) ) solution = create_animation( nodes ) objective = total_length( nodes, solution ) solution_string = str( objective ) + ' 0\n' solution_string += ' '.join( map( lambda x: str(x.id), solution ) ) return solution_string
def frame(nodes, solution, sn, t, c, y, x, z, gain): global pic global nn cities = [(n.x, n.y) for n in solution] cities = np.array(cities) cities2 = [(c.x, c.y), (y.x, y.y)] cities3 = [(x.x, x.y), (z.x, z.y)] cities2 = np.array(cities2) cities3 = np.array(cities3) plt.plot(cities[:, 0], cities[:, 1], 'bo-') #plt.scatter(cities[:,0], cities[:,1],s=50,c='k') if gain < 0: plt.scatter(cities2[:, 0], cities2[:, 1], c='r', s=180) plt.plot(cities2[:, 0], cities2[:, 1], c='r', linewidth=2) plt.scatter(cities3[:, 0], cities3[:, 1], c='b', s=150) plt.plot(cities3[:, 0], cities3[:, 1], c='r', linewidth=2) else: plt.scatter(cities2[:, 0], cities2[:, 1], c='g', s=180) plt.plot(cities2[:, 0], cities2[:, 1], c='g', linewidth=2) plt.scatter(cities3[:, 0], cities3[:, 1], c='b', s=150) plt.plot(cities3[:, 0], cities3[:, 1], c='g', linewidth=2) plt.axis([xmin - indent, xmax + indent, ymin - indent, ymax + indent]) plt.axis('off') l_min = total_length(nodes, solution) plt.title('(4) SA Temp {} Best Tour {}\nSwaps {} Gain {} '.format( t, l_min, nn, gain)) plt.savefig(("%05d" % pic) + '.png') plt.clf() pic += 1 print pic
def frame4(nodes, solution, sn, c, y, x, z, gain): global pic global nn l_min = total_length( nodes, solution ) cities = [ (n.x,n.y) for n in solution ] cities = numpy.array( cities ) cities2 = [ (c.x,c.y), (y.x,y.y) ] cities3 = [ (x.x,x.y), (z.x,z.y) ] cities2 = numpy.array( cities2 ) cities3 = numpy.array( cities3 ) plt.plot(cities[:,0],cities[:,1],'bo-') #plt.scatter(cities[:,0], cities[:,1],s=50,c='k') if gain < 0: plt.scatter(cities2[:,0], cities2[:,1],c='r',s=180) plt.plot(cities2[:,0],cities2[:,1],c='r',linewidth=2) plt.scatter(cities3[:,0], cities3[:,1],c='b',s=150) plt.plot(cities3[:,0],cities3[:,1],c='r',linewidth=2) else: plt.scatter(cities2[:,0], cities2[:,1],c='g',s=180) plt.plot(cities2[:,0],cities2[:,1],c='g',linewidth=2) plt.scatter(cities3[:,0], cities3[:,1],c='b',s=150) plt.plot(cities3[:,0],cities3[:,1],c='g',linewidth=2) plt.axis( [-100,4100,-100,2100] ) plt.axis('off') plt.title('(3) 2-Opt Tour {:6.1f}'.format(l_min)) plt.savefig( ("%05d" % pic)+'.png') plt.clf() pic += 1 print(pic)
def frame4( nodes, solution, sn, t, c,y,x,z, gain ): global pic global nn l_min = total_length( nodes, solution ) cities = [ (n.x,n.y) for n in solution ] cities = numpy.array( cities ) cities2 = [ (c.x,c.y), (y.x,y.y) ] cities3 = [ (x.x,x.y), (z.x,z.y) ] cities2 = numpy.array( cities2 ) cities3 = numpy.array( cities3 ) plt.plot(cities[:,0],cities[:,1],'bo-') #plt.scatter(cities[:,0], cities[:,1],s=50,c='k') if gain < 0: plt.scatter(cities2[:,0], cities2[:,1],c='r',s=180) plt.plot(cities2[:,0],cities2[:,1],c='r',linewidth=2) plt.scatter(cities3[:,0], cities3[:,1],c='b',s=150) plt.plot(cities3[:,0],cities3[:,1],c='r',linewidth=2) else: plt.scatter(cities2[:,0], cities2[:,1],c='g',s=180) plt.plot(cities2[:,0],cities2[:,1],c='g',linewidth=2) plt.scatter(cities3[:,0], cities3[:,1],c='b',s=150) plt.plot(cities3[:,0],cities3[:,1],c='g',linewidth=2) plt.axis( [-100,4100,-100,2100] ) plt.axis('off') plt.title('(3) 2-Opt Tour {:6.1f}'.format(l_min)) plt.savefig( ("%05d" % pic)+'.png') plt.clf() pic += 1 print pic
def create_animation(nodes): global nn global l_min number_of_nodes = len( nodes ) print('Size {}'.format( number_of_nodes )) if do_greedy: # Greedy Algorithm print('Computing greedy path') solution = greedy_algorithm(nodes) else: # For debugging solution = [n for n in nodes] if do_intro: # Only cities solution0 = [n for n in nodes] for i in range(2, number_of_nodes): s = solution0[0:i] framec(s, number_of_nodes) # Show all cities for an additional 20 frames. for i in range(20): framec(s, number_of_nodes) # Animate the Random Search for i in range(2, number_of_nodes): s = solution0[0:i] frame0(s, nodes, total_length(nodes, s), "(1) Random Path") s = solution0 for i in range(60): frame0(s, nodes, total_length(nodes, s), "(1) Random Path") # Animate the Greedy Search for i in range(2, number_of_nodes): s = solution[0:i] frame0(s, nodes, total_length(nodes, s), "(2) Greedy Search") s = solution for i in range(60): frame0(s, nodes, total_length(nodes, s), "(2) Greedy Search") # Under construction if do_perry: solution = miss_perry_s_compass(nodes, number_of_nodes) for i in range(2, number_of_nodes): s = solution[0:i] frame0(s, nodes, total_length(nodes, s), "(1) Random Path") for i in range(60): frame0(solution, nodes, total_length(nodes, s), "(3) Miss Perry") if do_2opt: print("2-Opt") # Run 2-Opt algorithm and create animation frames for each step s = two_opt_algorithm(nodes, number_of_nodes) # Show the best solution for an additional 60 frames. for i in range(60): frame0(s, nodes, total_length(nodes, s), "(4) 2-Opt") if do_sa: #=== Simulated Annealing print("SA") # Run SA algorithm and create animation frames for each step s = sa_algorithm(nodes, number_of_nodes) # Show the best solution for an additional 60 frames. for i in range(60): frame0(s, nodes, total_length(nodes, s), "(5) SA") return s
def create_animation( nodes ): global nn global l_min sn = len( nodes ) print 'Size {}'.format( sn ) if True: # Greedy Algorithm print 'Computing greedy path' free_nodes = nodes[:] solution = [] n = free_nodes[0] free_nodes.remove(n) solution.append( n ) while len( free_nodes ) > 0: print len( free_nodes ), min_l = None min_n = None for c in free_nodes: l = length( c, n ) if min_l is None: min_l = l min_n = c elif l < min_l: min_l = l min_n = c solution.append(min_n) free_nodes.remove(min_n) n = min_n else: solution = [ n for n in nodes ] if True: # Only cities solution0 = [ n for n in nodes ] for i in range(2,sn): s = solution0[0:i] framec(s,sn) for i in range(20): framec(s,sn) # Random Search for i in range(2,sn): s = solution0[0:i] frame0(s,solution0, total_length(nodes,s), "(1) Random Path") s = solution0 for i in range(60): frame0(s,solution, total_length(nodes,s), "(1) Random Path") # Greedy for i in range(2,sn): s = solution[0:i] frame0(s,solution, total_length(nodes,s), "(2) Greedy Search") s = solution for i in range(60): frame0(s,solution, total_length(nodes,s), "(2) Greedy Search") print "2-Opt" solution = [ n for n in nodes ] t = 100 go = True while go: (go,solution) = optimize2opt( nodes, solution, sn, t ) s = solution for i in range(60): frame0(s,solution, total_length(nodes,s), "(3) 2-Opt") print "SA" solution = [ n for n in nodes ] t = 100 l_min = total_length( nodes, solution ) best_solution = [] i = 0 while True: i = i + 1 solution = optimize( nodes, solution, sn, t ) if i >= 200: i = 0 l = total_length( nodes, solution ) print " ", l, t, nn t = t*0.9995 if l_min is None: l_min = l elif l < l_min: l_min = l print "++", l, t best_solution = solution[:] else: pass if t < 0.1: break s = best_solution for i in range(60): frame0(s, solution, total_length(nodes,s), "(4) SA") return best_solution
def create_animation(nodes): global nn global l_min number_of_nodes = len( nodes ) print('Size {}'.format( number_of_nodes )) if do_greedy: # Greedy Algorithm print 'Computing greedy path' solution = greedy_algorithm(nodes) else: # For debugging solution = [n for n in nodes] if do_intro: # Only cities solution0 = [n for n in nodes] for i in range(2, number_of_nodes): s = solution0[0:i] framec(s, number_of_nodes) # Show all cities for an additional 20 frames. for i in range(20): framec(s, number_of_nodes) # Animate the Random Search for i in range(2, number_of_nodes): s = solution0[0:i] frame0(s, nodes, total_length(nodes, s), "(1) Random Path") s = solution0 for i in range(60): frame0(s, nodes, total_length(nodes, s), "(1) Random Path") # Animate the Greedy Search for i in range(2, number_of_nodes): s = solution[0:i] frame0(s, nodes, total_length(nodes, s), "(2) Greedy Search") s = solution for i in range(60): frame0(s, nodes, total_length(nodes, s), "(2) Greedy Search") # Under construction if do_perry: solution = miss_perry_s_compass(nodes, number_of_nodes) for i in range(2, number_of_nodes): s = solution[0:i] frame0(s, nodes, total_length(nodes, s), "(1) Random Path") for i in range(60): frame0(solution, nodes, total_length(nodes, s), "(3) Miss Perry") if do_2opt: print("2-Opt") # Run 2-Opt algorithm and create animation frames for each step s = two_opt_algorithm(nodes, number_of_nodes) # Show the best solution for an additional 60 frames. for i in range(60): frame0(s, nodes, total_length(nodes, s), "(4) 2-Opt") if do_sa: #=== Simulated Annealing print("SA") # Run SA algorithm and create animation frames for each step s = sa_algorithm(nodes, number_of_nodes) # Show the best solution for an additional 60 frames. for i in range(60): frame0(s, nodes, total_length(nodes, s), "(5) SA") return s
def create_animation(nodes): global nn global l_min sn = len(nodes) print 'Size {}'.format(sn) if True: # Greedy Algorithm print 'Computing greedy path' free_nodes = nodes[:] solution = [] n = free_nodes[0] free_nodes.remove(n) solution.append(n) while len(free_nodes) > 0: print len(free_nodes), min_l = None min_n = None for c in free_nodes: l = length(c, n) if min_l is None: min_l = l min_n = c elif l < min_l: min_l = l min_n = c solution.append(min_n) free_nodes.remove(min_n) n = min_n else: solution = [n for n in nodes] if True: # Only cities solution0 = [n for n in nodes] for i in range(2, sn): s = solution0[0:i] framec(s, sn) # Show all cities for an additional 20 frames. for i in range(20): framec(s, sn) # Random Search for i in range(2, sn): s = solution0[0:i] frame0(s, solution0, total_length(nodes, s), "(1) Random Path") s = solution0 for i in range(60): frame0(s, solution, total_length(nodes, s), "(1) Random Path") # Greedy for i in range(2, sn): s = solution[0:i] frame0(s, solution, total_length(nodes, s), "(2) Greedy Search") s = solution for i in range(60): frame0(s, solution, total_length(nodes, s), "(2) Greedy Search") print "2-Opt" # Create an initial solution solution = [n for n in nodes] t = 100 go = True # Try to optimize the solution with 2opt until # no further optimization is possible. while go: (go, solution) = optimize2opt(nodes, solution, sn, t) s = solution for i in range(60): frame0(s, solution, total_length(nodes, s), "(3) 2-Opt") #=== Simulated Annealing print "SA" # Create an initial solution that we can improve upon. solution = [n for n in nodes] # The temperature t. This is the most important parameter # of the SA algorithm. It starts at a high temperature and # is then slowly decreased. Both rate of decrease and # initial values are parameters that need to be tuned to # get a good solution. # The initial temperature. # This should be high enough to allow the algorithm to # explore many sections of the search space. # Set too high it will waste a lot of computation time randomly # bouncing around the search space. t = 100 # Length of the best solution so far. l_min = total_length(nodes, solution) best_solution = [] i = 0 while True: i = i + 1 solution = optimize(nodes, solution, sn, t) # every ~200 steps if i >= 200: i = 0 # Compute the length of the solution l = total_length(nodes, solution) print " ", l, t, nn # Lower the temperature. # The slower we do this, the better then final solution # but also the more times it takes. t = t * 0.9995 # See if current solution is a better solution then the previous # best one. if l_min is None: # TODO: This can be removed, as l_min is set above. l_min = l elif l < l_min: # Yup it is, remember it. l_min = l print "++", l, t best_solution = solution[:] else: pass if t < 0.1: # TODO: This should be part of the while condition. break # Show the best solution for an additional 60 frames. s = best_solution for i in range(60): frame0(s, solution, total_length(nodes, s), "(4) SA") return best_solution