# -*- coding: utf-8 -*- ############################################################################### """ Tries to be as fast as possible in solving TSPs as possible using Gurobi and LKH as experimentally it was found out to be time-optimal.""" ############################################################################### from tsp_solvers.tsp_solver_ropt import solve_tsp_ropt from tsp_solvers.tsp_solver_lkh import solve_tsp_lkh from tsp_solvers.tsp_solver_gurobi import solve_tsp_gurobi def solve_tsp_fast(D, selected_idxs): if len(selected_idxs)<5: return solve_tsp_ropt(D, selected_idxs) elif len(selected_idxs)<20: return solve_tsp_gurobi(D, selected_idxs) else: return solve_tsp_lkh(D, selected_idxs, num_runs=1) if __name__=="__main__": from shared_cli import tsp_cli tsp_cli("fast", solve_tsp_fast)
skip = True elif "Length = " in l: obj_f = float(l.split()[-1]) elif not skip: vrp_nid = selected_idxs[int(l)-1] if vrp_nid==0: tail.append(0) depot_found = True if depot_found: sol.append(vrp_nid) else: tail.append(vrp_nid) if l == "TOUR_SECTION": skip = False sol+=tail if not depot_found: sol+=[sol[0]] remove_file(temp_problem_file_path) remove_file(temp_parameter_file_path) remove_file(temp_output_file_path) if are_float_distances: obj_f = obj_f/float_accuracy; return sol, obj_f if __name__=="__main__": from shared_cli import tsp_cli tsp_cli("lkh", solve_tsp_lkh)
m.setParam('TimeLimit', MAX_MIP_SOLVER_RUNTIME) m.setParam('Threads', MIP_SOLVER_THREADS) m.optimize(_subtourelim) # restore SIGINT callback handler which is changed by gurobipy signal(SIGINT, default_int_handler) status = m.Status if status == GRB.TIME_LIMIT: raise GurobiError( 10023, "Gurobi timeout reached when attempting to solve TSP") elif m.Status == GRB.INTERRUPTED: raise KeyboardInterrupt() solution = m.getAttr('x', edgevars) selected = [(i, j) for i in range(n) for j in range(n) if solution[i, j] > 0.5] cycles = _subtour(selected, n) assert len(cycles) == n # make the route always start from the 1st index sol = [selected_idxs[i] for i in cycles] + [selected_idxs[0]] obj_f = m.objVal return sol, obj_f if __name__ == "__main__": from shared_cli import tsp_cli tsp_cli("gurobi", solve_tsp_gurobi)
sol = None sol_f = None best_re = re.compile("try [0-9]+, Best ([0-9]+(\.?[0-9]*)?),") best_obj = None for l in stdout_data.split('\n'): if "best solution so far is" in l[:25]: tour_indices = [ int(n) for n in l.replace("best solution so far is", "").split() ] sol = list(selected_idxs[i] for i in tour_indices) first_pos = sol.index(selected_idxs[0]) sol = sol[first_pos:] + sol[:first_pos] + [selected_idxs[0]] sol_f = sum(D[sol[i - 1]][sol[i]] for i in range(1, len(sol))) #print("REMOVEME:", sol_f, best_obj) bo = best_re.search(l) if bo: best_obj = float(bo.group(1)) if are_float_distances: best_obj = best_obj / float_accuracy remove_file(temp_problem_file_path) return sol, sol_f if __name__ == "__main__": from shared_cli import tsp_cli tsp_cli("acotsp", solve_tsp_acotsp)
# 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 if __name__ == "__main__": from shared_cli import tsp_cli tsp_cli("ropt", solve_tsp_ropt)