Esempio n. 1
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
Esempio n. 2
0
 def copy_from(self, other: 'SubsetVectorSolution'):
     self.sel = other.sel
     if self.unselected_elems_in_x():
         super().copy_from(other)
     else:
         self.x[:self.sel] = other.x[:self.sel]
         Solution.copy_from(self, other)
Esempio n. 3
0
    def update_after_destroy_and_repair_performed(self, destroy: Method, repair: Method, sol_new: Solution,
                                                  sol_incumbent: Solution, sol: Solution):
        """Update current solution, incumbent, and all operator score data according to performed destroy+repair.

        :param destroy: applied destroy method
        :param repair: applied repair method
        :param sol_new: obtained new solution
        :param sol_incumbent: current incumbent solution
        :param sol: current (last accepted) solution
        """
        destroy_data = self.score_data[destroy.name]
        repair_data = self.score_data[repair.name]
        destroy_data.applied += 1
        repair_data.applied += 1
        score = 0
        if sol_new.is_better(sol_incumbent):
            score = self.own_settings.mh_alns_sigma1
            # print('better than incumbent')
            sol_incumbent.copy_from(sol_new)
            sol.copy_from(sol_new)
        elif sol_new.is_better(sol):
            score = self.own_settings.mh_alns_sigma2
            # print('better than current')
            sol.copy_from(sol_new)
        elif sol.is_better(sol_new) and self.metropolis_criterion(sol_new, sol):
            score = self.own_settings.mh_alns_sigma3
            # print('accepted although worse')
            sol.copy_from(sol_new)
        elif sol_new != sol:
            sol_new.copy_from(sol)
        destroy_data.score += score
        repair_data.score += score
Esempio n. 4
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()
Esempio n. 5
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
Esempio n. 6
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()