def shaw_insertion(solution, rho): period = np.random.randint(1, solution.T + 1) not_served = np.where(~np.any(solution.Y[period], axis=(0, 1)))[0] if len(not_served) > 0: (index, choice) = random.choice(list(enumerate(not_served))) dist_to_all = solution.problem.D[np.ix_( [choice + solution.N], [m + solution.N for m in range(solution.M) if m != choice])][0] rest_not_served = np.delete(not_served, index) dist_to_not_served = solution.problem.D[np.ix_( [choice + solution.N], rest_not_served + solution.N)][0] close = rest_not_served[dist_to_not_served <= 2 * np.min(dist_to_all)] closest_warehouse = np.argmin(solution.problem.D[np.ix_( [choice + solution.N], [i for i in range(solution.N)])][0]) close_reachable = [ m for m in close[solution.Cl[closest_warehouse, close] == 1] ] route = tsp_tour( close_reachable + solution.r[period][closest_warehouse][0], closest_warehouse, solution.problem.D) costs = solution.compute_route_dist(route, closest_warehouse) index = 0 for k in range(1, solution.V_number[closest_warehouse]): route_temp = tsp_tour( close_reachable + solution.r[period][closest_warehouse][k], closest_warehouse, solution.problem.D) costs_temp = solution.compute_route_dist(route_temp, closest_warehouse) if costs_temp < costs: route = route_temp index = k solution.Y[period, closest_warehouse, index, close_reachable] = 1 solution.r[period][closest_warehouse][index] = route
def swap_rho_cust_intra_plants(solution, rho): max_iter = 100 iterations = 0 changed = 0 candidates_time = np.where( np.sum(np.any(solution.Y, axis=(2, 3)), axis=1) > 1)[0] if len(candidates_time) > 0: while iterations < max_iter and changed < rho: t = random.choice(candidates_time) candidates_warehouses = np.nonzero( np.any(solution.Y[t, :, :, :], axis=(1, 2)))[0] temp1, temp2 = np.random.choice(len(candidates_warehouses), 2, replace=False) n1, n2 = candidates_warehouses[temp1], candidates_warehouses[temp2] candidates_1 = np.transpose(np.nonzero(solution.Y[t, n1, :, :])) candidates_2 = np.transpose(np.nonzero(solution.Y[t, n2, :, :])) [k1, m1], [k2, m2 ] = random.choice(candidates_1), random.choice(candidates_2) if solution.Cl[n1, m2] == 1 and solution.Cl[n2, m1] == 1: solution.Y[t, [n1, n2], [k1, k2], m1] = [0, 1] solution.Y[t, [n1, n2], [k1, k2], m2] = [1, 0] solution.r[t][n1][k1], solution.r[t][n2][k2] = tsp_tour( np.nonzero(solution.Y[t, n1, k1, :])[0] + solution.N, n1, solution.problem.D), tsp_tour( np.nonzero(solution.Y[t, n2, k2, :])[0] + solution.N, n2, solution.problem.D) changed += 1 iterations += 1
def insert_best_rho(solution, rho): candidates = ~np.any(solution.Y, axis=(1, 2)) # ~ is the negation of a boolean array candidates[0, :] = 0 eliminate = np.transpose(np.where(np.any(solution.Y, axis=(1, 2)))) for t, m in eliminate: solution.b[t, :, :, m] = sys.maxsize solution.b[0] = sys.maxsize for i in range(min(rho, np.sum(candidates))): b_flat = solution.b.reshape(-1) Y_flat = solution.Y.reshape(-1) Cl_flat = solution.Cl_shaped_like_Y().reshape(-1) V_num_flat = solution.V_num_array(shape_Y=True).reshape(-1) choice = np.where(V_num_flat + Cl_flat - Y_flat > 1)[0][np.argmin( b_flat[V_num_flat + Cl_flat - Y_flat > 1])] Y_flat[choice] = 1 t, rest = np.divmod(choice, solution.N * solution.K * solution.M) n, rest = np.divmod(rest, solution.K * solution.M) k, m = np.divmod(rest, solution.M) #solution.r[t][n][k],_ = solution.cheapest_school_insert(t,n,k,m) tour_school = np.nonzero(solution.Y[t, n, k, :])[0] + solution.N solution.r[t][n][k] = tsp_tour(tour_school, n, solution.problem.D) solution.compute_school_insert_dist(t, n, k) for m_temp in range(solution.M): if np.any(solution.Y, axis=(1, 2))[t, m_temp]: solution.b[t, n, k, m_temp] = sys.maxsize solution.b[t, :, :, m] = sys.maxsize solution.compute_a_and_b()
def avoid_consecutive_visits(solution, rho): for t in range(solution.T): time_schools = np.sum(solution.Y[[t, t + 1], :, :, :], axis=(1, 2)) index = np.where(time_schools[1, :] + time_schools[0, :] > 1)[0] change = np.transpose( np.where(np.sum(solution.Y[:, :, :, index][t + 1], axis=2) > 0)) solution.Y[t + 1, :, :, index] = 0 for n, k in change: schools = np.nonzero(solution.Y[t + 1, n, k, :])[0] solution.r[t + 1][n][k] = tsp_tour(schools + solution.N, n, solution.problem.D)
def swap_rho_cust_intra_routes(solution, rho): not_empty_veh = np.any(solution.Y, axis=3) candidates = np.transpose(np.where(np.sum(not_empty_veh, axis=2) > 1)) if len(candidates) > 0: for i in range(rho): [t, n] = random.choice(candidates) candid_veh = np.where(not_empty_veh[t, n, :])[0] number = len(candid_veh) k1, k2 = candid_veh[np.random.choice(number, 2, replace=False)] m1, m2 = random.choice(np.nonzero( solution.Y[t, n, k1, :])[0]), random.choice( np.nonzero(solution.Y[t, n, k2, :])[0]) if m1 != m2: solution.Y[t, n, [k1, k2], m1] = [0, 1] solution.Y[t, n, [k1, k2], m2] = [1, 0] solution.r[t][n][k1], solution.r[t][n][k2] = tsp_tour( np.nonzero(solution.Y[t, n, k1, :])[0] + solution.N, n, solution.problem.D), tsp_tour( np.nonzero(solution.Y[t, n, k2, :])[0] + solution.N, n, solution.problem.D)
def remove_worst_rho(solution, rho): for i in range(np.min([rho,len(np.nonzero(solution.Y)[0])])): choice = np.argmax(solution.a) solution.Y.reshape(-1)[choice] = 0 solution.a.reshape(-1)[choice] = 0 t, rest = np.divmod(choice, solution.N*solution.K*solution.M) n, rest = np.divmod(rest, solution.K*solution.M) k = np.floor_divide(rest, solution.M) tour_school = np.nonzero(solution.Y[t,n,k,:])[0] + solution.N solution.r[t][n][k] = tsp_tour(tour_school, n, solution.problem.D.values) solution.compute_school_remove(t,n,k)
def compute_r(self): # here are the TSP to be computed self.r = [[[[] for k in range(self.K)] for n in range(self.N)] for t in range(self.T)] # for each time t, for each vehicle k, for each warehouse n, a list of ordered integer of [0, M+N] corresponding to a tour dist_mat = self.problem.D.values for t in range(self.T): for n in range(self.N): for k in range(self.K): tour_school = np.nonzero(self.Y[t,n,k,:])[0] + self.N #tour = [n] + np.ndarray.tolist(np.array(s[0])+self.N) + [n] # the tour starts at the warehouse then add the school in the wrong order #edit Chris 07.06.20: tour = tsp_tour(tour_school, n, dist_mat) #function returns optimal tour and length of optimal tour #end of edit Chris 07.06.20 self.r[t][n][k] = tour # is this tour with or without the warehouse ?? It should be without
def insert_best_rho(solution, rho): for i in range(np.min([rho, len(np.where(solution.Y + 1 - solution.Cl_shaped_like_Y() == 0)[0])])): b_flat = solution.b.reshape(-1) Y_flat = solution.Y.reshape(-1) allowed = Y_flat + 1 - solution.Cl_shaped_like_Y().reshape(-1) == 0 choice = np.where(allowed)[0][np.argmin(b_flat[allowed])] Y_flat[choice] = 1 b_flat[choice] = 0 t, rest = np.divmod(choice, solution.N*solution.K*solution.M) n, rest = np.divmod(rest, solution.K*solution.M) k = np.floor_divide(rest, solution.M) tour_school = np.nonzero(solution.Y[t,n,k,:])[0] + solution.N solution.r[t][n][k] = tsp_tour(tour_school, n, solution.problem.D.values) solution.compute_school_insert(t,n,k)
def shaw_removal_route_based(solution, rho): if np.any(solution.Y): t, n, k, m = random.choice(np.transpose(np.nonzero(solution.Y))) route = np.array(solution.r[t][n][k]) if len(route) > 2: schools = route[np.where(route != m + solution.N)[0]] dist_from_m = solution.problem.D[np.ix_([m + solution.N], route)][0] min_dist_from_m = np.min(solution.problem.D[np.ix_( [m + solution.N], schools)][0]) to_remove = route[np.where( dist_from_m <= 2 * min_dist_from_m)[0]] - solution.N solution.Y[t, n, k, to_remove] = 0 solution.r[t][n][k] = tsp_tour( np.setdiff1d(route, to_remove + solution.N), n, solution.problem.D) else: solution.Y[t, n, k, :] = 0 solution.r[t][n][k] = []