def solution_from_path(fname, solver=None, verbose=False): """ Load a problem and solve it """ if verbose: solver = solver or TSPSolver.from_tspfile(fname) return solver.solve() else: with suppress.HiddenPrints(): solver = solver or TSPSolver.from_tspfile(fname) return solver.solve()
def computeTsp(n_trees, points): generateFile("trees.tsp", n_trees, points) solver = TSPSolver.from_tspfile( "/Users/Alessandro/Documents/Pyworkspace/trees.tsp") solution = solver.solve() sol = solution.tour fo = computeFo(sol, points) return fo, sol
def _tsp_solver_factory(edge_weights: List, dimension: int, edge_weight_format: str): with tempfile.NamedTemporaryFile() as file: tsplib95.models.StandardProblem( type="TSP", dimension=dimension, edge_weight_type=_EDGE_WEIGHT_TYPE, edge_weight_format=edge_weight_format, edge_weights=edge_weights, ).save(file.name) return TSPSolver.from_tspfile(file.name)
def solve_batch_graphs(batch, first_cities, tmp_name='tmpname'): def create_concorde_file_xy_coord(arr, name="route", template=''): n_cities = arr.shape[0] assert len(arr.shape) == 2 # space delimited string matrix_s = "" for i, row in enumerate(arr.tolist()): # print(row) matrix_s += "".join("{} {} {}".format(i, row[0], row[1])) # print(matrix_s) # print('-------------') matrix_s += "\n" # print(template.format(**{'name': name, # 'n_cities': n_cities, # 'matrix_s': matrix_s})) return template.format(**{'name': name, 'n_cities': n_cities, 'matrix_s': matrix_s}) def write_file(outf, x, template): with open(outf, 'w') as dest: dest.write(create_concorde_file_xy_coord(x, name="My Route", template=template)) # 100*x.squeeze(0) return Trajectory = C.namedtuple('Trajectory', 'costs actions') actions = torch.zeros((batch.size(0), batch.size(1))) costs = [] M = 100000000 for i, x in enumerate(batch.cpu().numpy()): template = "NAME: {name}\nTYPE: TSP\nCOMMENT: {name}\nDIMENSION: {n_cities}\nEDGE_WEIGHT_TYPE: EUC_2D\nNODE_COORD_SECTION\n{matrix_s}EOF" x = M * x x = x.astype(int) outf = "/tmp/{}.tsp".format(tmp_name) write_file(outf, x, template) solver = TSPSolver.from_tspfile(outf) solution = solver.solve() #print(list(solution.tour)) if first_cities[i] not in list(solution.tour): print('----') print(first_cities[i]) print(list(solution.tour)) actions[i] = torch.from_numpy( np.roll(solution.tour, solution.tour.shape[0] - list(solution.tour).index(first_cities[i]))) costs.append(solution.optimal_value / M) return (Trajectory(costs=costs, actions=actions))
def solve(Ma, Mw): write_graph(Ma, Mw, [], 'tmp', int_weights=True) redirector_stdout = Redirector(fd=STDOUT) redirector_stderr = Redirector(fd=STDERR) redirector_stderr.start() redirector_stdout.start() solver = TSPSolver.from_tspfile('tmp') solution = solver.solve(verbose=False) redirector_stderr.stop() redirector_stdout.stop() return solution.tour if solution.found_tour else []
def run(filename, is_plot=True): datapath = get_example_path() filepath = os.path.join(datapath, filename) problem = tsplib95.load(filepath) start = time() solver = TSPSolver.from_tspfile(filepath) solution = solver.solve() end = time() print("Time spent to solve {}s".format(end - start)) print("Optimal value: ", solution.optimal_value) tour = solution.tour tour = [t + 1 for t in tour] plot(problem, tour)
def test_solve(self): # Given fname = get_dataset_path('berlin52') expected_tour, expected_opt_value = get_solution_data('berlin52') datagroup = TSPSolver.from_tspfile(fname) # When tour, val, success, foundtour, hit_timebound = datagroup.solve() # Then nptest.assert_array_equal(tour, expected_tour) self.assertAlmostEqual(val, expected_opt_value) self.assertTrue(success) self.assertTrue(foundtour) self.assertFalse(hit_timebound)
def computeTsp(filename): solver = TSPSolver.from_tspfile(getCurrWDir() + "/inputs/" + filename) start_time = time.time() solution = solver.solve() eval_time = time.time() - start_time print(colored("--- %s seconds ---" % eval_time)) print(colored("Outcome TSP:", "red")) print(solution.found_tour) print(colored("With optimal value [m]:", "red")) print(solution.optimal_value / 100) return solution, eval_time
def solve(Ma, Mw): """ Invokes Concorde to solve a TSP instance Uses Python's Redirector library to prevent Concorde from printing unsufferably verbose messages """ STDOUT = 1 STDERR = 2 redirector_stdout = Redirector(fd=STDOUT) redirector_stderr = Redirector(fd=STDERR) # Write graph on a temporary file write_graph(Ma, Mw, filepath='tmp', int_weights=True) redirector_stderr.start() redirector_stdout.start() # Solve TSP on graph solver = TSPSolver.from_tspfile('tmp') # Get solution solution = solver.solve(verbose=False) redirector_stderr.stop() redirector_stdout.stop() """ Concorde solves only symmetric TSP instances. To circumvent this, we fill inexistent edges with large weights. Concretely, an inexistent edge is assigned with the strictest upper limit to the cost of an optimal tour, which is n (the number of nodes) times 1 (the maximum weight). If one of these edges is used in the optimal solution, we can deduce that no valid tour exists (as just one of these edges costs more than all the others combined). OBS. in this case the maximum weight 1 is multiplied by 'bins' because we are converting from floating point to integers """ if any([ Ma[i, j] == 0 for (i, j) in zip(list(solution.tour), list(solution.tour)[1:] + list(solution.tour)[:1]) ]): return None else: return list(solution.tour)
def pyconcorde(self): # Edge case: check for no stitches if len(self.multi_node_graph) == 0: return 0 # Create tsp file filename = 'embroidery.tsp' file_write = open(filename, 'w') file_write.write('NAME: Embroidery Reduction\n') file_write.write('TYPE: TSP\n') file_write.write( 'COMMENT: Concorde on a reduction from the embroidery problem\n') file_write.write('DIMENSION: ' + str(len(self.multi_node_graph)) + '\n') file_write.write('EDGE_WEIGHT_TYPE: EXPLICIT\n') file_write.write('EDGE_WEIGHT_FORMAT: FULL_MATRIX\n') file_write.write('EDGE_WEIGHT_SECTION\n') # Go through each row of the matrix, round up value, write to file for row in self.multi_node_graph: to_add = '' for val in row: to_add += str(math.ceil(val)) + ' ' file_write.write(to_add + '\n') file_write.write('EOF') file_write.close() # Solve instances solver = TSPSolver.from_tspfile(filename) solution = solver.solve() # Calculate excess distance -- every duplicate node needs distance excess = 0 for v in self.pattern: excess += 2 * len(self.pattern[v]) return solution.optimal_value - excess
print('testing') sys.stdout.flush() idx = 0 inst_idx = 1 for g, fname in tqdm(TestSet(), 'Solving instance no. {}'.format(inst_idx)): inst_idx += 1 testset_name = TESTSET if TESTSET != 'tsp2d' else "tsp2d_" + opt[ 'g_type'] inst_name = fname if TESTSET != 'tsp2d' else "inst_" + str(idx) inst_key = os.path.basename(inst_name)[:-4] if eval_concorde and inst_key not in all_results[ 'concorde'].keys(): # Concorde: # fname = get_dataset_path("berlin52") solver = TSPSolver.from_tspfile(fname) t3 = time.time() solution = solver.solve(verbose=False) t4 = time.time() # print 'Concorde sol val:' , solution.optimal_value # 1000000.0 is a normalization factor of s2v in TestSet above. # concorde_sol.append(solution.optimal_value / 1000000.0) # concorde_time.append(t4-t3) all_results['concorde'][inst_key] = { 'len': solution.optimal_value / 1000000.0, 'time': t4 - t3 } if inst_key not in all_results[model_name].keys(): api.InsertGraph(g, is_test=True) t1 = time.time() val, sol = api.GetSol(idx, nx.number_of_nodes(g))
def solution_from_path(fname, solver=None, verbose=False): """ Load a problem and solve it """ solver = solver or TSPSolver.from_tspfile(fname) return solver.solve(verbose=verbose)