def main(): """Test for the DD classes.""" # import logging # from pymhlib.demos.common import data_dir parser = get_settings_parser() parser.add("--inst_file", type=str, default=data_dir + 'mknap-small.txt', help='problem instance file') # parser.set_defaults(seed=3) parse_settings() init_logger() logger = logging.getLogger("pymhlib") logger.info("pymhlib demo for using decision diagrams for the MKP") logger.info(get_settings_as_str()) instance = MKPInstance(settings.inst_file) logger.info("MKP instance read:\n%s", str(instance)) # solution = MKPSolution(instance) # solution.initialize(0) dd = MKPDecisionDiag(instance) dd.expand_all('relaxed') logger.info(dd) sol = dd.derive_solution() # sol.check() logger.info("Solution: %s, obj=%f", sol, sol.obj())
def add_general_arguments_and_parse_settings( default_inst_file: str = 'inst.dat', args=None, seed: int = 0): """Some general parameters are registered and the settings are parsed. :param seed: optional seed value for the random number generators; 0: random initialization :param default_inst_file: default instance file to be loaded and solved """ parser = get_settings_parser() parser.add_argument("--alg", type=str, default='gvns', help='optimization algorithm to be used ' '(gvns, alns, pbig, par_alns, ssga, sa)') parser.add_argument("--inst_file", type=str, default=default_inst_file, help='problem instance file') parser.add_argument("--meths_ch", type=int, default=1, help='number of construction heuristics to be used') parser.add_argument("--meths_li", type=int, default=1, help='number of local improvement methods to be used') parser.add_argument("--meths_sh", type=int, default=5, help='number of shaking methods to be used') parser.add_argument("--meths_de", type=int, default=3, help='number of destroy methods to be used') parser.add_argument("--meths_re", type=int, default=3, help='number of repair methods to be used') parse_settings(args=args, seed=seed)
"""A general variable neighborhood search class which can also be used for plain local search, VND, GRASP, IG etc. It extends the more general scheduler module/class by distinguishing between construction heuristics, local improvement methods and shaking methods. """ from typing import List import time from pymhlib.scheduler import Method, Scheduler from pymhlib.settings import get_settings_parser from pymhlib.solution import Solution parser = get_settings_parser() class GVNS(Scheduler): """A general variable neighborhood search (GVNS). Attributes - sol: solution object, in which final result will be returned - meths_ch: list of construction heuristic methods - meths_li: list of local improvement methods - meths_sh: list of shaking methods """ def __init__(self, sol: Solution, meths_ch: List[Method], meths_li: List[Method], meths_sh: List[Method], own_settings: dict = None,
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()