Example #1
0
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()
Example #2
0
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
Example #3
0
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)
Example #4
0
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))
Example #5
0
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 []
Example #6
0
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)
Example #8
0
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
Example #9
0
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)
Example #10
0
    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
Example #11
0
 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)