Example #1
0
    def test_generate_chromosome(self):
        """
        Tests generate_chromosome() method.
        """

        param_values = deepcopy(self.default_param_values)
        brkga = BrkgaMpIpr(**param_values)

        local_rng = Random(param_values["seed"])
        # Same warm up that the one in the constructor.
        for _ in range(1000):
            local_rng.random()
        self.assertEqual(brkga._rng.getstate(), local_rng.getstate())

        size = param_values["chromosome_size"]
        standard = BaseChromosome([local_rng.random() for _ in range(size)])
        new_chr = brkga.generate_chromosome(size)
        self.assertEqual(len(new_chr), size)
        self.assertEqual(new_chr, standard)

        size = 1000
        standard = BaseChromosome([local_rng.random() for _ in range(size)])
        new_chr = brkga.generate_chromosome(size)
        self.assertEqual(len(new_chr), size)
        self.assertEqual(new_chr, standard)
Example #2
0
    def test_exchange_elite(self):
        """
        Tests exchange_elite() method.
        """

        param_values = deepcopy(self.default_param_values)
        brkga = BrkgaMpIpr(**param_values)
        self.assertRaises(NotImplementedError, brkga.exchange_elite, 0)
Example #3
0
    def test__direct_path_relink(self):
        """
        Tests _direct_path_relink() method.
        """

        param_values = deepcopy(self.default_param_values)
        brkga = BrkgaMpIpr(**param_values)
        self.assertRaises(NotImplementedError, brkga._direct_path_relink, None,
                          None, None, None, 0, 0, 0.0)
Example #4
0
    def test_shake(self):
        """
        Tests shake() method.
        """

        param_values = deepcopy(self.default_param_values)
        brkga = BrkgaMpIpr(**param_values)
        self.assertRaises(NotImplementedError, brkga.shake, 0,
                          ShakingType.SWAP, 0)
Example #5
0
    def test_inject_chromosome(self):
        """
        Tests inject_chromosome() method.
        """

        param_values = deepcopy(self.default_param_values)
        brkga = BrkgaMpIpr(**param_values)
        self.assertRaises(NotImplementedError, brkga.inject_chromosome,
                          BaseChromosome(), 0, 0, 0)
Example #6
0
    def test_fill_chromosome(self):
        """
        Tests fill_chromosome() method.
        """

        param_values = deepcopy(self.default_param_values)
        brkga = BrkgaMpIpr(**param_values)

        local_rng = Random(param_values["seed"])
        # Same warm up that the one in the constructor.
        for _ in range(1000):
            local_rng.random()
        self.assertEqual(brkga._rng.getstate(), local_rng.getstate())

        size = param_values["chromosome_size"]
        chromosome = BaseChromosome([0.0 for _ in range(size)])
        old_chrmosome = deepcopy(chromosome)

        brkga.fill_chromosome(chromosome)

        local_chr = BaseChromosome([local_rng.random() for _ in range(size)])
        self.assertEqual(len(chromosome), len(old_chrmosome))
        self.assertNotEqual(chromosome, old_chrmosome)
        self.assertEqual(chromosome, local_chr)

        size = 1000
        chromosome = BaseChromosome([0.0 for _ in range(size)])
        old_chrmosome = deepcopy(chromosome)

        brkga.fill_chromosome(chromosome)

        local_chr = BaseChromosome([local_rng.random() for _ in range(size)])
        self.assertEqual(len(chromosome), len(old_chrmosome))
        self.assertNotEqual(chromosome, old_chrmosome)
        self.assertEqual(chromosome, local_chr)
def main() -> None:
    if len(sys.argv) < 4:
        print("Usage: python main_minimal.py <seed> <config-file> "
              "<num-generations> <tsp-instance-file>")
        sys.exit(1)

    ########################################
    # Read the command-line arguments and the instance
    ########################################

    seed = int(sys.argv[1])
    configuration_file = sys.argv[2]
    num_generations = int(sys.argv[3])
    instance_file = sys.argv[4]

    print("Reading data...")
    instance = TSPInstance(instance_file)

    ########################################
    # Read algorithm parameters
    ########################################

    print("Reading parameters...")
    brkga_params, _ = load_configuration(configuration_file)

    ########################################
    # Build the BRKGA data structures and initialize
    ########################################

    print("Building BRKGA data and initializing...")

    decoder = TSPDecoder(instance)

    brkga = BrkgaMpIpr(decoder=decoder,
                       sense=Sense.MINIMIZE,
                       seed=seed,
                       chromosome_size=instance.num_nodes,
                       params=brkga_params)

    # NOTE: don't forget to initialize the algorithm.
    brkga.initialize()

    ########################################
    # Find good solutions / evolve
    ########################################

    print(f"Evolving {num_generations} generations...")
    brkga.evolve(num_generations)

    best_cost = brkga.get_best_fitness()
    print(f"Best cost: {best_cost}")
Example #8
0
    def test_reset(self):
        """
        Tests reset() method.
        """

        param_values = deepcopy(self.default_param_values)
        params = param_values["params"]
        brkga = BrkgaMpIpr(**param_values)

        with self.assertRaises(RuntimeError) as context:
            brkga.reset()
        self.assertEqual(str(context.exception).strip(),
                         "The algorithm hasn't been initialized. "
                         "Call 'initialize()' before 'reset()'")

        brkga.initialize()

        # Create a local RNG and advance it until the same state as the
        # internal BRKGA RNG after initialization.
        local_rng = Random(param_values["seed"])
        skip = 1000 + params.num_independent_populations * \
               params.population_size * brkga.chromosome_size
        for _ in range(skip):
            local_rng.random()

        # Assert the both generators are in the same state.
        self.assertEqual(brkga._rng.getstate(), local_rng.getstate())

        # Create a local chromosome and applied the decoder on it.
        local_chr = BaseChromosome([
            local_rng.random() for _ in range(param_values["chromosome_size"])
        ])
        param_values["decoder"].decode(local_chr, rewrite=True)

        # Reset and test the first individual.
        brkga.reset()
        self.assertEqual(brkga._current_populations[0].chromosomes[0],
                         local_chr)

        # After reset, the reset phase flag should be deactivated.
        self.assertFalse(brkga._reset_phase)
    def test_get_best_fitness(self):
        """
        Tests get_best_fitness() method.
        """

        param_values = deepcopy(self.default_param_values)
        param_values["sense"] = Sense.MAXIMIZE
        param_values["seed"] = 12323
        param_values["chromosome_size"] = self.chromosome_size
        param_values["params"].population_size = 500
        param_values["params"].num_independent_populations = 3

        params = param_values["params"]
        brkga = BrkgaMpIpr(**param_values)

        # Not initialized
        with self.assertRaises(RuntimeError) as context:
            brkga.get_best_fitness()
        self.assertEqual(str(context.exception).strip(),
                         "The algorithm hasn't been initialized. "
                         "Call 'initialize()' before 'get_best_fitness()'")

        brkga.initialize()

        ########################
        # Test for maximization
        ########################

        local_rng = Random(param_values["seed"])
        for _ in range(1000):
            local_rng.random()

        num_individuals = params.population_size * \
                          params.num_independent_populations

        best_value = -math.inf
        for _ in range(num_individuals):
            local_chr = BaseChromosome([
                local_rng.random() for _ in range(param_values["chromosome_size"])
            ])
            best_value = max(
                best_value, self.sum_decoder.decode(local_chr, True)
            )

        # Assert the both generators are in the same state.
        self.assertEqual(brkga._rng.getstate(), local_rng.getstate())

        # Test the actual value.
        self.assertAlmostEqual(brkga.get_best_fitness(), best_value)

        ########################
        # Test for minimization
        ########################

        param_values["sense"] = Sense.MINIMIZE
        brkga = BrkgaMpIpr(**param_values)
        brkga.initialize()

        local_rng = Random(param_values["seed"])
        for _ in range(1000):
            local_rng.random()

        num_individuals = params.population_size * \
                          params.num_independent_populations

        best_value = math.inf
        for _ in range(num_individuals):
            local_chr = BaseChromosome([
                local_rng.random() for _ in range(param_values["chromosome_size"])
            ])
            best_value = min(
                best_value, self.sum_decoder.decode(local_chr, True)
            )

        # Assert the both generators are in the same state.
        self.assertEqual(brkga._rng.getstate(), local_rng.getstate())

        # Test the actual value.
        self.assertAlmostEqual(brkga.get_best_fitness(), best_value)
    def test_get_current_population(self):
        """
        Tests get_current_population() method.
        """

        param_values = deepcopy(self.default_param_values)
        param_values["params"].num_independent_populations = 3
        params = param_values["params"]
        brkga = BrkgaMpIpr(**param_values)

        # Not initialized
        with self.assertRaises(RuntimeError) as context:
            brkga.get_current_population()
        self.assertEqual(str(context.exception).strip(),
                         "The algorithm hasn't been initialized. "
                         "Call 'initialize()' before 'get_current_population()'")

        brkga.initialize()

         # Test invalid population indices.
        population_index = -1
        with self.assertRaises(ValueError) as context:
            brkga.get_current_population(population_index)
        self.assertEqual(str(context.exception).strip(),
                         "Population must be in [0, 2]: -1")

        population_index = brkga.params.num_independent_populations
        with self.assertRaises(ValueError) as context:
            brkga.get_current_population(population_index)
        self.assertEqual(str(context.exception).strip(),
                         "Population must be in [0, 2]: 3")

        # Test if it is returning the right population.
        for i in range(params.num_independent_populations):
            self.assertIs(brkga.get_current_population(i),
                          brkga._current_populations[i])
    def test_get_chromosome(self):
        """
        Tests get_chromosome() method.
        """

        param_values = deepcopy(self.default_param_values)
        param_values["params"].num_independent_populations = 3
        params = param_values["params"]
        brkga = BrkgaMpIpr(**param_values)

        # Not initialized
        with self.assertRaises(RuntimeError) as context:
            brkga.get_chromosome(0, 0)
        self.assertEqual(str(context.exception).strip(),
                         "The algorithm hasn't been initialized. "
                         "Call 'initialize()' before 'get_chromosome()'")

        brkga.initialize()

        # Test invalid population indices.
        population_index = -1
        position = 0
        with self.assertRaises(ValueError) as context:
            brkga.get_chromosome(population_index, position)
        self.assertEqual(str(context.exception).strip(),
                         "Population must be in [0, 2]: -1")

        population_index = brkga.params.num_independent_populations
        position = 0
        with self.assertRaises(ValueError) as context:
            brkga.get_chromosome(population_index, position)
        self.assertEqual(str(context.exception).strip(),
                         "Population must be in [0, 2]: 3")

        # Test invalid chrmosome indices.
        population_index = 0
        position = -1
        with self.assertRaises(ValueError) as context:
            brkga.get_chromosome(population_index, position)
        self.assertEqual(str(context.exception).strip(),
                         "Chromosome position must be in [0, 9]: -1")

        population_index = 0
        position = brkga.params.population_size
        with self.assertRaises(ValueError) as context:
            brkga.get_chromosome(population_index, position)
        self.assertEqual(str(context.exception).strip(),
                         "Chromosome position must be in [0, 9]: 10")

        # Test if the chromosome matches.

        # Create a local RNG and advance it until the same state as the
        # internal BRKGA RNG after initialization.
        local_rng = Random(param_values["seed"])
        skip = 1000
        for _ in range(skip):
            local_rng.random()

        # Now, we create the populations, decode them, and sort the
        # individuals according to their fitness, reproducing initialize()
        # basically.
        local_populations = []
        for _ in range(brkga.params.num_independent_populations):
            population = []
            for _ in range(brkga.params.population_size):
                local_chr = BaseChromosome([
                    local_rng.random() for _ in range(param_values["chromosome_size"])
                ])

                fitness = brkga._decoder.decode(local_chr, True)
                population.append((fitness, local_chr))
            # end for
            population.sort(reverse=(brkga.opt_sense == Sense.MAXIMIZE))
            local_populations.append(population)
        # end for

        # Assert the both generators are in the same state.
        self.assertEqual(brkga._rng.getstate(), local_rng.getstate())

        population_index = 0
        position = 0
        copy_chr = brkga.get_chromosome(population_index, position)
        self.assertEqual(copy_chr, local_populations[population_index][position][1])
        self.assertIsNot(copy_chr, local_populations[population_index][position][1])

        population_index = 1
        position = 1
        copy_chr = brkga.get_chromosome(population_index, position)
        self.assertEqual(copy_chr, local_populations[population_index][position][1])
        self.assertIsNot(copy_chr, local_populations[population_index][position][1])

        population_index = brkga.params.num_independent_populations - 1
        position = brkga.params.population_size - 1
        copy_chr = brkga.get_chromosome(population_index, position)
        self.assertEqual(copy_chr, local_populations[population_index][position][1])
        self.assertIsNot(copy_chr, local_populations[population_index][position][1])
Example #12
0
def main() -> None:
    """
    Proceeds with the optimization. Create to avoid spread `global` keywords
    around the code.
    """

    args = docopt.docopt(__doc__)
    # print(args)

    configuration_file = args["--config_file"]
    instance_file = args["--instance_file"]
    seed = int(args["--seed"])
    stop_rule = StopRule(args["--stop_rule"])

    if stop_rule == StopRule.TARGET:
        stop_argument = float(args["--stop_arg"])
    else:
        stop_argument = int(args["--stop_arg"])

    maximum_time = float(args["--max_time"])

    if maximum_time <= 0.0:
        raise RuntimeError(f"Maximum time must be larger than 0.0. "
                           f"Given {maximum_time}.")

    perform_evolution = not args["--no_evolution"]

    ########################################
    # Load config file and show basic info.
    ########################################

    brkga_params, control_params = load_configuration(configuration_file)

    print(f"""------------------------------------------------------
> Experiment started at {datetime.now()}
> Instance: {instance_file}
> Configuration: {configuration_file}
> Algorithm Parameters:""",
          end="")

    if not perform_evolution:
        print(">    - Simple multi-start: on (no evolutionary operators)")
    else:
        output_string = ""
        for name, value in vars(brkga_params).items():
            output_string += f"\n>  -{name} {value}"
        for name, value in vars(control_params).items():
            output_string += f"\n>  -{name} {value}"

        print(output_string)
        print(f"""> Seed: {seed}
> Stop rule: {stop_rule}
> Stop argument: {stop_argument}
> Maximum time (s): {maximum_time}
------------------------------------------------------""")

    ########################################
    # Load instance and adjust BRKGA parameters
    ########################################

    print(f"\n[{datetime.now()}] Reading TSP data...")

    instance = TSPInstance(instance_file)
    print(f"Number of nodes: {instance.num_nodes}")

    print(f"\n[{datetime.now()}] Generating initial tour...")

    # Generate a greedy solution to be used as warm start for BRKGA.
    initial_cost, initial_tour = greedy_tour(instance)
    print(f"Initial cost: {initial_cost}")

    ########################################
    # Build the BRKGA data structures and initialize
    ########################################

    print(f"\n[{datetime.now()}] Building BRKGA data...")

    # Usually, it is a good idea to set the population size
    # proportional to the instance size.
    brkga_params.population_size = min(brkga_params.population_size,
                                       10 * instance.num_nodes)
    print(f"New population size: {brkga_params.population_size}")

    # Build a decoder object.
    decoder = TSPDecoder(instance)

    # Chromosome size is the number of nodes.
    # Each chromosome represents a permutation of nodes.
    brkga = BrkgaMpIpr(decoder=decoder,
                       sense=Sense.MINIMIZE,
                       seed=seed,
                       chromosome_size=instance.num_nodes,
                       params=brkga_params,
                       evolutionary_mechanism_on=perform_evolution)

    # To inject the initial tour, we need to create chromosome representing
    # that solution. First, we create a set of keys to be used in the
    # chromosome.
    random.seed(seed)
    keys = sorted([random.random() for _ in range(instance.num_nodes)])

    # Then, we visit each node in the tour and assign to it a key.
    initial_chromosome = [0] * instance.num_nodes
    for i in range(instance.num_nodes):
        initial_chromosome[initial_tour[i]] = keys[i]

    # Inject the warm start solution in the initial population.
    brkga.set_initial_population([initial_chromosome])

    # NOTE: don't forget to initialize the algorithm.
    print(f"\n[{datetime.now()}] Initializing BRKGA data...")
    brkga.initialize()

    ########################################
    # Warm up the script/code
    ########################################

    # To make sure we are timing the runs correctly, we run some warmup
    # iterations with bogus data. Warmup is always recommended for script
    # languages. Here, we call the most used methods.
    print(f"\n[{datetime.now()}] Warming up...")

    bogus_alg = deepcopy(brkga)
    bogus_alg.evolve(2)
    # TODO (ceandrade): warm up path relink functions.
    # bogus_alg.path_relink(brkga_params.pr_type, brkga_params.pr_selection,
    #              (x, y) -> 1.0, (x, y) -> true, 0, 0.5, 1, 10.0, 1.0)
    bogus_alg.get_best_fitness()
    bogus_alg.get_best_chromosome()
    bogus_alg = None

    ########################################
    # Evolving
    ########################################

    print(f"\n[{datetime.now()}] Evolving...")
    print("* Iteration | Cost | CurrentTime")

    best_cost = initial_cost * 2
    best_chromosome = initial_chromosome

    iteration = 0
    last_update_time = 0.0
    last_update_iteration = 0
    large_offset = 0
    # TODO (ceandrade): enable the following when path relink is ready.
    # path_relink_time = 0.0
    # num_path_relink_calls = 0
    # num_homogenities = 0
    # num_best_improvements = 0
    # num_elite_improvements = 0
    run = True

    # Main optimization loop. We evolve one generation at time,
    # keeping track of all changes during such process.
    start_time = time.time()
    while run:
        iteration += 1

        # Evolves one iteration.
        brkga.evolve()

        # Checks the current results and holds the best.
        fitness = brkga.get_best_fitness()
        if fitness < best_cost:
            last_update_time = time.time() - start_time
            update_offset = iteration - last_update_iteration

            if large_offset < update_offset:
                large_offset = update_offset

            last_update_iteration = iteration
            best_cost = fitness
            best_chromosome = brkga.get_best_chromosome()

            print(f"* {iteration} | {best_cost:.0f} | {last_update_time:.2f}")
        # end if

        # TODO (ceandrade): implement path relink calls here.
        # Please, see Julia version for that.

        iter_without_improvement = iteration - last_update_iteration

        # Check stop criteria.
        run = not (
            (time.time() - start_time > maximum_time) or
            (stop_rule == StopRule.GENERATIONS and iteration == stop_argument)
            or (stop_rule == StopRule.IMPROVEMENT
                and iter_without_improvement >= stop_argument) or
            (stop_rule == StopRule.TARGET and best_cost <= stop_argument))
    # end while
    total_elapsed_time = time.time() - start_time
    total_num_iterations = iteration

    print(f"[{datetime.now()}] End of optimization\n")

    print(f"Total number of iterations: {total_num_iterations}")
    print(f"Last update iteration: {last_update_iteration}")
    print(f"Total optimization time: {total_elapsed_time:.2f}")
    print(f"Last update time: {last_update_time:.2f}")
    print(f"Large number of iterations between improvements: {large_offset}")

    # TODO (ceandrade): enable when path relink is ready.
    # print(f"\nTotal path relink time: {path_relink_time:.2f}")
    # print(f"\nTotal path relink calls: {num_path_relink_calls}")
    # print(f"\nNumber of homogenities: {num_homogenities}")
    # print(f"\nImprovements in the elite set: {num_elite_improvements}")
    # print(f"\nBest individual improvements: {num_best_improvements}")

    ########################################
    # Extracting the best tour
    ########################################

    tour = []
    for (index, key) in enumerate(best_chromosome):
        tour.append((key, index))
    tour.sort()

    print(f"\n% Best tour cost: {best_cost:.2f}")
    print("% Best tour: ", end="")
    for _, node in tour:
        print(node, end=" ")

    print(
        "\n\nInstance,Seed,NumNodes,TotalIterations,TotalTime,"
        #"TotalPRTime,PRCalls,NumHomogenities,NumPRImprovElite,"
        #"NumPrImprovBest,"
        "LargeOffset,LastUpdateIteration,LastUpdateTime,"
        "Cost")

    print(
        f"{basename(instance_file)},"
        f"{seed},{instance.num_nodes},{total_num_iterations},"
        f"{total_elapsed_time:.2f},"
        # f"{path_relink_time:.2f},{num_path_relink_calls},"
        # f"{num_homogenities},{num_elite_improvements},{num_best_improvements},"
        f"{large_offset},{last_update_iteration},"
        f"{last_update_time:.2f},{best_cost:.0f}")
def gen_conf1():
    param_values = deepcopy(default_param_values)
    brkga_params = param_values["params"]

    brkga_params.population_size = 100
    brkga_params.elite_percentage = 0.3
    brkga_params.mutants_percentage = 0.1
    brkga_params.num_elite_parents = 1
    brkga_params.total_parents = 2
    brkga_params.bias_type = BiasFunctionType.LOGINVERSE
    brkga_params.num_independent_populations = 1
    brkga_params.pr_number_pairs = 0
    brkga_params.pr_minimum_distance = 0.0
    brkga_params.pr_type = PathRelinkingType.DIRECT
    brkga_params.pr_selection = PathRelinkingSelection.BESTSOLUTION
    brkga_params.alpha_block_size = 1.0
    brkga_params.pr_percentage = 1.0

    param_values["decoder"] = sum_decoder
    param_values["sense"] = Sense.MAXIMIZE
    param_values["seed"] = 4013750229
    param_values["chromosome_size"] = chromosome_size
    param_values["evolutionary_mechanism_on"] = True

    print("\n> Building configuration 1")
    brkga = BrkgaMpIpr(**param_values)
    brkga.initialize()

    print("> Writing configuration 1")
    with open(os.path.join(STATE_DIR, "state1.pickle"), "wb") as hd:
        pickle.dump(brkga, hd)

    print("> Evolving population 0")

    brkga.evolve_population(0)
    fitness1 = brkga.get_best_fitness()
    chromosome1 = brkga.get_best_chromosome()

    brkga.evolve_population(0)
    fitness2 = brkga.get_best_fitness()
    chromosome2 = brkga.get_best_chromosome()

    for _ in range(100):
        brkga.evolve_population(0)
    fitness102 = brkga.get_best_fitness()
    chromosome102 = brkga.get_best_chromosome()

    with open(os.path.join(SOLUTION_DIR, "best_solution1.pickle"), "wb") as hd:
        pickle.dump(
            {
                "fitness1": fitness1,
                "chromosome1": chromosome1,
                "fitness2": fitness2,
                "chromosome2": chromosome2,
                "fitness102": fitness102,
                "chromosome102": chromosome102,
            },
            hd
        )
def gen_conf5():
    param_values = deepcopy(default_param_values)
    brkga_params = param_values["params"]

    chromosome_size = 100
    instance = Instance(chromosome_size)

    brkga_params.population_size = 100
    brkga_params.elite_percentage = 0.30
    brkga_params.mutants_percentage = 0.20
    brkga_params.num_elite_parents = 2
    brkga_params.total_parents = 3
    brkga_params.bias_type = BiasFunctionType.LOGINVERSE
    brkga_params.num_independent_populations = 3
    brkga_params.pr_number_pairs = 0
    brkga_params.pr_minimum_distance = 0.0
    brkga_params.pr_type = PathRelinkingType.DIRECT
    brkga_params.pr_selection = PathRelinkingSelection.BESTSOLUTION
    brkga_params.alpha_block_size = 1.0
    brkga_params.pr_percentage = 1.0

    param_values["decoder"] = SumDecode(instance)
    param_values["sense"] = Sense.MINIMIZE
    param_values["seed"] = 4659930950303
    param_values["chromosome_size"] = chromosome_size
    param_values["evolutionary_mechanism_on"] = True

    print("\n> Building configuration 5")
    brkga = BrkgaMpIpr(**param_values)
    brkga.initialize()

    print("> Writing configuration 5")
    with open(os.path.join(STATE_DIR, "state5.pickle"), "wb") as hd:
        pickle.dump(brkga, hd)

    print("> Evolving one generation...")
    brkga.evolve()
    fitness1 = brkga.get_best_fitness()
    chromosome1 = brkga.get_best_chromosome()

    print("> Evolving 10 generations...")
    brkga.evolve(10)
    fitness10 = brkga.get_best_fitness()
    chromosome10 = brkga.get_best_chromosome()

    print("> Evolving 100 generations...")
    brkga.evolve(100)
    fitness100 = brkga.get_best_fitness()
    chromosome100 = brkga.get_best_chromosome()

    with open(os.path.join(SOLUTION_DIR, "best_solution5.pickle"), "wb") as hd:
        pickle.dump(
            {
                "fitness1": fitness1,
                "chromosome1": chromosome1,
                "fitness10": fitness10,
                "chromosome10": chromosome10,
                "fitness100": fitness100,
                "chromosome100": chromosome100
            },
            hd
        )

    print("fitness", fitness1)
    print("fitness", fitness10)
    print("fitness", fitness100)
def gen_conf4():
    param_values = deepcopy(default_param_values)
    brkga_params = param_values["params"]

    chromosome_size = 500
    instance = Instance(chromosome_size)

    brkga_params.population_size = 100
    brkga_params.elite_percentage = 0.35
    brkga_params.mutants_percentage = 0.15
    brkga_params.num_elite_parents = 1
    brkga_params.total_parents = 2
    brkga_params.bias_type = BiasFunctionType.EXPONENTIAL
    brkga_params.num_independent_populations = 3
    brkga_params.pr_number_pairs = 0
    brkga_params.pr_minimum_distance = 0.0
    brkga_params.pr_type = PathRelinkingType.DIRECT
    brkga_params.pr_selection = PathRelinkingSelection.BESTSOLUTION
    brkga_params.alpha_block_size = 1.0
    brkga_params.pr_percentage = 1.0

    param_values["decoder"] = SumDecode(instance)
    param_values["sense"] = Sense.MINIMIZE
    param_values["seed"] = 2947804214761
    param_values["chromosome_size"] = chromosome_size
    param_values["evolutionary_mechanism_on"] = True

    print("\n> Building configuration 4")
    brkga = BrkgaMpIpr(**param_values)
    brkga.initialize()

    rho = 0.75
    brkga.set_bias_custom_function(lambda x: rho if x == 1 else 1.0 - rho)

    print("> Writing configuration 4")
    with open(os.path.join(STATE_DIR, "state4.pickle"), "wb") as hd:
        pickle.dump(brkga, hd)

    print("> Evolving population 0...")
    brkga.evolve_population(0)
    fitness1 = brkga.get_best_fitness()
    chromosome1 = brkga.get_best_chromosome()

    print("> Evolving population 1...")
    brkga.evolve_population(1)
    fitness2 = brkga.get_best_fitness()
    chromosome2 = brkga.get_best_chromosome()

    print("> Evolving population 2...")
    brkga.evolve_population(2)
    fitness3 = brkga.get_best_fitness()
    chromosome3 = brkga.get_best_chromosome()

    print("> Evolving both populations for 100 generations...")
    for _ in range(100):
        start_time = time()
        brkga.evolve_population(0)
        brkga.evolve_population(1)
        brkga.evolve_population(2)
        print(f"Elapsed time: {time() - start_time :.2f}")

    fitness103 = brkga.get_best_fitness()
    chromosome103 = brkga.get_best_chromosome()

    with open(os.path.join(SOLUTION_DIR, "best_solution4.pickle"), "wb") as hd:
        pickle.dump(
            {
                "fitness1": fitness1,
                "chromosome1": chromosome1,
                "fitness2": fitness2,
                "chromosome2": chromosome2,
                "fitness3": fitness2,
                "chromosome3": chromosome2,
                "fitness103": fitness103,
                "chromosome103": chromosome103,
            },
            hd
        )
def gen_conf3():
    param_values = deepcopy(default_param_values)
    brkga_params = param_values["params"]

    chromosome_size = 500
    instance = Instance(chromosome_size)

    brkga_params.population_size = 100
    brkga_params.elite_percentage = 0.35
    brkga_params.mutants_percentage = 0.17
    brkga_params.num_elite_parents = 3
    brkga_params.total_parents = 5
    brkga_params.bias_type = BiasFunctionType.EXPONENTIAL
    brkga_params.num_independent_populations = 5
    brkga_params.pr_number_pairs = 0
    brkga_params.pr_minimum_distance = 0.0
    brkga_params.pr_type = PathRelinkingType.DIRECT
    brkga_params.pr_selection = PathRelinkingSelection.BESTSOLUTION
    brkga_params.alpha_block_size = 1.0
    brkga_params.pr_percentage = 1.0

    param_values["decoder"] = SumDecode(instance)
    param_values["sense"] = Sense.MINIMIZE
    param_values["seed"] = 253624607406
    param_values["chromosome_size"] = chromosome_size
    param_values["evolutionary_mechanism_on"] = True

    print("\n> Building configuration 3")
    brkga = BrkgaMpIpr(**param_values)
    brkga.initialize()

    print("> Writing configuration 3")
    with open(os.path.join(STATE_DIR, "state3.pickle"), "wb") as hd:
        pickle.dump(brkga, hd)

    print("> Evolving both populations for one generation...")
    for i in range(brkga_params.num_independent_populations):
        brkga.evolve_population(i)
    fitness1 = brkga.get_best_fitness()
    chromosome1 = brkga.get_best_chromosome()

    print("> Evolving both populations for another generation...")
    for i in range(brkga_params.num_independent_populations):
        brkga.evolve_population(i)
    brkga.evolve_population(1)
    fitness2 = brkga.get_best_fitness()
    chromosome2 = brkga.get_best_chromosome()

    print("> Evolving both populations for 100 generations...")
    for _ in range(100):
        start_time = time()
        for i in range(brkga_params.num_independent_populations):
            brkga.evolve_population(i)
        print(f"Elapsed time: {time() - start_time :.2f}")

    fitness102 = brkga.get_best_fitness()
    chromosome102 = brkga.get_best_chromosome()

    with open(os.path.join(SOLUTION_DIR, "best_solution3.pickle"), "wb") as hd:
        pickle.dump(
            {
                "fitness1": fitness1,
                "chromosome1": chromosome1,
                "fitness2": fitness2,
                "chromosome2": chromosome2,
                "fitness102": fitness102,
                "chromosome102": chromosome102,
            },
            hd
        )

    print("fitness", fitness1)
    # print("chromosome", chromosome1)

    print("fitness", fitness2)
    # print("chromosome", chromosome2)

    print("fitness", fitness102)
def gen_conf2():
    param_values = deepcopy(default_param_values)
    brkga_params = param_values["params"]

    chromosome_size = 1000
    instance = Instance(chromosome_size)

    brkga_params.population_size = 500
    brkga_params.elite_percentage = 0.25
    brkga_params.mutants_percentage = 0.25
    brkga_params.num_elite_parents = 5
    brkga_params.total_parents = 50
    brkga_params.bias_type = BiasFunctionType.QUADRATIC
    brkga_params.num_independent_populations = 2
    brkga_params.pr_number_pairs = 0
    brkga_params.pr_minimum_distance = 0.0
    brkga_params.pr_type = PathRelinkingType.DIRECT
    brkga_params.pr_selection = PathRelinkingSelection.BESTSOLUTION
    brkga_params.alpha_block_size = 1.0
    brkga_params.pr_percentage = 1.0

    param_values["decoder"] = RankDecode(instance)
    param_values["sense"] = Sense.MINIMIZE
    param_values["seed"] = 1297832326904308
    param_values["chromosome_size"] = chromosome_size
    param_values["evolutionary_mechanism_on"] = True

    print("\n> Building configuration 2")
    brkga = BrkgaMpIpr(**param_values)
    brkga.initialize()

    print("> Writing configuration 2")
    with open(os.path.join(STATE_DIR, "state2.pickle"), "wb") as hd:
        pickle.dump(brkga, hd)

    print("> Evolving population 0...")
    brkga.evolve_population(0)
    fitness1 = brkga.get_best_fitness()
    chromosome1 = brkga.get_best_chromosome()

    print("> Evolving population 1...")
    brkga.evolve_population(1)
    fitness2 = brkga.get_best_fitness()
    chromosome2 = brkga.get_best_chromosome()

    print("> Evolving both populations for 100 generations...")
    for _ in range(100):
        start_time = time()
        brkga.evolve_population(0)
        brkga.evolve_population(1)
        print(f"Elapsed time: {time() - start_time :.2f}")

    fitness102 = brkga.get_best_fitness()
    chromosome102 = brkga.get_best_chromosome()

    with open(os.path.join(SOLUTION_DIR, "best_solution2.pickle"), "wb") as hd:
        pickle.dump(
            {
                "fitness1": fitness1,
                "chromosome1": chromosome1,
                "fitness2": fitness2,
                "chromosome2": chromosome2,
                "fitness102": fitness102,
                "chromosome102": chromosome102,
            },
            hd
        )
Example #18
0
    def test_set_initial_population(self):
        """
        Tests set_initial_population() method.
        """

        param_values = deepcopy(self.default_param_values)
        param_values["chromosome_size"] = 3
        param_values["params"].num_independent_populations = 2
        brkga = BrkgaMpIpr(**param_values)

        local_rng = Random(param_values["seed"])

        chromosomes = [
            BaseChromosome() for _ in range(brkga.params.population_size + 1)
        ]
        with self.assertRaises(ValueError) as context:
            brkga.set_initial_population(chromosomes)
        self.assertEqual(
            str(context.exception).strip(),
            "Number of given chromosomes (11) is large than "
            "the population size (10)")

        chromosomes = [
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"] + 1)
            ])
        ]
        with self.assertRaises(ValueError) as context:
            brkga.set_initial_population(chromosomes)
        self.assertEqual(
            str(context.exception).strip(),
            "Error on setting initial population: chromosome 0 "
            "does not have the required dimension "
            "(actual size: 4, required size: 3)")

        chromosomes = [
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"] - 1)
            ])
        ]
        with self.assertRaises(ValueError) as context:
            brkga.set_initial_population(chromosomes)
        self.assertEqual(
            str(context.exception).strip(),
            "Error on setting initial population: chromosome 0 "
            "does not have the required dimension "
            "(actual size: 2, required size: 3)")

        chromosomes = [
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"] + 1)
            ]),
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"])
            ]),
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"])
            ])
        ]
        with self.assertRaises(ValueError) as context:
            brkga.set_initial_population(chromosomes)
        self.assertEqual(
            str(context.exception).strip(),
            "Error on setting initial population: chromosome 0 "
            "does not have the required dimension "
            "(actual size: 4, required size: 3)")

        chromosomes = [
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"])
            ]),
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"] + 1)
            ]),
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"])
            ])
        ]
        with self.assertRaises(ValueError) as context:
            brkga.set_initial_population(chromosomes)
        self.assertEqual(
            str(context.exception).strip(),
            "Error on setting initial population: chromosome 1 "
            "does not have the required dimension "
            "(actual size: 4, required size: 3)")

        chromosomes = [
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"])
            ]),
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"])
            ]),
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"] + 1)
            ])
        ]
        with self.assertRaises(ValueError) as context:
            brkga.set_initial_population(chromosomes)
        self.assertEqual(
            str(context.exception).strip(),
            "Error on setting initial population: chromosome 2 "
            "does not have the required dimension "
            "(actual size: 4, required size: 3)")

        chromosomes = [
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"])
            ])
        ]
        brkga.set_initial_population(chromosomes)

        self.assertEqual(brkga._current_populations[0].chromosomes[0],
                         chromosomes[0])
        self.assertIsNot(brkga._current_populations[0].chromosomes[0],
                         chromosomes[0])

        chromosomes[0] = BaseChromosome([0.1111, 0.2222, 0.3333])
        self.assertNotEqual(brkga._current_populations[0].chromosomes[0],
                            chromosomes[0])

        chromosomes = [
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"])
            ]),
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"])
            ]),
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"])
            ])
        ]
        brkga.set_initial_population(chromosomes)

        self.assertEqual(len(brkga._current_populations[0].chromosomes),
                         len(chromosomes))
        self.assertEqual(brkga._current_populations[0].chromosomes,
                         chromosomes)
        self.assertIsNot(brkga._current_populations[0].chromosomes,
                         chromosomes)

        self.assertEqual(brkga._initial_population, True)
Example #19
0
    def test_set_bias_custom_function(self):
        """
        Tests set_bias_custom_function() method.
        """

        param_values = deepcopy(self.default_param_values)
        param_values["params"].population_size = 100
        param_values["params"].total_parents = 10
        brkga = BrkgaMpIpr(**param_values)

        # After build, brkga_params function is never CUSTOM
        self.assertNotEqual(brkga.params.bias_type, BiasFunctionType.CUSTOM)

        with self.assertRaises(ValueError) as context:
            brkga.set_bias_custom_function(lambda x: -x)
        self.assertEqual(
            str(context.exception).strip(),
            "Bias function must be positive non-increasing")

        with self.assertRaises(ValueError) as context:
            brkga.set_bias_custom_function(lambda x: x)
        self.assertEqual(
            str(context.exception).strip(),
            "Bias function is not a non-increasing function")

        with self.assertRaises(ValueError) as context:
            brkga.set_bias_custom_function(lambda x: x + 1)
        self.assertEqual(
            str(context.exception).strip(),
            "Bias function is not a non-increasing function")

        with self.assertRaises(ValueError) as context:
            brkga.set_bias_custom_function(lambda x: math.log1p(x))
        self.assertEqual(
            str(context.exception).strip(),
            "Bias function is not a non-increasing function")

        brkga.set_bias_custom_function(lambda x: 1.0 / math.log1p(x))
        self.assertAlmostEqual(brkga._total_bias_weight, 6.554970525044798)

        # After 2nd call to set_bias_custom_function, brkga_params function
        # is always CUSTOM
        self.assertEqual(brkga.params.bias_type, BiasFunctionType.CUSTOM)

        brkga.set_bias_custom_function(lambda x: 1.0 / x)
        self.assertAlmostEqual(brkga._total_bias_weight, 2.9289682539682538)
        self.assertEqual(brkga.params.bias_type, BiasFunctionType.CUSTOM)

        brkga.set_bias_custom_function(lambda x: x**-2.0)
        self.assertAlmostEqual(brkga._total_bias_weight, 1.5497677311665408)
        self.assertEqual(brkga.params.bias_type, BiasFunctionType.CUSTOM)

        brkga.set_bias_custom_function(lambda x: x**-3.0)
        self.assertAlmostEqual(brkga._total_bias_weight, 1.197531985674193)
        self.assertEqual(brkga.params.bias_type, BiasFunctionType.CUSTOM)

        brkga.set_bias_custom_function(lambda x: math.exp(-x))
        self.assertAlmostEqual(brkga._total_bias_weight, 0.5819502851677112)
        self.assertEqual(brkga.params.bias_type, BiasFunctionType.CUSTOM)

        # This is a constance function.
        brkga.set_bias_custom_function(
            lambda _: 1.0 / brkga.params.total_parents)
        self.assertAlmostEqual(brkga._total_bias_weight, 0.9999999999999999)
        self.assertEqual(brkga.params.bias_type, BiasFunctionType.CUSTOM)

        brkga.set_bias_custom_function(lambda x: 0.6325 / math.sqrt(x))
        self.assertAlmostEqual(brkga._total_bias_weight, 3.175781171302612)
        self.assertEqual(brkga.params.bias_type, BiasFunctionType.CUSTOM)

        #############################################
        # Constant functions test for standard BRKGA
        #############################################

        param_values = deepcopy(self.default_param_values)
        param_values["params"].num_elite_parents = 1
        param_values["params"].total_parents = 2
        brkga = BrkgaMpIpr(**param_values)

        rho = 0.5
        brkga.set_bias_custom_function(lambda x: rho if x == 1 else 1.0 - rho)
        self.assertAlmostEqual(brkga._total_bias_weight, 1.0)
        self.assertAlmostEqual(brkga._bias_function(1), 0.5)
        self.assertAlmostEqual(brkga._bias_function(2), 0.5)

        rho = 0.75
        brkga.set_bias_custom_function(lambda x: rho if x == 1 else 1.0 - rho)
        self.assertAlmostEqual(brkga._total_bias_weight, 1.0)
        self.assertAlmostEqual(brkga._bias_function(1), 0.75)
        self.assertAlmostEqual(brkga._bias_function(2), 0.25)

        rho = 0.9
        brkga.set_bias_custom_function(lambda x: rho if x == 1 else 1.0 - rho)
        self.assertAlmostEqual(brkga._total_bias_weight, 1.0)
        self.assertAlmostEqual(brkga._bias_function(1), 0.9)
        self.assertAlmostEqual(brkga._bias_function(2), 0.1)
Example #20
0
    def test_initialize(self):
        """
        Tests initialize() method.
        """

        # Double initialization.
        param_values = deepcopy(self.default_param_values)
        brkga = BrkgaMpIpr(**param_values)

        # 1st initialization.
        brkga.initialize()
        with self.assertRaises(RuntimeError) as context:
            # 2nd initialization.
            brkga.initialize()
        self.assertEqual(
            str(context.exception).strip(),
            "The algorithm is already initialized. "
            "Please call 'reset()' instead.")

        # Custom function is not defined.
        filename = os.path.join(CONFIG_DIR, "custom_bias_function.conf")
        brkga_params, _ = load_configuration(filename)

        param_values = deepcopy(self.default_param_values)
        param_values["params"] = brkga_params
        brkga = BrkgaMpIpr(**param_values)

        with self.assertRaises(ValueError) as context:
            brkga.initialize()
        self.assertEqual(
            str(context.exception).strip(),
            "The bias function is not defined. Call "
            "set_bias_custom_function() before call initialize().")

        ########################
        # Test without warmstart
        ########################

        param_values = deepcopy(self.default_param_values)
        param_values["sense"] = Sense.MAXIMIZE
        params = param_values["params"]
        brkga = BrkgaMpIpr(**param_values)
        brkga.initialize()

        self.assertTrue(brkga._initialized,
                        "Flag 'brkga._initialized' is supposed to be 'True'")
        self.assertFalse(
            brkga._reset_phase,
            "Flag 'brkga._reset_phase' is supposed to be 'False'")

        self.assertEqual(len(brkga._current_populations),
                         params.num_independent_populations)
        self.assertEqual(len(brkga._previous_populations),
                         params.num_independent_populations)

        for i in range(params.num_independent_populations):
            self.assertEqual(len(brkga._current_populations[i].chromosomes),
                             params.population_size)
            self.assertEqual(len(brkga._current_populations[i].fitness),
                             params.population_size)
            self.assertEqual(len(brkga._previous_populations[i].chromosomes),
                             params.population_size)
            self.assertEqual(len(brkga._previous_populations[i].fitness),
                             params.population_size)

            self.assertEqual(brkga._current_populations[i].chromosomes,
                             brkga._previous_populations[i].chromosomes)

            self.assertIsNot(brkga._current_populations[i].chromosomes,
                             brkga._previous_populations[i].chromosomes)

            correct_order = True
            for j in range(1, brkga.params.population_size):
                correct_order &= \
                    brkga._current_populations[i].fitness[j - 1][0] >= \
                    brkga._current_populations[i].fitness[j][0]
            # end for
            self.assertTrue(correct_order, "incorrect chromosome order")
        # end for

        param_values = deepcopy(self.default_param_values)
        param_values["sense"] = Sense.MINIMIZE
        params = param_values["params"]
        brkga = BrkgaMpIpr(**param_values)
        brkga.initialize()

        for i in range(params.num_independent_populations):
            correct_order = True
            for j in range(1, brkga.params.population_size):
                correct_order &= \
                    brkga._current_populations[i].fitness[j - 1][0] <= \
                    brkga._current_populations[i].fitness[j][0]
            # end for
            self.assertTrue(correct_order, "incorrect chromosome order")
        # end for

        ########################
        # Test with warmstart
        ########################

        local_rng = Random(param_values["seed"])
        chromosomes = [
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"])
            ]),
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"])
            ]),
            BaseChromosome([
                local_rng.random()
                for _ in range(param_values["chromosome_size"])
            ])
        ]

        param_values = deepcopy(self.default_param_values)
        param_values["sense"] = Sense.MINIMIZE
        params = param_values["params"]
        brkga = BrkgaMpIpr(**param_values)
        brkga.set_initial_population(chromosomes)
        brkga.initialize()

        for i in range(params.num_independent_populations):
            self.assertEqual(len(brkga._current_populations[i].chromosomes),
                             params.population_size)
            self.assertEqual(len(brkga._current_populations[i].fitness),
                             params.population_size)
            self.assertEqual(len(brkga._previous_populations[i].chromosomes),
                             params.population_size)
            self.assertEqual(len(brkga._previous_populations[i].fitness),
                             params.population_size)

            self.assertEqual(brkga._current_populations[i].chromosomes,
                             brkga._previous_populations[i].chromosomes)

            self.assertIsNot(brkga._current_populations[i].chromosomes,
                             brkga._previous_populations[i].chromosomes)
        # end for

        old_chr = deepcopy(chromosomes[0])
        param_values["decoder"].decode(chromosomes[0], rewrite=True)
        self.assertNotEqual(chromosomes[0], old_chr)
        self.assertEqual(brkga._current_populations[0].chromosomes[0],
                         chromosomes[0])

        # Create a local chromosome and applied the decoder on it.
        local_rng = Random(param_values["seed"])
        for _ in range(1000):
            local_rng.random()
        local_chr = BaseChromosome([
            local_rng.random() for _ in range(param_values["chromosome_size"])
        ])
        param_values["decoder"].decode(local_chr, rewrite=True)

        # 4th chromosome must be the 1st generated one due to the warmstart.
        self.assertEqual(brkga._current_populations[0].chromosomes[3],
                         local_chr)

        ########################
        # Test reset phase
        ########################

        param_values = deepcopy(self.default_param_values)
        params = param_values["params"]
        brkga = BrkgaMpIpr(**param_values)
        brkga.initialize()

        # Create a local RNG and advance it until the same state as the
        # internal BRKGA RNG after initialization.
        local_rng = Random(param_values["seed"])
        skip = 1000 + params.num_independent_populations * \
               params.population_size * brkga.chromosome_size
        for _ in range(skip):
            local_rng.random()

        self.assertEqual(brkga._rng.getstate(), local_rng.getstate())

        brkga._reset_phase = True
        brkga.initialize()

        # Create a local chromosome and applied the decoder on it.
        local_chr = BaseChromosome([
            local_rng.random() for _ in range(param_values["chromosome_size"])
        ])
        param_values["decoder"].decode(local_chr, rewrite=True)

        self.assertEqual(brkga._current_populations[0].chromosomes[0],
                         local_chr)
Example #21
0
    def test_evolve_population0(self):
        """
        Tests evolve_population() method.
        """

        param_values = deepcopy(self.default_param_values)
        brkga_params = param_values["params"]
        brkga_params.num_independent_populations = 3
        brkga_params.num_elite_parents = 1
        brkga_params.total_parents = 2
        brkga = BrkgaMpIpr(**param_values)

        # Not initialized
        with self.assertRaises(RuntimeError) as context:
            brkga.evolve_population(0)
        self.assertEqual(
            str(context.exception).strip(),
            "The algorithm hasn't been initialized. "
            "Call 'initialize()' before 'evolve_population()'")

        brkga.initialize()

        # Test invalid population indices.
        population_index = -1
        with self.assertRaises(ValueError) as context:
            brkga.evolve_population(population_index)
        self.assertEqual(
            str(context.exception).strip(), "Population must be in [0, 2]: -1")

        population_index = brkga.params.num_independent_populations
        with self.assertRaises(ValueError) as context:
            brkga.evolve_population(population_index)
        self.assertEqual(
            str(context.exception).strip(), "Population must be in [0, 2]: 3")

        # Save previous and current populations locally
        current = deepcopy(brkga._current_populations)
        previous = deepcopy(brkga._previous_populations)

        ########################
        # Test if algorithm swaps the populations correctly
        ########################

        for i in range(brkga_params.num_independent_populations):
            brkga.evolve_population(i)

            # Internal current and previous generation must be different.
            self.assertNotEqual(brkga._current_populations[i].chromosomes,
                                brkga._previous_populations[i].chromosomes)

            # The current the from this generation is equal to the previous
            # of the next generation.
            self.assertEqual(current[i].chromosomes,
                             brkga._previous_populations[i].chromosomes)
            self.assertEqual(current[i].fitness,
                             brkga._previous_populations[i].fitness)

            # The previous of this generation is lost. Just make sure that
            # the internal swap gets the new generation, not the current one.
            self.assertNotEqual(previous[i].chromosomes,
                                brkga._current_populations[i].chromosomes)
            self.assertNotEqual(previous[i].fitness,
                                brkga._current_populations[i].fitness)
        # end for
        print(f"Elapsed time: {time() - self.start_time :.2f}")
Example #22
0
    def test_evolve(self):
        """
        Tests evolve() method.
        """

        param_values = deepcopy(self.default_param_values)
        brkga_params = param_values["params"]
        brkga = BrkgaMpIpr(**param_values)

        # Not initialized
        with self.assertRaises(RuntimeError) as context:
            brkga.evolve()
        self.assertEqual(
            str(context.exception).strip(),
            "The algorithm hasn't been initialized. "
            "Call 'initialize()' before 'evolve()'")

        brkga.initialize()

        with self.assertRaises(ValueError) as context:
            brkga.evolve(-1)
        self.assertEqual(
            str(context.exception).strip(),
            "Number of generations must be large than one. "
            "Given -1")

        with open(os.path.join(STATE_DIR, "state5.pickle"), "rb") as hd:
            brkga = pickle.load(hd)

        with open(os.path.join(SOLUTION_DIR, "best_solution5.pickle"),
                  "rb") as hd:
            results = pickle.load(hd)

        brkga.evolve()
        self.assertEqual(brkga.get_best_fitness(), results["fitness1"])
        self.assertEqual(brkga.get_best_chromosome(), results["chromosome1"])
        print(f"Elapsed time: {time() - self.start_time :.2f}")

        brkga.evolve(10)
        self.assertEqual(brkga.get_best_fitness(), results["fitness10"])
        self.assertEqual(brkga.get_best_chromosome(), results["chromosome10"])
        print(f"Elapsed time: {time() - self.start_time :.2f}")

        brkga.evolve(100)
        self.assertEqual(brkga.get_best_fitness(), results["fitness100"])
        self.assertEqual(brkga.get_best_chromosome(), results["chromosome100"])
        print(f"Elapsed time: {time() - self.start_time :.2f}")
Example #23
0
    def test_constructor(self):
        """
        Tests BrkgaParams constructor.
        """

        ########################
        # Test regular/correct building.
        #######################

        param_values = deepcopy(self.default_param_values)
        brkga = BrkgaMpIpr(**param_values)

        self.assertEqual(brkga.elite_size, 3)
        self.assertEqual(brkga.num_mutants, 1)

        brkga_params = param_values["params"]
        self.assertEqual(len(brkga._parents_ordered),
                         brkga_params.total_parents)

        local_rng = Random(param_values["seed"])
        # Same warm up that the one in the constructor.
        for _ in range(1000):
            local_rng.random()
        self.assertEqual(brkga._rng.getstate(), local_rng.getstate())

        self.assertEqual(brkga._ChromosomeType, BaseChromosome)

        ########################
        # Test multi-start building.
        ########################

        param_values["evolutionary_mechanism_on"] = False
        param_values["params"].population_size = 10
        brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(brkga.elite_size, 1)
        self.assertEqual(brkga.num_mutants, 9)

        ########################
        # Test bias functions.
        ########################

        param_values = deepcopy(self.default_param_values)
        param_values["params"].bias_type = BiasFunctionType.LOGINVERSE
        brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(brkga.params.bias_type, BiasFunctionType.LOGINVERSE)
        self.assertAlmostEqual(brkga._bias_function(1), 1.4426950408889634)
        self.assertAlmostEqual(brkga._bias_function(2), 0.9102392266268375)
        self.assertAlmostEqual(brkga._bias_function(3), 0.721347520444481)

        param_values["params"].bias_type = BiasFunctionType.LINEAR
        brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(brkga.params.bias_type, BiasFunctionType.LINEAR)
        self.assertAlmostEqual(brkga._bias_function(1), 1.0)
        self.assertAlmostEqual(brkga._bias_function(2), 0.5)
        self.assertAlmostEqual(brkga._bias_function(3), 0.333333333333)

        param_values["params"].bias_type = BiasFunctionType.QUADRATIC
        brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(brkga.params.bias_type, BiasFunctionType.QUADRATIC)
        self.assertAlmostEqual(brkga._bias_function(1), 1.0)
        self.assertAlmostEqual(brkga._bias_function(2), 0.25)
        self.assertAlmostEqual(brkga._bias_function(3), 0.111111111111)

        param_values["params"].bias_type = BiasFunctionType.CUBIC
        brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(brkga.params.bias_type, BiasFunctionType.CUBIC)
        self.assertAlmostEqual(brkga._bias_function(1), 1.0)
        self.assertAlmostEqual(brkga._bias_function(2), 0.125)
        self.assertAlmostEqual(brkga._bias_function(3), 0.037037037037037035)

        param_values["params"].bias_type = BiasFunctionType.EXPONENTIAL
        brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(brkga.params.bias_type, BiasFunctionType.EXPONENTIAL)
        self.assertAlmostEqual(brkga._bias_function(1), 0.36787944117144233)
        self.assertAlmostEqual(brkga._bias_function(2), 0.1353352832366127)
        self.assertAlmostEqual(brkga._bias_function(3), 0.049787068367863944)

        param_values["params"].bias_type = BiasFunctionType.CONSTANT
        brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(brkga.params.bias_type, BiasFunctionType.CONSTANT)
        self.assertAlmostEqual(brkga._bias_function(1), 0.5)
        self.assertAlmostEqual(brkga._bias_function(2), 0.5)
        self.assertAlmostEqual(brkga._bias_function(3), 0.5)

        ########################
        # Test exceptions.
        ########################

        # Chromosome size
        param_values = deepcopy(self.default_param_values)
        param_values["chromosome_size"] = 0
        with self.assertRaises(ValueError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(),
            "Chromosome size must be larger than zero: 0")

        param_values["chromosome_size"] = -10
        with self.assertRaises(ValueError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(),
            "Chromosome size must be larger than zero: -10")

        # Population size
        param_values = deepcopy(self.default_param_values)
        param_values["params"].population_size = 0
        with self.assertRaises(ValueError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(),
            "Population size size must be larger than zero: 0")

        param_values["params"].population_size = -10
        with self.assertRaises(ValueError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(),
            "Population size size must be larger than zero: -10")

        # Elite size
        param_values = deepcopy(self.default_param_values)
        param_values["params"].elite_percentage = 0.0
        with self.assertRaises(ValueError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(), "Elite set size less then one: 0")

        param_values["params"].elite_percentage = -1.0
        with self.assertRaises(ValueError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(),
            "Elite set size less then one: -10")

        param_values["params"].elite_percentage = 0.3
        param_values["params"].population_size = 2
        with self.assertRaises(ValueError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(), "Elite set size less then one: 0")

        param_values["params"].elite_percentage = 1.1
        param_values["params"].population_size = 10
        with self.assertRaises(ValueError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(),
            "Elite set size (11) greater than population size (10)")

        # Mutant size
        param_values = deepcopy(self.default_param_values)
        param_values["params"].mutants_percentage = 0.0
        brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(brkga.num_mutants, 0)

        param_values["params"].mutants_percentage = -1.0
        with self.assertRaises(ValueError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(),
            "Mutant set size less then zero: -10")

        param_values["params"].mutants_percentage = 1.1
        with self.assertRaises(ValueError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(),
            "Mutant set size (11) greater than population size (10)")

        # Elite + Mutant size.
        param_values = deepcopy(self.default_param_values)
        param_values["params"].elite_percentage = 0.6
        param_values["params"].mutants_percentage = 0.6
        with self.assertRaises(ValueError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(),
            "Elite set size (6) + mutant set size (6) greater "
            "than population size (10)")

        # Elite parents for mating.
        param_values = deepcopy(self.default_param_values)
        param_values["params"].num_elite_parents = 0
        with self.assertRaises(ValueError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(),
            "Number of elite parents must be at least 1: 0")

        param_values["params"].num_elite_parents = 1
        param_values["params"].total_parents = 1
        with self.assertRaises(ValueError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(),
            "Total parents must be at least 2: 1")

        param_values["params"].num_elite_parents = 2
        param_values["params"].total_parents = 2
        with self.assertRaises(ValueError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(),
            "Number of elite parents (2) is greater than or "
            "equal to total_parents (2)")

        param_values["params"].num_elite_parents = 3
        param_values["params"].total_parents = 2
        with self.assertRaises(ValueError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(),
            "Number of elite parents (3) is greater than or "
            "equal to total_parents (2)")

        brkga_params = param_values["params"]
        brkga_params.num_elite_parents = \
            1 + int(brkga_params.population_size * brkga_params.elite_percentage)
        brkga_params.total_parents = 1 + brkga_params.num_elite_parents
        with self.assertRaises(ValueError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(),
            "Number of elite parents (4) is greater than elite set (3)")

        # Number of independent populations.
        param_values = deepcopy(self.default_param_values)
        param_values["params"].num_independent_populations = 0
        with self.assertRaises(ValueError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(),
            "Number of parallel populations must be larger than zero: 0")

        # TODO: enable the following when IPR methods be implemented.
        # # alpha_block_size.
        # param_values = deepcopy(self.default_param_values)
        # param_values["params"].alpha_block_size = 0
        # with self.assertRaises(ValueError) as context:
        #     brkga = BrkgaMpIpr(**param_values)
        # self.assertEqual(str(context.exception).strip(),
        #                  "Alpha block size must be larger than zero: 0")

        # # Percentage / path size.
        # param_values = deepcopy(self.default_param_values)
        # param_values["params"].pr_percentage = 0.0
        # with self.assertRaises(ValueError) as context:
        #     brkga = BrkgaMpIpr(**param_values)
        # self.assertEqual(str(context.exception).strip(),
        #                  "Percentage / path size must be in (0, 1]: 0.0")

        # param_values["params"].pr_percentage = 1.001
        # with self.assertRaises(ValueError) as context:
        #     brkga = BrkgaMpIpr(**param_values)
        # self.assertEqual(str(context.exception).strip(),
        #                  "Percentage / path size must be in (0, 1]: 1.001")

        # Invalid decoder object.
        param_values = deepcopy(self.default_param_values)
        param_values["decoder"] = None
        with self.assertRaises(TypeError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(),
            "The given decoder (<class 'NoneType'>) has no 'decode()' method")

        param_values["decoder"] = lambda x: sum(x)
        with self.assertRaises(TypeError) as context:
            brkga = BrkgaMpIpr(**param_values)
        self.assertEqual(
            str(context.exception).strip(),
            "The given decoder (<class 'function'>) has no 'decode()' method")