def cheapest_insertion(matrix): tours = [] matrix = __calculate_weighted_matrix(matrix) for i in range(len(matrix)): tours.append(__nearest_insertion_fixed_start(matrix, i)) cheapest_route = min(tours, key=lambda k: calc_route_length(k, matrix)) cheapest_route_costs = calc_route_length(cheapest_route, matrix) return cheapest_route, cheapest_route_costs
def nearest_neighbour(matrix): """Returns a NN route (a list of indices: the first one is the start start index of the route, the last one is the last vistited point in the route """ all_routes = [] # calculate the nearest neighbour for each start point for v in range(len(matrix)): all_routes.append(__nearest_neighbour_fixed_start(matrix, v)) # return the best route of all: return min(all_routes, key=lambda route: calc_route_length(route, matrix))
def draw_route(route, axis, label, data): tsp_x = [data['points'][i][0] for i in route] tsp_y = [data['points'][i][1] for i in route] # also close the route: tsp_x.append(tsp_x[0]) tsp_y.append(tsp_y[0]) route_length = calc_route_length(route, data['matrix']) if label != 'Optimal Solution': error = (route_length / data['opt_length']) - 1 error_str = ', Error = {:.2f}%'.format(error * 100) else: error_str = '' axis.plot(tsp_x, tsp_y, label=label) axis.set_title('{} (${}$={:.2f}{})'.format(label, 'Dist_{Total}', route_length, error_str))
def main(nodes, min_xy, max_xy): point_list = generate_points(nodes, min_xy, max_xy) matrix = calculate_distance_matrix(point_list) data = { 'nn_route': heur.nearest_neighbour(matrix), 'fcfs': heur.first_come_first_serve(matrix), 'ni_route': heur.nearest_insertion(matrix), 'ch_route': heur.cheapest_insertion(matrix), 'mst_route': heur.mst_heuristic(matrix), 'mult_route': heur.multi_fragment(matrix), 'opt_solution': opt.solve_optimal(matrix, point_list), 'matrix': matrix, 'points': point_list } data['opt_length'] = calc_route_length(data['opt_solution'], matrix) plot(data)
def __nearest_insertion_fixed_start(matrix, start_point): n = len(matrix) tour = [start_point] while len(tour) < n: all_nearest = [] # find nearest: for tour_point in tour: possible_neighbours = [(i, val) for i, val in enumerate(matrix[tour_point]) if i not in tour] nearest_to_point = min(possible_neighbours, key=lambda k: k[1]) all_nearest.append(nearest_to_point) next_point = min(all_nearest, key=lambda i: i[1]) # find best insert position: all_possible_tours = [] for pos in range(len(tour)): possible_tour = tour[:pos + 1] + [next_point[0]] + tour[pos + 1:] length = calc_route_length(possible_tour, matrix) all_possible_tours.append([possible_tour, length]) best_tour = min(all_possible_tours, key=lambda k: k[1]) tour = best_tour[0] return tour
def mst_heuristic_python(matrix): # get mst graph mst_graph = _kruskal(matrix) # create an eulerian graph by double all edges: graph = [] for edge in mst_graph: reversed_edge = { 'from': edge['to'], 'to': edge['from'], 'dist': edge['dist'] } graph.append(edge) graph.append(reversed_edge) # create tour path = __get_hierholzer_path(graph, 0) # remove doubled entries tours = [ __mst_tour_from_hierholzer(path, start_point) for start_point in range(len(path)) ] tours = [(calc_route_length(tour, matrix), tour) for tour in tours] return min(tours, key=lambda k: k[0])[1]
def nearest_insertion(matrix): tours = [] for i in range(len(matrix)): tours.append(__nearest_insertion_fixed_start(matrix, i)) return min(tours, key=lambda k: calc_route_length(k, matrix))