Exemple #1
0
    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
Exemple #2
0
 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())
Exemple #3
0
    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
Exemple #4
0
    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))
Exemple #5
0
    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
Exemple #6
0
    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))
Exemple #7
0
    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
Exemple #8
0
    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
Exemple #9
0
 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)
Exemple #10
0
    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))
Exemple #11
0
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)
Exemple #12
0
    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'))
Exemple #13
0
    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