def plan_tour(xys, budget, exact, fixed=[]): """ Calculates a tour over all given points. :param xys: list of points to visit :param budget: limit of points to visit + length limit :param exact: whether or not to run Gurobi :param fixed: segments of the trip already travelled (using this option avoids heuristic mode [multistart_localsearch]) :return: solution, feasibility, cost of the tour including probings, whether the tour is optimal """ n = len(xys) pos = xys c = {} for i in range(n): for j in range(n): # non optimized distance calculations! c[i, j] = dist(*pos[i], *pos[j]) c[j, i] = c[i, j] cost_is_optimal_or_timeout = False if n > 2: # heuristic if len(fixed) == 0: sol_, cost = multistart_localsearch(100, n, c, cutoff=budget - n) # inst.T - (N) * inst.t) idx = sol_.index(0) sol = sol_[idx:] + sol_[:idx] cost = complete_cost(cost, n) # exact (or time out) if len(fixed) > 0 or cost > budget: if exact: print("# trying exact solution") cost, edges = solve_tsp( range(n), c, False, fixed, 60000) # not using cutoff because it appears to be slow # cost, edges = tsp(n, c, cutoff=budget - n) cost = complete_cost(cost, n) cost_is_optimal_or_timeout = True try: sol = sequence(range(n), edges) except ValueError: print("# time out") cost = 99999999 sol = [] # keeps cost_is_optimal_or_timeout=True to avoid adding more points in add_while_possible() else: pass print('# NOT trying exact solution') elif n == 1: cost = 0 sol = [0] cost_is_optimal_or_timeout = True else: cost = dist(*pos[0], *pos[1]) cost = complete_cost(cost, n) sol = [0, 1] cost_is_optimal_or_timeout = True return sol, cost <= budget, cost, cost_is_optimal_or_timeout
def explorer(X, z, plan): """planner: decide list of points to visit based on: - X: list of coordinates [(x1,y1), ...., (xN,yN)] - z: list of evaluations of "true" function [z1, ..., zN] - plan: list of coordinates of initial probing plan [(x1,y1), ...., (xP,yP)] this plan may be changed; the only important movement is (x1,y1) """ X = list(X) # work with local copies z = list(z) from tsp import solve_tsp, sequence kernel = RationalQuadratic(length_scale_bounds=(0.08, 100)) + WhiteKernel( noise_level_bounds=(1e-5, 1e-2)) gpr = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=100) x0, y0 = (inst.x0, inst.y0) # initial position (depot) x1, y1 = plan[0] pos = [(x0, y0), (x1, y1)] N = 2 c = {} c[0, 1] = dist(*pos[0], *pos[1]) while True: # attempt adding Nth "city" to the tour points = max_var(gpr, n=100) # n x n grid !!!!! (x, y), (z_new_std, z_new) = points.pop() for i in range(N): c[i, N] = dist(*pos[i], *(x, y)) if N < 3: N += 1 pos.append((x, y)) continue # !!!!! obj, edges = solve_tsp(range(N + 1), c) if obj <= inst.T - (N) * inst.t: sol = sequence(range(N + 1), edges) print("TSP solution:", obj, N, inst.T, sol) print("appending", (x, y), z_new_std, z_new) N += 1 pos.append((x, y)) X.append((x, y)) z.append( z_new) # !!!!! with average of the prediction as an estimate gpr.fit(X, z) else: # maybe some other elements of 'points' should be attempted here break return [pos[i] for i in sol[1:]]
def planner(X, z, f, dynam=False): """planner: decide list of points to visit based on: - X: list of coordinates [(x1,y1), ...., (xN,yN)] - z: list of evaluations of "true" function [z1, ..., zN] - f: useless in static version """ X = list(X) # work with local copies z = list(z) from tsp import solve_tsp, sequence # exact from tsp import multistart_localsearch # heuristic kernel = RationalQuadratic(length_scale_bounds=(0.08, 100)) + WhiteKernel( noise_level_bounds=(1e-5, 1e-2)) gpr = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=10) # # plot preliminary GP # from functions import plot # from functions import f1 # plot(f1,100) # # end of plot # # # plot posteriori GP # GPR = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=10) # GPR.fit(X, z) # def GP(x_,y_): # return GPR.predict([(x_,y_)])[0] # plot(GP,100) # # # end of plot x0, y0 = (inst.x0, inst.y0) # initial position (depot) pos = [(x0, y0)] N = 1 c = {} while True: # attempt adding Nth "city" to the tour # retorna lista ordenada por variância points = max_var(gpr, n=100) # n x n grid !!!!! # pega ponto com maior variância (x, y), (z_new_std, z_new) = points.pop() # descarta previamente já selecionados, passando para a próxima maior variância while (x, y) in pos: (x, y), (z_new_std, z_new) = points.pop() # estende matriz de distâncias para ambos solvers for i in range(N): c[i, N] = dist(*pos[i], x, y) c[N, i] = c[i, N] # evita TSP em menos de 3 'cidades', falta checar limite de tempo if N < 3: N += 1 pos.append((x, y)) continue # !!!!! sol_, cost = multistart_localsearch(100, N + 1, c, cutoff=inst.T - (N) * inst.t) # heuristic if cost <= inst.T - (N) * inst.t: print("heuristic solution") idx = sol_.index(0) sol = sol_[idx:] + sol_[:idx] # heuristic # print(obj + (N)*inst.t, "TSP solution:", obj, N, inst.T, sol) # print("appending", (x,y), z_new_std, z_new, "orient.len:", obj + (N)*inst.t) N += 1 assert (x, y) not in pos pos.append((x, y)) X.append((x, y)) if (dynam): z.append(f(x, y)) # !!!!! with PROBING else: z.append( z_new ) # !!!!! with average of the prediction as an estimate gpr.fit(X, z) else: # attempt exact solution: print("attempting exact solution") cost, edges = solve_tsp(range(N + 1), c) # exact if cost <= inst.T - (N) * inst.t: sol = sequence(range(N + 1), edges) # exact # print(obj + (N) * inst.t, "TSP EXACT:", obj, N, inst.T, sol) # print("appending", (x, y), z_new_std, z_new, "orient.len:", obj + (N) * inst.t) N += 1 pos.append((x, y)) X.append((x, y)) if (dynam): z.append(f(x, y)) # !!!!! with PROBING else: z.append( z_new ) # !!!!! with average of the prediction as an estimate gpr.fit(X, z) print("found; continue") continue print("heuristic and exact solution exceeds time limit") # print("testing next interesting points") print("break") break print(cost + (N) * inst.t, "TSP solution:", cost, N, inst.T, sol) return [pos[i] for i in sol[1:]]
def planner(X, z, f, mode, dynam=False): """planner: decide list of points to visit based on: - X: list of coordinates [(x1,y1), ...., (xN,yN)] - z: list of evaluations of "true" function [z1, ..., zN] - f: useless in static version """ X = list(X) # work with local copies z = list(z) l = len(X) kernel = RationalQuadratic(length_scale_bounds=(0.08, 100)) + WhiteKernel( noise_level_bounds=(1e-5, 1e-2)) gpr = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=10) #gpr.fit(X,z) <- we should be fitting but for some reason it often worsens the solution # # plot preliminary GP # from functions import plot # from functions import f1 # plot(f1,100) # # end of plot # # # plot posteriori GP # GPR = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=10) # GPR.fit(X, z) # def GP(x_,y_): # return GPR.predict([(x_,y_)])[0] # plot(GP,100) # # # end of plot x0, y0 = (inst.x0, inst.y0) # initial position (depot) pos = [(x0, y0)] N = 1 c = {} randomize = False if mode == 0 else True local_search = False if mode % 2 == 0 else True multimodal = False if mode < 2 else True while True: # retorna lista ordenada por variância points = max_var(gpr, n=100) # n x n grid !!!!! z_std = [i[1][0] for i in points] if randomize: if not multimodal: (x, y), (z_new_std, z_new) = points.pop() while (x, y) in pos: (x, y), (z_new_std, z_new) = points.pop() (x, y), (z_new_std, z_new) = search_around_point(x, y, pos, gpr, n=100) else: (x, y), (z_new_std, z_new) = get_next_point(points, pos, gpr, local_search, n=100) #(x,y), (z_new_std, z_new) = find_next_candidate_point(pos, gpr, 0.01, 2) else: # pega ponto com maior variância (x, y), (z_new_std, z_new) = points.pop() # descarta previamente já selecionados, passando para a próxima maior variância while (x, y) in pos: (x, y), (z_new_std, z_new) = points.pop() print('Trying to probe point nº ', N) # estende matriz de distâncias para ambos solvers for i in range(N): c[i, N] = dist( *pos[i], x, y ) / inst.s # We divide by the speed to reflect the time needed to travel c[N, i] = c[i, N] # evita TSP em menos de 3 'cidades', falta checar limite de tempo if N < 3: N += 1 pos.append((x, y)) X.append((x, y)) z.append(z_new) #gpr.fit(X,z) continue # !!!!! sol_, cost = multistart_localsearch(100, N + 1, c, cutoff=inst.T - (N) * inst.t) # heuristic if cost <= inst.T - (N) * inst.t: print("heuristic solution") idx = sol_.index(0) sol = sol_[idx:] + sol_[:idx] # heuristic # print(obj + (N)*inst.t, "TSP solution:", obj, N, inst.T, sol) # print("appending", (x,y), z_new_std, z_new, "orient.len:", obj + (N)*inst.t) N += 1 assert (x, y) not in pos pos.append((x, y)) X.append((x, y)) if (dynam): z.append(f(x, y)) # !!!!! with PROBING else: z.append( z_new ) # !!!!! with average of the prediction as an estimate gpr.fit(X, z) else: # attempt exact solution: print("attempting exact solution") cost, edges = solve_tsp(range(N + 1), c) # exact if cost <= inst.T - (N) * inst.t: sol = sequence(range(N + 1), edges) # exact # print(obj + (N) * inst.t, "TSP EXACT:", obj, N, inst.T, sol) # print("appending", (x, y), z_new_std, z_new, "orient.len:", obj + (N) * inst.t) N += 1 pos.append((x, y)) X.append((x, y)) if (dynam): z.append(f(x, y)) # !!!!! with PROBING else: z.append( z_new ) # !!!!! with average of the prediction as an estimate gpr.fit(X, z) print("found; continue") continue print("heuristic and exact solution exceeds time limit") # print("testing next interesting points") print("break") break #print("Found original points. Checking them") #print() #result = check_chosen_points(X, pos, l, gpr, z, c, sol, N, n=100) #pos, sol = result[0], result[1] print(cost + (N) * inst.t, "TSP solution:", cost, N, inst.T, sol) return [pos[i] for i in sol[1:]]