def _intraclass_computation(self, best_cost, checked_cycle, computation_cycle, method): result = list() nodes_combination = list(combinations(checked_cycle[:-1], r=2)) if method == 'greedy': random.shuffle(nodes_combination) for (node1, node2) in nodes_combination: if self.neighborhood == 'nodes': temp_solution, temp_cost = cycle_operations.replace_nodes_inside_cycle( self, node1, node2, checked_cycle[:], best_cost) if temp_cost < best_cost: result.append( Replacement(temp_solution, computation_cycle, temp_cost)) if method == 'greedy': break if self.neighborhood == 'edges': temp_solution, temp_cost = cycle_operations.replace_edges_inside_cycle( self, node1, node2, checked_cycle[:], best_cost) if temp_cost < best_cost: result.append( Replacement(temp_solution, computation_cycle, temp_cost)) if method == 'greedy': break return result
def _greedy(self, fs, ss): greedy_cycle = Greedy(self.instance, regret=0) greedy_cycle.first_solution = fs greedy_cycle.second_solution = ss _ = greedy_cycle.solve(fs[0], ss[0]) return Replacement(greedy_cycle.first_solution[:], greedy_cycle.second_solution[:], greedy_cycle.compute_total_cost())
def _ils2_fn(self, n_candidats, num_nodes, max_time, ils2a): cost = self.compute_total_cost() solutions_list = list() greedy_cycle = Greedy(self.instance, regret=0) start = time.time() _, cost = self._steepest_solution(n_candidats, max_time=max_time - (time.time() - start), total_best_cost=cost) solutions_list.append( Replacement(self._first_solution, self._second_solution, cost)) while time.time() - start < max_time: random_perturbation = random.sample( range(int(self.examples_num_first)), k=int(self.examples_num_first * num_nodes / 100)) fs = list( map(self._first_solution.__getitem__, random_perturbation)) ss = list( map(self._second_solution.__getitem__, random_perturbation)) fs.append(fs[0]) ss.append(ss[0]) greedy_cycle.first_solution = fs greedy_cycle.second_solution = ss _ = greedy_cycle.solve(fs[0], ss[0]) self._first_solution = greedy_cycle.first_solution self._second_solution = greedy_cycle.second_solution cost = greedy_cycle.compute_total_cost() if ils2a: _, cost = self._steepest_solution(n_candidats, max_time=max_time - (time.time() - start), total_best_cost=cost) solutions_list.append( Replacement(self._first_solution, self._second_solution, cost)) min_sol = min(solutions_list) self._first_solution, self._second_solution = min_sol.first_cycle, min_sol.second_cycle return time.time() - start
def _perform_between_cycles(self, main_solution, node_idx, neighbour, candidates): solution = getattr(self, main_solution)[:] if candidates: local_best = min(candidates).score else: local_best = self.total_best_cost if main_solution == '_first_solution': temp_first_solution, temp_second_solution, temp_cost \ = cycle_operations.replace_nodes_between_cycles(self, solution[node_idx+1], neighbour, \ self._first_solution[:], self._second_solution[:], \ self.total_best_cost) else: temp_first_solution, temp_second_solution, temp_cost \ = cycle_operations.replace_nodes_between_cycles(self, neighbour, solution[node_idx+1], \ self._first_solution[:], self._second_solution[:], \ self.total_best_cost) if temp_cost < local_best: local_best = temp_cost candidates.append( Replacement(temp_first_solution[:], temp_second_solution[:], temp_cost)) j = node_idx - 1 if j == -1: j = -2 if main_solution == '_first_solution': temp_first_solution, temp_second_solution, temp_cost \ = cycle_operations.replace_nodes_between_cycles(self, solution[j], neighbour, \ self._first_solution[:], self._second_solution[:], \ self.total_best_cost) else: temp_first_solution, temp_second_solution, temp_cost \ = cycle_operations.replace_nodes_between_cycles(self, neighbour, solution[j], \ self._first_solution[:], self._second_solution[:], \ self.total_best_cost) if temp_cost < local_best: local_best = temp_cost candidates.append( Replacement(temp_first_solution[:], temp_second_solution[:], temp_cost))
def _ils1_fn(self, n_candidats, num_moves, max_time): cost = self.compute_total_cost() solutions_list = list() start = time.time() _, cost = self._steepest_solution(n_candidats, max_time=max_time - (time.time() - start), total_best_cost=cost) solutions_list.append( Replacement(self._first_solution, self._second_solution, cost)) while time.time() - start < max_time: nodes_f = random.sample(self._first_solution[:-1], k=num_moves + 1) nodes_s = random.sample(self._second_solution[:-1], k=num_moves + 1) for i in range(num_moves): self._first_solution, cost = cycle_operations.replace_nodes_inside_cycle( self, nodes_f[i], nodes_f[i + 1], self._first_solution[:], cost) self._second_solution, cost = cycle_operations.replace_nodes_inside_cycle( self, nodes_s[i], nodes_s[i + 1], self._second_solution[:], cost) nodes_f = random.sample(self._first_solution[:-1], k=num_moves) nodes_s = random.sample(self._second_solution[:-1], k=num_moves) for i in range(num_moves): self._first_solution, self._second_solution, cost = cycle_operations.replace_nodes_between_cycles( self, nodes_f[i], nodes_s[i], self._first_solution[:], self._second_solution[:], cost) _, cost = self._steepest_solution(n_candidats, max_time=max_time - (time.time() - start), total_best_cost=cost) solutions_list.append( Replacement(self._first_solution, self._second_solution, cost)) min_sol = min(solutions_list) self._first_solution, self._second_solution = min_sol.first_cycle, min_sol.second_cycle return time.time() - start
def _perform_inside_cycle(self, main_solution, node, node_idx, neighbour, solutions_idx, candidates): if candidates: local_best = min(candidates).score else: local_best = self.total_best_cost solution = getattr(self, main_solution)[:] temp_solution, temp_cost = cycle_operations.replace_edges_inside_cycle( self, node, neighbour, solution, self.total_best_cost) if temp_cost < local_best: local_best = temp_cost if main_solution == '_first_solution': candidates.append( Replacement(temp_solution[:], self._second_solution[:], temp_cost)) else: candidates.append( Replacement(self._first_solution[:], temp_solution[:], temp_cost)) if node_idx + 1 == solutions_idx[neighbour]: return j_n = solutions_idx[neighbour] + 1 if j_n == len(solution) - 1: return temp_solution, temp_cost = cycle_operations.replace_edges_inside_cycle( self, solution[node_idx + 1], solution[j_n], solution, self.total_best_cost) if temp_cost < local_best: local_best = temp_cost if main_solution == '_first_solution': candidates.append( Replacement(temp_solution[:], self._second_solution[:], temp_cost)) else: candidates.append( Replacement(self._first_solution[:], temp_solution[:], temp_cost))
def _interclass_computation(self, best_cost, method, replace=False): result = list() nodes_product = list( product(self._first_solution[:-1], self._second_solution[:-1])) if method == 'greedy': random.shuffle(nodes_product) for (node1, node2) in nodes_product: temp_first_solution, temp_second_solution, temp_cost = cycle_operations.replace_nodes_between_cycles( self, node1, node2, self._first_solution[:], self._second_solution[:], best_cost) if temp_cost < best_cost: if replace: result.append( Replacement(temp_second_solution, temp_first_solution, temp_cost)) else: result.append( Replacement(temp_first_solution, temp_second_solution, temp_cost)) if method == 'greedy': break return result
def _steady_state(self, n_candidats, max_time, ls): greedy_cycle = Greedy(self.instance, regret=0) start = time.time() for solution in self.solutions: solution = self._local_local_search( solution, n_candidats, max_time - (time.time() - start)) while time.time() - start < max_time: [first_parent, second_parent] = random.sample(self.solutions, k=2) self._first_solution = first_parent.first_cycle[:] self._second_solution = first_parent.second_cycle[:] fs, ss = self._recombination(second_parent) if len(fs) == 0: fs = [self._first_solution[0]] if len(ss) == 0: ss = [self._second_solution[0]] fs.append(fs[0]) ss.append(ss[0]) greedy_cycle.first_solution = fs greedy_cycle.second_solution = ss _ = greedy_cycle.solve(fs[0], ss[0]) self._first_solution = greedy_cycle.first_solution self._second_solution = greedy_cycle.second_solution cost = greedy_cycle.compute_total_cost() if ls: _, cost = self._steepest_solution(n_candidats, max_time=max_time - (time.time() - start), total_best_cost=cost) child = Replacement(self.first_solution[:], self.second_solution[:], cost) if not self._child_in_population(child): idx = argmax(self.solutions) if child.score < self.solutions[idx].score: self.solutions[idx] = child min_sol = min(self.solutions) self._first_solution, self._second_solution = min_sol.first_cycle, min_sol.second_cycle return time.time() - start
def _init_population(self): unavailable_points = list() for i in range(20): first_start_node = random.choice( list( set(list(self.instance.point_dict.keys())) - set(unavailable_points))) second_start_node = np.argmax( self.instance.matrix[first_start_node]) unavailable_points.append(first_start_node) unavailable_points.append(second_start_node) #Get random solution greedy_cycle = Greedy(self.instance, regret=0, neighbour=True) greedy_cycle.solve(first_start_node, second_start_node) population = Replacement(greedy_cycle.first_solution[:], greedy_cycle.second_solution[:], greedy_cycle.compute_total_cost()) self.solutions.append(population)
def _intraclass_computation(self, best_cost, checked_cycle, computation_cycle, new_node=None, result=SortedList(), main_cycle='_first_solution'): if new_node is None: nodes_product = list(combinations(checked_cycle[:-1], r=2)) else: nodes_product = list(product([new_node], checked_cycle[:-1])) for (node1, node2) in nodes_product: _, temp_cost = cycle_operations.replace_edges_inside_cycle( self, node1, node2, checked_cycle[:], best_cost) if temp_cost < best_cost: result.add( Replacement(None, None, temp_cost, node1, node2, 'intraclass', main_cycle))
def main(): times_number = get_value() times = defaultdict(list) scores = defaultdict(list) for instance_name in ['kroA200', 'kroB200']: instance = Instance(name=instance_name) instance.compute_matrix() #################################### max_time = 733.0 print(f'MSLS time: {max_time}') unavailable_points = list() for number in range(times_number): solutions = [] for i in range(20): first_start_node = random.choice( list( set(list(instance.point_dict.keys())) - set(unavailable_points))) second_start_node = np.argmax( instance.matrix[first_start_node]) unavailable_points.append(first_start_node) unavailable_points.append(second_start_node) #Get random solution random_cycle = Random(instance, seed=None) random_cycle.solve(first_start_node, second_start_node) population = Replacement(random_cycle.first_solution[:], random_cycle.second_solution[:], random_cycle.compute_total_cost()) solutions.append(population) print(f'Global iteration number: {number+1}') ################################################################## #SteadyState + LS print('\t-> SteadyState + LS') steady_state = SteadyState(instance, deepcopy(solutions)) steady_state.neighborhood = 'edges' steady_state.first_solution = None steady_state.second_solution = None time = steady_state.solve(n_candidats=8, max_time=max_time, ls=True) times[f'SteadyState + LS, {instance_name}'].append(time) scores[f'SteadyState + LS, {instance_name}'].append( deepcopy(steady_state)) ################################################################## #ILS2 print('\t-> SteadyState - LS') steady_state = SteadyState(instance, deepcopy(solutions)) steady_state.neighborhood = 'edges' steady_state.first_solution = None steady_state.second_solution = None time = steady_state.solve(n_candidats=8, max_time=max_time, ls=False) times[f'SteadyState - LS, {instance_name}'].append(time) scores[f'SteadyState - LS, {instance_name}'].append( deepcopy(steady_state)) save_string = '\n' worst_time = float('-inf') for key in scores.keys(): best = min(scores[key], key=lambda el: el.compute_total_cost()) costs = list(map(lambda el: el.compute_total_cost(), scores[key])) save_string += f'Version: {key}\nMean: {np.mean(costs)}\nMin: {min(costs)}\nMax: {max(costs)}\n\n|TIMES|\n' save_string += f'\nMean: {np.mean(times[key])}\nMin: {min(times[key])}\nMax: {max(times[key])}\n\n==========\n\n' if np.mean(times[key]) > worst_time: worst_time = np.mean(times[key]) plot_best(best, key) print(save_string) save_string_fn(save_string, 'SteadyState_results', None)
def _interclass_computation(self, best_cost, new_node1=None, new_node2=None, result=SortedList(), main_cycle=None): if new_node1 is None: nodes_product = list( product(self._first_solution[:-1], self._second_solution[:-1])) for (node1, node2) in nodes_product: _, _, temp_cost = cycle_operations.replace_nodes_between_cycles( self, node1, node2, self._first_solution[:], self._second_solution[:], best_cost) if temp_cost < best_cost: result.add( Replacement(None, None, temp_cost, node1, node2, 'interclass')) elif main_cycle == '_second_solution': nodes_product = list( product(self._first_solution[:-1], [new_node1])) for (node1, node2) in nodes_product: _, _, temp_cost = cycle_operations.replace_nodes_between_cycles( self, node1, node2, self._first_solution[:], self._second_solution[:], best_cost) if temp_cost < best_cost: result.add( Replacement(None, None, temp_cost, node1, node2, 'interclass')) nodes_product = list( product(self._first_solution[:-1], [new_node2])) for (node1, node2) in nodes_product: _, _, temp_cost = cycle_operations.replace_nodes_between_cycles( self, node1, node2, self._first_solution[:], self._second_solution[:], best_cost) if temp_cost < best_cost: result.add( Replacement(None, None, temp_cost, node1, node2, 'interclass')) elif main_cycle == '_first_solution': nodes_product = list( product([new_node1], self._second_solution[:-1])) for (node1, node2) in nodes_product: _, _, temp_cost = cycle_operations.replace_nodes_between_cycles( self, node1, node2, self._first_solution[:], self._second_solution[:], best_cost) if temp_cost < best_cost: result.add( Replacement(None, None, temp_cost, node1, node2, 'interclass')) nodes_product = list( product([new_node2], self._second_solution[:-1])) for (node1, node2) in nodes_product: _, _, temp_cost = cycle_operations.replace_nodes_between_cycles( self, node1, node2, self._first_solution[:], self._second_solution[:], best_cost) if temp_cost < best_cost: result.add( Replacement(None, None, temp_cost, node1, node2, 'interclass')) else: nodes_product = list( product(self._first_solution[:-1], [new_node1])) for (node1, node2) in nodes_product: _, _, temp_cost = cycle_operations.replace_nodes_between_cycles( self, node1, node2, self._first_solution[:], self._second_solution[:], best_cost) if temp_cost < best_cost: result.add( Replacement(None, None, temp_cost, node1, node2, 'interclass')) nodes_product = list( product([new_node2], self._second_solution[:-1])) for (node1, node2) in nodes_product: _, _, temp_cost = cycle_operations.replace_nodes_between_cycles( self, node1, node2, self._first_solution[:], self._second_solution[:], best_cost) if temp_cost < best_cost: result.add( Replacement(None, None, temp_cost, node1, node2, 'interclass'))
def _own_method(self, max_time): start = time.time() self._init_population() for solution in self.solutions: solution = self._local_local_search( solution, max_time - (time.time() - start)) improvement = 0 while time.time() - start < max_time: print(f'\t\t->{time.time() - start}') [first_parent, second_parent, third_parent, fourth_parent] = random.sample(self.solutions, k=4) first_parent_copy_fs = first_parent.first_cycle[:] first_parent_copy_ss = first_parent.second_cycle[:] #third_parent_copy_fs = third_parent.first_cycle[:] #third_parent_copy_ss = third_parent.second_cycle[:] fs1, ss1 = self._recombination(first_parent, second_parent) #fs2, ss2 = self._recombination(third_parent, fourth_parent) fs1, ss1 = self._add_if_empty(fs1, ss1, first_parent_copy_fs[0], first_parent_copy_ss[0]) #fs2, ss2 = self._add_if_empty(fs2, ss2, third_parent_copy_fs[0], third_parent_copy_ss[0]) parent1 = self._greedy(fs1, ss1) #parent2 = self._greedy(fs2, ss2) #if parent1.score < parent2.score: # fs, ss = self._recombination2(parent1, parent2) #else: # fs, ss = self._recombination2(parent2, parent1) #parent = self._greedy(fs, ss) self._first_solution = parent1.first_cycle[:] self._second_solution = parent1.second_cycle[:] cost = parent1.score _, cost = self._steepest_solution(method='steepest', max_time=max_time - (time.time() - start), total_best_cost=cost) child = Replacement(self._first_solution[:], self._second_solution[:], cost) if not self._child_in_population(child): idx = argmax(self.solutions) if child.score < self.solutions[idx].score: self.solutions[idx] = child improvement = 0 else: improvement += 1 if improvement >= 5: print(f'\t\t\t->Iterated') self.solutions = sorted(self.solutions) for i in range( len(self.solutions) - 1, len(self.solutions) - len(self.solutions) // 4, -1): local_search = LocalSearchIterated(self.instance) local_search.neighborhood = 'edges' local_search.first_solution = self.solutions[ i].first_cycle[:] local_search.second_solution = self.solutions[ i].second_cycle[:] local_search.solve_ils2( n_candidats=8, num_nodes=10, max_time=min(max_time - (time.time() - start), 10), ils2a=False) child = Replacement(local_search.first_solution[:], local_search.second_solution[:], local_search.compute_total_cost()) if not self._child_in_population(child): if child.score < self.solutions[i].score: self.solutions[i] = child np.random.shuffle(self.solutions) improvement = 0 min_sol = min(self.solutions) self._first_solution, self._second_solution = min_sol.first_cycle, min_sol.second_cycle return time.time() - start