def optimize(self,
                 iterations=10,
                 swap=2,
                 **kwargs) -> Tuple[float, np.ndarray]:
        """ Запуск метаэвристики табу поиска
        Алгоритм запоминает все локальные минимумы, и, если попадает в одно из  них, перезапускает поиск
        iterations: количество возможных перезапусков
        swap: сколько раз ломать тур за итерацию. Если тур не улучшится, на следующей итерации ломается он же
        return: лучшая длина тура, лучший тур
        """
        if self.collector is not None:
            self.collector.update({'length': self.length, 'gain': 0})

        while iterations > 0:
            self.opt.meta_heuristic_optimize(self.data, self.collector)
            _length, _tour = self.best_tour()

            if self.length > _length:
                self.length, self.tour = _length, _tour  # если найден другой хороший оптимум, обновляем текущий
                assert round(get_length(self.tour, self.matrix), 2) == round(self.length, 2), \
                    f'{get_length(self.tour, self.matrix)} != {self.length}'

            logging.info(f'{iterations} : {_length} : {self.length}')
            mix(self.tour, swap)  # а вот ломается текущий сохраненный
            self.length = get_length(self.tour, self.matrix)
            self.opt.length, self.opt.tour = self.length, self.tour.copy(
            )  # улучшается только копия
            iterations -= 1

        self.length, self.tour = self.best_tour()
        logging.info(f'tabu search done, best length: {self.length}')
        return self.length, self.tour
def worker(opt: AbcOpt, conn: Connection, iterations: int, swap: int):
    """ Локальный поиск под управлением Поиска с запретами
    Табу обновляется раз в итерацию, в основном процессе хранится весь табу
    opt: эвристика
    conn: для передачи данных
    iterations: количество возможных перезапусков
    swap: сколько раз ломать тур за итерацию
    """
    best_length, best_tour = opt.length, opt.tour.copy()
    length, tour = opt.length, opt.tour
    try:

        while iterations > 0:
            _length, _tour = opt.optimize()
            if best_length > _length:
                best_length, best_tour = _length, _tour.copy()
                assert round(get_length(best_tour, opt.matrix), 2) == round(best_length, 2), \
                    f'{get_length(best_tour, opt.matrix)} != {best_length}'

            conn.send(opt.solutions)
            solutions = conn.recv()

            mix(tour, swap)
            length = get_length(tour, opt.matrix)
            opt.length, opt.tour, opt.solutions = length, tour, solutions
            iterations -= 1

    except Exception as exc:
        print(f'Exception: {exc}')

    conn.send(set())
    conn.send(best_length)
    conn.send(best_tour)
Exemple #3
0
def test_lk_opt_full_bridge(generate_metric_tsp):
    length, tour, matrix = generate_metric_tsp
    lk_opt = LKOpt(length, tour, matrix, bridge=(1, True))
    opt_length, opt_tour = lk_opt.optimize()
    assert opt_length < length, 'optimized'
    assert round(get_length(opt_tour, matrix),
                 2) == round(opt_length, 2), 'generated wrong tour'
Exemple #4
0
def test_lk_opt_simple(generate_metric_tsp):
    length, tour, matrix = generate_metric_tsp
    lk_opt = LKOpt(length, tour, matrix, dlb=False)
    opt_length, opt_tour = lk_opt.optimize()
    assert opt_length < length, 'optimized'
    assert round(get_length(opt_tour, matrix),
                 2) == round(opt_length, 2), 'generated wrong tour'
Exemple #5
0
def test_three_opt(generate_metric_tsp):
    length, tour, matrix = generate_metric_tsp
    three_opt = ThreeOpt(length, tour, matrix)
    opt_length, opt_tour = three_opt.optimize()
    assert opt_length < length, 'optimized'
    assert round(get_length(opt_tour, matrix),
                 2) == round(opt_length, 2), 'generated wrong tour'
Exemple #6
0
def test_tabu_proc_search(generate_metric_tsp):
    length, tour, matrix = generate_metric_tsp
    lkh_search = TabuProcSearch('two_opt', matrix)
    opt_length, opt_tour = lkh_search.optimize()
    assert opt_length < length, 'optimized'
    assert round(get_length(opt_tour, matrix),
                 2) == round(opt_length, 2), 'generated wrong tour'
Exemple #7
0
def test_lkh_search_with_two_opt_init(generate_metric_tsp):
    length, tour, matrix = generate_metric_tsp
    lkh_search = LKHSearch(matrix, two_opt=True)
    opt_length, opt_tour = lkh_search.optimize()
    assert opt_length < length, 'optimized'
    assert round(get_length(opt_tour, matrix),
                 2) == round(opt_length, 2), 'generated wrong tour'
Exemple #8
0
def test_lkh_search_helsgaun(generate_metric_tsp):
    length, tour, matrix = generate_metric_tsp
    lkh_search = LKHSearch(matrix, init='helsgaun')
    opt_length, opt_tour = lkh_search.optimize()
    assert opt_length < length, 'optimized'
    assert round(get_length(opt_tour, matrix),
                 2) == round(opt_length, 2), 'generated wrong tour'
Exemple #9
0
def test_tabu_search_with_collect(generate_metric_tsp):
    length, tour, matrix = generate_metric_tsp
    tabu_search = TabuSearch('two_opt', matrix, collect=True)
    opt_length, opt_tour = tabu_search.optimize()
    assert opt_length < length, 'optimized'
    assert round(get_length(opt_tour, matrix),
                 2) == round(opt_length, 2), 'generated wrong tour'
Exemple #10
0
def test_tabu_search_lkh_opt(generate_metric_tsp):
    length, tour, matrix = generate_metric_tsp
    tabu_search = TabuSearch('lkh_opt', matrix)
    opt_length, opt_tour = tabu_search.optimize()
    assert opt_length < length, 'optimized'
    assert round(get_length(opt_tour, matrix),
                 2) == round(opt_length, 2), 'generated wrong tour'
Exemple #11
0
def test_lkh_opt_non_seq(generate_metric_tsp):
    length, tour, matrix = generate_metric_tsp
    lkh_opt = LKHOpt(length, tour, matrix, bridge=True, non_seq=True)
    opt_length, opt_tour = lkh_opt.optimize()
    assert opt_length < length, 'optimized'
    assert round(get_length(opt_tour, matrix),
                 2) == round(opt_length, 2), 'generated wrong tour'
Exemple #12
0
    def optimize(self, iterations=10, **kwargs) -> Tuple[float, np.ndarray]:
        """ Запуск метаэвристики Multi trial LKH
        iterations: количество возможных перезапусков
        return: лучшая длина тура, лучший тур
        """
        if self.collector is not None:
            self.collector.update({'length': self.length, 'gain': 0})

        while iterations > 0:
            self.opt.meta_heuristic_optimize(self.data, self.collector)
            _length, _tour = self.best_tour()

            if self.length > _length:
                self.length, self.tour = _length, _tour  # если найден другой хороший оптимум, обновляем текущий
                self.opt.best_solution = get_set(self.tour)
                assert round(get_length(self.tour, self.matrix), 2) == round(self.length, 2), \
                    f'{get_length(self.tour, self.matrix)} != {self.length}'

            logging.info(f'{iterations} : {_length} : {self.length}')

            if self.initial == 'helsgaun' or self.initial == 'fast_helsgaun':
                self.opt.length, self.opt.tour = _initialization[self.initial](
                    self.opt.alpha,
                    self.matrix,
                    self.opt.best_solution,
                    self.opt.candidates,
                    self.opt.excess)
            else:
                self.opt.length, self.opt.tour = _initialization[self.initial](self.matrix)

            assert round(get_length(self.opt.tour, self.matrix), 2) == round(self.opt.length, 2), \
                f'{get_length(self.opt.tour, self.matrix)} != {self.opt.length}'

            iterations -= 1

        self.length, self.tour = self.best_tour()
        logging.info(f'multi trial lkh done, best length: {self.length}')
        return self.length, self.tour
Exemple #13
0
    def meta_heuristic_optimize(
            self, tabu_list: TabuSet,
            collector: Optional[Collector]) -> Tuple[float, np.ndarray]:
        """ Запуск локального поиска под управление некоторой метаэвристики
        tabu_list: проверенные ранее маршруты
        collector: структура для сбора данных о локальном поиске
        return: длина, список городов
        """
        gain, self.tabu_list, self.collector = 1, tabu_list, collector
        self.solutions = self.tabu_list.data

        while gain > 0:
            gain = self.improve()

            if gain > 1.e-10:
                if not self.tabu_list.append(self.length, self.tour):
                    break
                logging.info(self.length)

            assert round(get_length(self.tour, self.matrix), 2) == round(self.length, 2), \
                f'{get_length(self.tour, self.matrix)} != {self.length}'

        return self.length, self.tour
Exemple #14
0
    def optimize(self) -> Tuple[float, np.ndarray]:
        """ Запуск локального поиска
        return: длина, список городов
        """
        gain, iteration = 1, 0
        logging.info(f'start : {self.length}')

        while gain > 0:
            gain = self.improve()
            if gain > 0:
                logging.info(f'{iteration} : {self.length}')
                iteration += 1

            h = generate_hash(self.tour)
            if h in self.solutions:
                break
            else:
                self.solutions.add(h)

            assert round(get_length(self.tour, self.matrix), 2) == round(self.length, 2), \
                f'{get_length(self.tour, self.matrix)} != {self.length}'

        return self.length, self.tour
Exemple #15
0
def test_fast_three_opt(generate_metric_tsp):
    length, tour, matrix = generate_metric_tsp
    opt_length, opt_tour = ThreeOpt.just_improve(length, tour, matrix)
    assert opt_length < length, 'optimized'
    assert round(get_length(opt_tour, matrix),
                 2) == round(opt_length, 2), 'generated wrong tour'
Exemple #16
0
def test_greedy_with_two_opt():
    tsp = generator(size)
    matrix = adjacency_matrix(tsp)
    length, tour = two_opt(matrix)
    assert round(get_length(tour, matrix),
                 2) == round(length, 2), 'generated wrong tour'