def visualize_3opt_move_s1_r2_s3(D, pts, optimum): """ Test the 2nd 3-opt alternative (actually corresponding a 2-opt move), where the middle segment (segment2) is reversed.""" # modify the distance matrix to force a recombination move D = D.copy() _set_weight(D, 2, 3, 100) _set_weight(D, 8, 9, 100) _set_weight(D, 2, 8, 1) _set_weight(D, 3, 9, 1) initial_sol = optimum sol = do_3opt_move(initial_sol, D) _visualize_result("output/3opt_move2_s1_r2_s3.dot", sol, pts, D)
def visualize_3opt_move_s1_s2_r3(D, pts, optimum): """ Test the 1st 3-opt alternative (actually corresponding a 2-opt move), where the last segment (segment3) is reversed.""" # modify the distance matrix to force a recombination move D = D.copy() _set_weight(D, 8, 9, 100) _set_weight(D, 16, 17, 100) _set_weight(D, 8, 16, 1) _set_weight(D, 9, 17, 1) initial_sol = optimum sol = do_3opt_move(initial_sol, D) _visualize_result("output/3opt_move1_s1_s2_r3.dot", sol, pts, D)
def visualize_3opt_move_s1_r2_r3(D, pts, optimum): """ Test the 4th 3-opt alternative, where the middle AND last segments (segment2 and segment3) are both reversed but their order kept.""" # modify the distance matrix to force a recombination move D = D.copy() _set_weight(D, 2, 3, 100) _set_weight(D, 8, 9, 100) _set_weight(D, 16, 17, 100) _set_weight(D, 2, 8, 1) _set_weight(D, 3, 16, 1) _set_weight(D, 9, 17, 1) initial_sol = optimum sol = do_3opt_move(initial_sol, D) _visualize_result("output/3opt_move4_s1_r2_r3.dot", sol, pts, D)
def visualize_3opt_move_s1_r3_r2(D, pts, optimum): """ Test the 3rd 3-opt alternative (actually corresponding a 2-opt move), where the first segment (segment1) is reversed. However, in symmetric case this is equal to reversing the order and direction of the segments 2 and 3 and this is the expected move operation here.""" # modify the distance matrix to force a recombination move D = D.copy() _set_weight(D, 2, 3, 100) _set_weight(D, 16, 17, 100) _set_weight(D, 2, 16, 1) _set_weight(D, 3, 17, 1) initial_sol = optimum sol = do_3opt_move(initial_sol, D) _visualize_result("output/3opt_move3_s1_r3_r2.dot", sol, pts, D)
def visualize_3opt_move_s1_r3_s2(D, pts, optimum): """Test the 7th and final 3-opt alternative, where the middle AND last segments (segment2 and segment3) are swapped, and the segment3 is reversed.""" # modify the distance matrix to force a recombination move D = D.copy() _set_weight(D, 2, 3, 100) _set_weight(D, 8, 9, 100) _set_weight(D, 16, 17, 100) _set_weight(D, 2, 16, 1) _set_weight(D, 9, 3, 1) _set_weight(D, 8, 17, 1) initial_sol = optimum sol = do_3opt_move(initial_sol, D) _visualize_result("output/3opt_move7_s1_r3_s2.dot", sol, pts, D)
def visualize_3opt_move_s1_s3_s2(D, pts, optimum): """ Test the 5th 3-opt alternative, where the middle AND last segments (segment2 and segment3) are swapped, but their traverse direction kept.""" # modify the distance matrix to force a recombination move D = D.copy() _set_weight(D, 2, 3, 100) _set_weight(D, 8, 9, 100) _set_weight(D, 16, 17, 100) _set_weight(D, 2, 9, 1) _set_weight(D, 16, 3, 1) _set_weight(D, 8, 17, 1) initial_sol = optimum sol = do_3opt_move(initial_sol, D) _visualize_result("output/3opt_move5_s1_s3_s2.dot", sol, pts, D)
def solve_tsp_ropt(D, selected_idxs, do_shuffle=False, do2opt=True, do3opt=True): # r-Opt (r \in {2,3} ) endp = selected_idxs[0] if do_shuffle: shuffled_idxs = list(selected_idxs[1:]) shuffle(shuffled_idxs) new_route = [endp] + shuffled_idxs + [endp] elif selected_idxs[-1] != endp: new_route = selected_idxs + [endp] else: new_route = selected_idxs new_route_cost = objf(new_route, D) # make first 2-optimal if do2opt: improved = True while improved: improved = False improved_route, delta = do_2opt_move(new_route, D, 1) if improved_route is not None: new_route = improved_route new_route_cost += delta improved = True # then 3-optimal (do not waste time on "easy" 2-opt # operations if the route has already been made 2-optimal if do3opt: improved = True while improved: improved = False improved_route, delta = do_3opt_move(new_route, D, 1) if improved_route is not None: new_route = improved_route new_route_cost += delta improved = True return new_route, new_route_cost