示例#1
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
示例#2
0
    def run(self):
        """Actually performs the construction heuristics followed by the SteadyStateGeneticAlgorithm."""

        population = self.population

        while True:
            # Create a new solution
            p1 = population[population.select()].copy()

            # Methods to perform in this iteration
            methods: List[Method] = []

            # Optionally crossover
            if random.random() < self.own_settings.mh_ssga_cross_prob:
                p2 = population[population.select()].copy()

                # Workaround for Method not allowing a second Solution as parameter
                def meth_cx(crossover, p2: Solution, p1: Solution, par: Any,
                            res: Result):
                    crossover(p1, p2)

                meth_cx_with_p2_bound = partial(meth_cx, self.meth_cx, p2)

                meth = Method("cx", meth_cx_with_p2_bound, None)
                methods.append(meth)

            # Mutation
            methods.append(self.meth_mu)

            # Optionally local search
            if self.meth_ls and random.random(
            ) < self.own_settings.mh_ssga_loc_prob:
                methods.append(self.meth_ls)

            res = self.perform_methods(methods, p1)

            if res.terminate:
                break

            # Replace in population
            worst = population.worst()
            population[worst].copy_from(p1)

            # Update best solution
            if p1.is_better(self.incumbent):
                self.incumbent = p1
示例#3
0
    def sa(self, sol: Solution):
        """Perform simulated annealing with geometric cooling on given solution."""
        def sa_iteration(sol: Solution, _par, result):
            neighborhood_move, delta_obj = self.random_move_delta_eval(sol)
            acceptance = self.metropolis_criterion(sol, delta_obj)
            if acceptance:
                self.apply_neighborhood_move(sol, neighborhood_move)
                sol.obj_val = sol.obj_val + delta_obj
                result.changed = True
            if self.iter_cb is not None:
                self.iter_cb(self.iteration, sol, self.temperature, acceptance)

        sa_method = Method("sa", sa_iteration, 0)

        while True:
            for _ in range(self.equi_iter):
                t_start = time.process_time()
                obj_old = self.incumbent.obj()
                res = self.perform_method(sa_method, sol, delayed_success=True)
                self.delayed_success_update(sa_method, obj_old, t_start, sol)
                if res.terminate:
                    return True
            self.cool_down()
示例#4
0
def run_optimization(problem_name: str,
                     instance_class,
                     solution_class,
                     default_inst_file: str = "inst.dat",
                     own_settings: dict = None,
                     embedded: bool = False,
                     iter_cb: Callable = None,
                     seed: int = 0) -> Solution:
    """Initialize and run optimization algorithm given by parameter alg on given problem instance.

    First, some general parameters for the algorithm to be applied, the instance file, and the methods to
    be applied are registered and the settings are parsed.
    Then the loggers are initialized, instance and solution objects are created and the chosen algorithm is
    performed. The resulting solution is finally returned.

    :param problem_name: name of the problem to be printed
    :param instance_class: class of the instance to be solved
    :param solution_class: concrete solution class to be used
    :param default_inst_file: default instance file to be loaded and solved
    :param own_settings: optional run-specific settings dictionary
    :param embedded: if set it is assumed that the call is embedded in a Notebook or other larger framework,
        and therefore, the parameters are assumed to be already registered and parsed
    :param iter_cb: optional callback function that is called each iteration by some of the algorithms
    :param seed: optional seed value for the random number generators; 0: random initialization
    """
    if not embedded:
        add_general_arguments_and_parse_settings(default_inst_file, seed=seed)

    init_logger()
    logger = logging.getLogger("pymhlib")
    logger.info("pymhlib demo for solving %s", problem_name)
    logger.info(get_settings_as_str())
    instance = instance_class(settings.inst_file)
    logger.info("%s instance read:\n%s", problem_name, str(instance))
    solution = solution_class(instance)
    # solution.initialize(0)

    logger.info("Solution: %s, obj=%f\n", solution, solution.obj())

    if settings.alg == 'gvns':
        alg = GVNS(solution, [
            Method(f"ch{i}", solution_class.construct, i)
            for i in range(settings.meths_ch)
        ], [
            Method(f"li{i}", solution_class.local_improve, i)
            for i in range(1, settings.meths_li + 1)
        ], [
            Method(f"sh{i}", solution_class.shaking, i)
            for i in range(1, settings.meths_sh + 1)
        ], own_settings)
    elif settings.alg == 'alns':
        alg = ALNS(solution, [
            Method(f"ch{i}", solution_class.construct, i)
            for i in range(settings.meths_ch)
        ], [
            Method(f"de{i}", solution_class.destroy, i)
            for i in range(1, settings.meths_de + 1)
        ], [
            Method(f"re{i}", solution_class.repair, i)
            for i in range(1, settings.meths_re + 1)
        ], own_settings)
    elif settings.alg == 'pbig':
        alg = PBIG(solution, [
            Method(f"ch{i}", solution_class.construct, i)
            for i in range(settings.meths_ch)
        ], [
            Method(f"li{i}", solution_class.local_improve, i)
            for i in range(1, settings.meths_li + 1)
        ] + [
            Method(f"sh{i}", solution_class.shaking, i)
            for i in range(1, settings.meths_sh + 1)
        ], own_settings)
    elif settings.alg == 'par_alns':
        alg = ParallelALNS(solution, [
            Method(f"ch{i}", solution_class.construct, i)
            for i in range(settings.meths_ch)
        ], [
            Method(f"de{i}", solution_class.destroy, i)
            for i in range(1, settings.meths_de + 1)
        ], [
            Method(f"re{i}", solution_class.repair, i)
            for i in range(1, settings.meths_re + 1)
        ], own_settings)
    elif settings.alg == 'ssga':
        alg = SteadyStateGeneticAlgorithm(
            solution, [
                Method("ch{i}", solution_class.construct, i)
                for i in range(settings.meths_ch)
            ], solution_class.crossover, Method("mu", solution_class.shaking,
                                                1),
            Method("ls", solution_class.local_improve, 1), own_settings)
    elif settings.alg == 'sa':
        alg = SA(solution, [
            Method(f"ch{i}", solution_class.construct, i)
            for i in range(settings.meths_ch)
        ], solution_class.random_move_delta_eval,
                 solution_class.apply_neighborhood_move, iter_cb, own_settings)
    else:
        raise ValueError(
            'Invalid optimization algorithm selected (settings.alg): ',
            settings.alg)

    alg.run()
    logger.info("")
    alg.method_statistics()
    alg.main_results()
    return solution
示例#5
0
def run_optimization(problem_name: str, Instance, Solution, default_inst_file: str, own_settings=None, embedded=False, iter_cb=None):
    """Run optimization algorithm given by parameter alg on given problem instance."""
    if not embedded:
        parser = get_settings_parser()
        parser.add("--alg", type=str, default='gvns', help='optimization algorithm to be used '
                                                           '(gvns, alns, parallel_alns, ssga)')
        parser.add("--inst_file", type=str, default=default_inst_file,
                   help='problem instance file')
        parser.add("--meths_ch", type=int, default=1,
                   help='number of construction heuristics to be used')
        parser.add("--meths_li", type=int, default=1,
                   help='number of local improvement methods to be used')
        parser.add("--meths_sh", type=int, default=5,
                   help='number of shaking methods to be used')
        parser.add("--meths_de", type=int, default=3,
                   help='number of destroy methods to be used')
        parser.add("--meths_re", type=int, default=3,
                   help='number of repair methods to be used')
        # parser.set_defaults(seed=3)
        parse_settings()

    init_logger()
    logger = logging.getLogger("pymhlib")
    logger.info(f"pymhlib demo for solving {problem_name}")
    logger.info(get_settings_as_str())
    instance = Instance(settings.inst_file)
    logger.info(f"{problem_name} instance read:\n" + str(instance))
    solution = Solution(instance)
    # solution.initialize(0)

    logger.info(f"Solution: {solution}, obj={solution.obj()}\n")

    if settings.alg == 'gvns':
        alg = GVNS(solution,
                   [Method(f"ch{i}", Solution.construct, i) for i in range(settings.meths_ch)],
                   [Method(f"li{i}", Solution.local_improve, i) for i in range(1, settings.meths_li + 1)],
                   [Method(f"sh{i}", Solution.shaking, i) for i in range(1, settings.meths_sh + 1)],
                   own_settings)
    elif settings.alg == 'alns':
        alg = ALNS(solution,
                   [Method(f"ch{i}", Solution.construct, i) for i in range(settings.meths_ch)],
                   [Method(f"de{i}", Solution.destroy, i) for i in range(1, settings.meths_de + 1)],
                   [Method(f"re{i}", Solution.repair, i) for i in range(1, settings.meths_re + 1)],
                   own_settings)
    elif settings.alg == 'pbig':
        alg = PBIG(solution,
                   [Method(f"ch{i}", Solution.construct, i) for i in range(settings.meths_ch)],
                   [Method(f"li{i}", Solution.local_improve, i) for i in range(1, settings.meths_li + 1)] +
                   [Method(f"sh{i}", Solution.shaking, i) for i in range(1, settings.meths_sh + 1)],
                   own_settings)
    elif settings.alg == 'par_alns':
        alg = ParallelALNS(solution,
                           [Method(f"ch{i}", Solution.construct, i) for i in range(settings.meths_ch)],
                           [Method(f"de{i}", Solution.destroy, i) for i in range(1, settings.meths_de + 1)],
                           [Method(f"re{i}", Solution.repair, i) for i in range(1, settings.meths_re + 1)],
                           own_settings)
    elif settings.alg == 'ssga':
        alg = SteadyStateGeneticAlgorithm(solution,
                                          [Method(f"ch{i}", Solution.construct, i) for i in range(settings.meths_ch)],
                                          Solution.crossover,
                                          Method(f"mu", Solution.shaking, 1),
                                          Method(f"ls", Solution.local_improve, 1),
                                          own_settings)
    elif settings.alg == 'sa':
        alg = SA(solution,
                 [Method(f"ch{i}", Solution.construct, i) for i in range(settings.meths_ch)],
                 Solution.random_move_delta_eval, Solution.apply_neighborhood_move, iter_cb, own_settings)
    else:
        raise ValueError('Invalid optimization algorithm selected (settings.alg): ', settings.alg)

    alg.run()
    logger.info("")
    alg.method_statistics()
    alg.main_results()
示例#6
0
 def get_method(self, opt: Option, par=None):
     param = par if par != None else self.value
     if self.callback == None:
         return None
     return Method(f'{opt.name.lower()}{param if param != None else ""}',
                   self.callback, param)