예제 #1
0
 def test_3_opt_2(self):
     route = [0, 3, 2, 1, 4, 5, 6, 7, 8]
     result = tsp_3_opt(self.graph2, route)
     new_route_cost = route_cost(self.graph2, result)
     old_route_cost = route_cost(self.graph2, route)
     print(new_route_cost)
     print(old_route_cost)
     assert new_route_cost < old_route_cost
예제 #2
0
def test_permutation_algorithm():
    graph = np.array([[0, 5, 2, 1, 1, 4], [5, 0, 6, 2, 2,
                                           5], [2, 6, 0, 7, 4, 2],
                      [1, 2, 7, 0, 8, 4], [1, 2, 4, 8, 0, 5],
                      [4, 5, 2, 4, 5, 0]])
    route = [0, 1, 2, 3, 4, 5]
    result = permutations_tsp(graph)
    print(result)
    assert route_cost(graph, route) > route_cost(graph, result)
예제 #3
0
def test_permutation_algorithm_2():
    graph = np.array([[0, 4, 3, 4, 5, 1, 2, 3, 4], [4, 0, 1, 4, 3, 4, 6, 2, 1],
                      [3, 1, 0, 1, 4, 3, 2, 1, 9], [4, 4, 1, 0, 4, 6, 1, 2, 3],
                      [5, 3, 4, 4, 0, 1, 2, 5, 3], [1, 4, 3, 6, 1, 0, 2, 5, 3],
                      [2, 6, 2, 1, 2, 2, 0, 3, 5], [3, 2, 1, 2, 5, 5, 3, 0, 9],
                      [4, 1, 9, 3, 3, 3, 5, 0, 0]])
    route = [0, 1, 2, 3, 4, 5, 6, 7, 8]
    result = permutations_tsp(graph)
    print(route_cost(graph, result))
    assert route_cost(graph, route) > route_cost(graph, result)
예제 #4
0
 def test_2_opt_algorithm(self):
     graph = np.array([[0, 5, 2, 1, 1, 4],
                       [5, 0, 6, 2, 2, 5],
                       [2, 6, 0, 7, 4, 2],
                       [1, 2, 7, 0, 8, 4],
                       [1, 2, 4, 8, 0, 5],
                       [4, 5, 2, 4, 5, 0]])
     route = [0, 1, 2, 3, 4, 5]
     result = tsp_2_opt(graph, route)
     new_route_cost = route_cost(graph, result)
     old_route_cost = route_cost(graph, route)
     print(new_route_cost)
     print(old_route_cost)
     print(result)
     assert old_route_cost > new_route_cost
예제 #5
0
def branch_and_bound_tsp_bfs(graph: ndarray):
    """ Branch and bound by BFS, lower bound is spanning tree"""
    number_of_nodes = len(graph)
    bnb_tree = Tree(number_of_nodes)

    # top level node
    top_lower_bound = 0
    for node in graph:
        top_lower_bound += np.sum(np.sort(node[node.nonzero()])[:2])

    # top node
    top_node = Node(top_lower_bound / 2, [0], graph)
    bnb_tree.add_leaf(top_node)

    while not bnb_tree.optimized():
        most_promising_leaf = bnb_tree.get_leaf_with_lowest_bound()
        bnb_tree.remove_leaf_from_list(most_promising_leaf)

        unvisited_nodes = list(bnb_tree.node_indexes -
                               set(most_promising_leaf.visited_nodes))
        for vertex in unvisited_nodes:
            lower_bound = calculate_two_neighbor_bound(graph,
                                                       most_promising_leaf,
                                                       vertex)
            new_leaf = Node(lower_bound,
                            most_promising_leaf.visited_nodes + [vertex],
                            most_promising_leaf)
            bnb_tree.add_leaf(new_leaf)

            if len(new_leaf.visited_nodes) is number_of_nodes:
                new_leaf.visited_nodes.append(0)
                bnb_tree.set_solution(route_cost(graph,
                                                 new_leaf.visited_nodes))
                print(*new_leaf.visited_nodes, sep=", ")
                print('Solution found %s' %
                      (str(route_cost(graph, new_leaf.visited_nodes))))
                bnb_tree.remove_leaf_from_list(new_leaf)

    print('Best solution found: %s' % str(bnb_tree.best_solution_value))
예제 #6
0
def simulated_annealing(graph,
                        path=None,
                        temperature=1,
                        n_of_iter=1000,
                        alpha=0.95):
    if path is None:
        path = christofides_tsp(graph)

    changed = True

    while changed:
        temp_solution = [node for node in path]
        for iter in range(n_of_iter):
            new_solution = _get_next_solution(path)

            new_route_cost = route_cost(graph, new_solution)
            current_route_cost = route_cost(graph, path)
            if new_route_cost < current_route_cost:
                path = new_solution
            else:
                if np.exp(
                    (current_route_cost - new_route_cost) /
                    (temperature * Constants.BOLTZMANN)) > random.random():
                    path = new_solution

        temperature = _decrease_temperature(temperature, alpha)

        if temp_solution == path:
            changed = False

    # just to start with the same node -> we will need to cycle the results.
    cycled = cycle(path)
    skipped = dropwhile(lambda x: x != 0, cycled)
    sliced = islice(skipped, None, len(path))
    path = list(sliced)

    return path
예제 #7
0
def tsp_2_opt(graph, route):
    """
    Approximate the optimal path of travelling salesman according to 2-opt algorithm
    Args:
        graph: 2d numpy array as graph
        route: list of nodes

    Returns:
        optimal path according to 2-opt algorithm

    Examples:
        >>> import numpy as np
        >>> graph = np.array([[  0, 300, 250, 190, 230],
        >>>                   [300,   0, 230, 330, 150],
        >>>                   [250, 230,   0, 240, 120],
        >>>                   [190, 330, 240,   0, 220],
        >>>                   [230, 150, 120, 220,   0]])
        >>> tsp_2_opt(graph)
    """
    improved = True
    best_found_route = route
    best_found_route_cost = route_cost(graph, best_found_route)
    while improved:
        improved = False
        for i in range(1, len(best_found_route) - 1):
            for k in range(i + 1, len(best_found_route) - 1):
                new_route = _swap_2opt(best_found_route, i, k)
                new_route_cost = route_cost(graph, new_route)
                if new_route_cost < best_found_route_cost:
                    best_found_route_cost = new_route_cost
                    best_found_route = new_route
                    improved = True
                    break
            if improved:
                break
    return best_found_route
예제 #8
0
def permutations_tsp(graph):
    """
    Creates all permutations from the added graph check all the combinations and the route costs and then
    returns the best solution. BEWARE: this method is computationally expensive, therefore it shouldn't be run on over 12 nodes
    Args:
        graph: graph

    Returns:
        list of nodes []
    """
    route = range(0, len(graph))
    # generate all permutations
    all_routes = [list(i) for i in permutations(route)]
    # calculate all costs
    cost_all_routes = [route_cost(graph, i) for i in all_routes]
    # find the lowest cost
    best_route = all_routes[cost_all_routes.index(min(cost_all_routes))]
    return best_route