Example #1
0
 def alns(self, sol: Solution):
     """Perform adaptive large neighborhood search (ALNS) on given solution."""
     self.next_segment = self.iteration + self.own_settings.mh_alns_segment_size
     sol_incumbent = sol.copy()
     sol_new = sol.copy()
     while True:
         destroy, repair = self.select_method_pair()
         res = self.perform_method_pair(destroy, repair, sol_new)
         self.update_after_destroy_and_repair_performed(
             destroy, repair, sol_new, sol_incumbent, sol)
         if res.terminate:
             sol.copy_from(sol_incumbent)
             return
         self.update_operator_weights()
Example #2
0
 def gvns(self, sol: Solution):
     """Perform general variable neighborhood search (GVNS) to given solution."""
     sol2 = sol.copy()
     if self.vnd(sol2) or not self.meths_sh:
         return
     use_vnd = bool(self.meths_li)
     while True:
         for m in self.next_method(self.meths_sh, repeat=True):
             t_start = time.process_time()
             res = self.perform_method(m, sol2, delayed_success=use_vnd)
             terminate = res.terminate
             if not terminate and use_vnd:
                 terminate = self.vnd(sol2)
             self.delayed_success_update(m, sol.obj(), t_start, sol2)
             if sol2.is_better(sol):
                 sol.copy_from(sol2)
                 if terminate or res.terminate:
                     return
                 break
             else:
                 if terminate or res.terminate:
                     return
                 sol2.copy_from(sol)
         else:
             break
Example #3
0
    def ts(self, sol: Solution):

        while True:
            # use of multiple different methods for restricted neighborhood search is possible,
            # but usually only one is used
            for m in self.next_method(self.meths_rli, repeat=True):
                sol_old = sol.copy()

                def ts_iteration(sol: Solution, _par, result):

                    for ta in self.tabu_list.tabu_list:
                        self.step_logger.info(f'TA: {ta}')

                    m.func(sol, m.par, None, self.tabu_list, self.incumbent)

                ts_method = Method(m.name, ts_iteration, m.par)

                t_start = time.process_time()
                res = self.perform_method(ts_method, sol, delayed_success=True)
                self.update_tabu_list(sol, sol_old)
                self.delayed_success_update(m, sol.obj(), t_start, sol_old)

                for ta in self.tabu_list.tabu_list:
                    self.step_logger.info(f'TA: {ta}')

                if res.terminate:
                    return
Example #4
0
    def __new__(cls,
                sol: Solution,
                meths_ch: List[Method],
                own_settings: dict = None):
        """Create population of mh_pop_size solutions using the list of construction heuristics if given.

        If sol is None or no constructors are given, the population is initialized empty.
        sol itself is just used as template for obtaining further solutions.
        """
        own_settings = OwnSettings(own_settings) if own_settings else settings
        size = own_settings.mh_pop_size
        obj = super(Population, cls).__new__(cls, size, Solution)
        obj.own_settings = own_settings
        if sol is not None and meths_ch:
            # cycle through construction heuristics to generate population
            # perform all construction heuristics, take best solution
            meths_cycle = cycle(meths_ch)
            idx = 0
            while idx < size:
                m = next(meths_cycle)
                sol = sol.copy()
                res = Result()
                m.func(sol, m.par, res)
                if own_settings.mh_pop_dupelim and obj.duplicates_of(
                        sol) != []:
                    continue  # do not add this duplicate
                obj[idx] = sol
                if res.terminate:
                    break
                idx += 1
        return obj
Example #5
0
 def alns(self, sol: Solution):
     """Perform adaptive large neighborhood search (ALNS) on given solution."""
     self.next_segment = self.iteration + self.own_settings.mh_alns_segment_size
     sol_incumbent = sol.copy()
     sol_new = sol.copy()
     operators = self.operators_generator(sol_new)
     worker_seed = 0 if settings.mh_workers > 1 else settings.seed
     with mp.Pool(processes=settings.mh_workers,
                  initializer=self.process_init,
                  initargs=(settings, worker_seed)) as worker_pool:
         result_iter = worker_pool.imap_unordered(
             self.perform_method_pair_in_worker, operators)
         for result in result_iter:
             # print("Result:", result)
             destroy, repair, sol_result, res, obj_old, t_destroy, t_repair = result
             sol_new.copy_from(sol_result)
             self.update_stats_for_method_pair(destroy, repair, sol, res,
                                               obj_old, t_destroy, t_repair)
             self.update_after_destroy_and_repair_performed(
                 destroy, repair, sol_new, sol_incumbent, sol)
             if res.terminate:
                 sol.copy_from(sol_incumbent)
                 return
             self.update_operator_weights()
Example #6
0
    def vnd(self, sol: Solution) -> bool:
        """Perform variable neighborhood descent (VND) on given solution.

        :returns: true if a global termination condition is fulfilled, else False.
        """
        sol2 = sol.copy()
        while True:
            for m in self.next_method(self.meths_li):
                res = self.perform_method(m, sol2)
                if sol2.is_better(sol):
                    sol.copy_from(sol2)
                    if res.terminate:
                        return True
                    break
                if res.terminate:
                    return True
                if res.changed:
                    sol2.copy_from(sol)
            else:  # local optimum reached
                return False