Exemple #1
0
 def __init__(self, comparator: Comparator = DominanceComparator()):
     super(BinaryTournamentSelection, self).__init__()
     self.comparator = comparator
Exemple #2
0
class OMOPSO(ParticleSwarmOptimization):
    def __init__(
        self,
        problem: FloatProblem,
        swarm_size: int,
        uniform_mutation: UniformMutation,
        non_uniform_mutation: NonUniformMutation,
        leaders: Optional[BoundedArchive],
        epsilon: float,
        termination_criterion: TerminationCriterion,
        swarm_generator: Generator = store.default_generator,
        swarm_evaluator: Evaluator = store.default_evaluator,
    ):
        """This class implements the OMOPSO algorithm as described in

        todo Update this reference
        * SMPSO: A new PSO-based metaheuristic for multi-objective optimization

        The implementation of OMOPSO provided in jMetalPy follows the algorithm template described in the algorithm
        templates section of the documentation.

        :param problem: The problem to solve.
        :param swarm_size: Size of the swarm.
        :param leaders: Archive for leaders.
        """
        super(OMOPSO, self).__init__(problem=problem, swarm_size=swarm_size)
        self.swarm_generator = swarm_generator
        self.swarm_evaluator = swarm_evaluator

        self.termination_criterion = termination_criterion
        self.observable.register(termination_criterion)

        self.uniform_mutation = uniform_mutation
        self.non_uniform_mutation = non_uniform_mutation

        self.leaders = leaders

        self.epsilon = epsilon
        self.epsilon_archive = NonDominatedSolutionsArchive(
            EpsilonDominanceComparator(epsilon))

        self.c1_min = 1.5
        self.c1_max = 2.0
        self.c2_min = 1.5
        self.c2_max = 2.0
        self.r1_min = 0.0
        self.r1_max = 1.0
        self.r2_min = 0.0
        self.r2_max = 1.0
        self.weight_min = 0.1
        self.weight_max = 0.5
        self.change_velocity1 = -1
        self.change_velocity2 = -1

        self.dominance_comparator = DominanceComparator()

        self.speed = numpy.zeros(
            (self.swarm_size, self.problem.number_of_variables), dtype=float)

    def create_initial_solutions(self) -> List[FloatSolution]:
        return [
            self.swarm_generator.new(self.problem)
            for _ in range(self.swarm_size)
        ]

    def evaluate(self, solution_list: List[FloatSolution]):
        return self.swarm_evaluator.evaluate(solution_list, self.problem)

    def stopping_condition_is_met(self) -> bool:
        return self.termination_criterion.is_met

    def initialize_global_best(self, swarm: List[FloatSolution]) -> None:
        for particle in swarm:
            if self.leaders.add(particle):
                self.epsilon_archive.add(copy(particle))

    def initialize_particle_best(self, swarm: List[FloatSolution]) -> None:
        for particle in swarm:
            particle.attributes["local_best"] = copy(particle)

    def initialize_velocity(self, swarm: List[FloatSolution]) -> None:
        for i in range(self.swarm_size):
            for j in range(self.problem.number_of_variables):
                self.speed[i][j] = 0.0

    def update_velocity(self, swarm: List[FloatSolution]) -> None:
        for i in range(self.swarm_size):
            best_particle = copy(swarm[i].attributes["local_best"])
            best_global = self.select_global_best()

            r1 = round(random.uniform(self.r1_min, self.r1_max), 1)
            r2 = round(random.uniform(self.r2_min, self.r2_max), 1)
            c1 = round(random.uniform(self.c1_min, self.c1_max), 1)
            c2 = round(random.uniform(self.c2_min, self.c2_max), 1)
            w = round(random.uniform(self.weight_min, self.weight_max), 1)

            for var in range(swarm[i].number_of_variables):
                self.speed[i][var] = (
                    w * self.speed[i][var] +
                    (c1 * r1 *
                     (best_particle.variables[var] - swarm[i].variables[var]))
                    + (c2 * r2 *
                       (best_global.variables[var] - swarm[i].variables[var])))

    def update_position(self, swarm: List[FloatSolution]) -> None:
        for i in range(self.swarm_size):
            particle = swarm[i]

            for j in range(particle.number_of_variables):
                particle.variables[j] += self.speed[i][j]

                if particle.variables[j] < self.problem.lower_bound[j]:
                    particle.variables[j] = self.problem.lower_bound[j]
                    self.speed[i][j] *= self.change_velocity1

                if particle.variables[j] > self.problem.upper_bound[j]:
                    particle.variables[j] = self.problem.upper_bound[j]
                    self.speed[i][j] *= self.change_velocity2

    def update_global_best(self, swarm: List[FloatSolution]) -> None:
        for particle in swarm:
            if self.leaders.add(copy(particle)):
                self.epsilon_archive.add(copy(particle))

    def update_particle_best(self, swarm: List[FloatSolution]) -> None:
        for i in range(self.swarm_size):
            flag = self.dominance_comparator.compare(
                swarm[i], swarm[i].attributes["local_best"])
            if flag != 1:
                swarm[i].attributes["local_best"] = copy(swarm[i])

    def perturbation(self, swarm: List[FloatSolution]) -> None:
        self.non_uniform_mutation.set_current_iteration(self.evaluations /
                                                        self.swarm_size)
        for i in range(self.swarm_size):
            if (i % 3) == 0:
                self.non_uniform_mutation.execute(swarm[i])
            else:
                self.uniform_mutation.execute(swarm[i])

    def select_global_best(self) -> FloatSolution:
        leaders = self.leaders.solution_list

        if len(leaders) > 2:
            particles = random.sample(leaders, 2)

            if self.leaders.comparator.compare(particles[0], particles[1]) < 1:
                best_global = copy(particles[0])
            else:
                best_global = copy(particles[1])
        else:
            best_global = copy(self.leaders.solution_list[0])

        return best_global

    def __velocity_constriction(self, value: float, delta_max: [],
                                delta_min: [], variable_index: int) -> float:
        result = value
        if value > delta_max[variable_index]:
            result = delta_max[variable_index]
        if value < delta_min[variable_index]:
            result = delta_min[variable_index]

        return result

    def __inertia_weight(self, wmax: float):
        return wmax

    def __constriction_coefficient(self, c1: float, c2: float) -> float:
        rho = c1 + c2
        if rho <= 4:
            result = 1.0
        else:
            result = 2.0 / (2.0 - rho - sqrt(pow(rho, 2.0) - 4.0 * rho))

        return result

    def init_progress(self) -> None:
        self.evaluations = self.swarm_size
        self.leaders.compute_density_estimator()

        self.initialize_velocity(self.solutions)
        self.initialize_particle_best(self.solutions)
        self.initialize_global_best(self.solutions)

    def update_progress(self) -> None:
        self.evaluations += self.swarm_size
        self.leaders.compute_density_estimator()

        observable_data = self.get_observable_data()
        observable_data["SOLUTIONS"] = self.epsilon_archive.solution_list
        self.observable.notify_all(**observable_data)

    def get_result(self) -> List[FloatSolution]:
        return self.epsilon_archive.solution_list

    def get_name(self) -> str:
        return "OMOPSO"
Exemple #3
0
 def __init__(self,
              max_population_size: int,
              dominance_comparator: Comparator = DominanceComparator()):
     super(RankingAndCrowdingDistanceSelection, self).__init__()
     self.max_population_size = max_population_size
     self.dominance_comparator = dominance_comparator
Exemple #4
0
    def run(self) -> List[S]:
        pool_1_size = self.population_size
        pool_2_size = self.population_size

        selection_operator_1 = BinaryTournamentSelection()
        crossover_operator_1 = IntegerSBXCrossover(1.0, 20.0)
        mutation_operator_1 = IntegerPolynomialMutation(
            1.0 / self.problem.number_of_variables, 20.0)
        selection_operator_2 = DifferentialEvolutionSelection()
        crossover_operator_2 = DifferentialEvolutionCrossover(0.2, 0.5, 0.5)

        dominance = DominanceComparator()

        max_iterations = self.max_iterations
        iterations = 0

        parent_1: List[IntegerSolution] = [None, None]

        generational_hv: List[float] = []

        current_gen = 0
        """Create the initial subpopulation pools and evaluate them"""
        pool_1: List[IntegerSolution] = []
        for i in range(pool_1_size):
            pool_1.append(self.problem.create_solution())
            pool_1[i] = self.problem.evaluate(pool_1[i])

        pool_2: List[IntegerSolution] = []
        for i in range(pool_2_size):
            pool_2.append(self.problem.create_solution())
            pool_2[i] = self.problem.evaluate(pool_2[i])

        evaluations = pool_1_size + pool_2_size

        mix = self.mix_interval

        problem = self.problem

        h = HyperVolume(reference_point=[1] *
                        self.problem.number_of_objectives)

        initial_population = True
        """The main evolutionary cycle"""
        while iterations < max_iterations:
            combi: List[IntegerSolution] = []
            if not initial_population:
                offspring_pop_1: List[IntegerSolution] = []
                offspring_pop_2: List[IntegerSolution] = []
                """Evolve pool 1"""
                for i in range(pool_1_size):
                    parent_1[0] = selection_operator_1.execute(pool_1)
                    parent_1[1] = selection_operator_1.execute(pool_1)

                    child_1: IntegerSolution = crossover_operator_1.execute(
                        parent_1)[0]
                    child_1 = mutation_operator_1.execute(child_1)

                    child_1 = problem.evaluate(child_1)
                    evaluations += 1

                    offspring_pop_1.append(child_1)
                """Evolve pool 2"""
                for i in range(pool_2_size):
                    parent_2: List[
                        IntegerSolution] = selection_operator_2.execute(pool_2)

                    crossover_operator_2.current_individual = pool_2[i]
                    child_2 = crossover_operator_2.execute(parent_2)
                    child_2 = problem.evaluate(child_2[0])

                    evaluations += 1

                    result = dominance.compare(pool_2[i], child_2)

                    if result == -1:
                        offspring_pop_2.append(pool_2[i])
                    elif result == 1:
                        offspring_pop_2.append(child_2)
                    else:
                        offspring_pop_2.append(child_2)
                        offspring_pop_2.append(pool_2[i])

                ind_1 = pool_1[random.randint(0, pool_1_size - 1)]
                ind_2 = pool_2[random.randint(0, pool_2_size - 1)]

                offspring_pop_1.append(ind_1)
                offspring_pop_2.append(ind_2)

                offspring_pop_1.extend(pool_1)
                pool_1 = self.r.replace(offspring_pop_1[:pool_1_size],
                                        offspring_pop_1[pool_1_size:])

                pool_2 = self.r.replace(offspring_pop_2[:pool_2_size],
                                        offspring_pop_2[pool_2_size:])

                mix -= 1
                if mix == 0:
                    """Time to perform fitness sharing"""
                    mix = self.mix_interval
                    combi = combi + pool_1 + pool_2
                    # print("Combi size: ", len(combi))
                    """pool1size/10"""

                    combi = self.r.replace(
                        combi[:int(pool_1_size / 10)],
                        combi[int(pool_1_size / 10):len(combi)],
                    )
                    """
                    print(
                        "Sizes: ",
                        len(pool_1) + len(combi),
                        len(pool_2) + len(combi),
                        "\n",
                    )
                    """
                    pool_1 = self.r.replace(pool_1, combi)

                    pool_2 = self.r.replace(pool_2, combi)

            if initial_population:
                initial_population = False

            iterations += 1
            print("Iterations: ", str(iterations))
            """
            hval_1 = h.compute([s.objectives for s in pool_1])
            hval_2 = h.compute([s.objectives for s in pool_2])
            print("hval_1: ", str(hval_1))
            print("hval_2: ", str(hval_2), "\n")
            """

            new_gen = int(evaluations / self.report_interval)
            if new_gen > current_gen:
                combi = combi + pool_1 + pool_2

                combi = self.r.replace(combi[:(2 * pool_1_size)],
                                       combi[(2 * pool_1_size):])

                hval = h.compute([s.objectives for s in combi])
                for i in range(current_gen, new_gen, 1):
                    generational_hv.append(hval)

                current_gen = new_gen
        """#Write runtime generational HV to file"""
        """Return the first non dominated front"""
        combi_ini: List[IntegerSolution] = []
        combi_ini.extend(pool_1)
        combi_ini.extend(pool_2)
        combi_ini = self.r.replace(
            combi_ini[:pool_1_size + pool_2_size],
            combi_ini[pool_1_size + pool_2_size:],
        )
        return combi_ini
Exemple #5
0
 def default_comparator(self):
     return DominanceComparator()
class BMOPSO(ParticleSwarmOptimization):
    def __init__(
        self,
        problem: BinaryProblem,
        swarm_size: int,
        mutation: BitFlipMutation,
        leaders: Optional[BoundedArchive],
        epsilon: float,
        termination_criterion: TerminationCriterion,
        swarm_generator: Generator = store.default_generator,
        swarm_evaluator: Evaluator = store.default_evaluator,
    ):

        super(BMOPSO, self).__init__(problem=problem, swarm_size=swarm_size)
        self.swarm_generator = swarm_generator
        self.swarm_evaluator = swarm_evaluator

        self.termination_criterion = termination_criterion
        self.observable.register(termination_criterion)

        self.mutation_operator = mutation

        self.leaders = leaders

        self.epsilon = epsilon
        self.epsilon_archive = NonDominatedSolutionListArchive(
            # EpsilonDominanceComparator(epsilon)
            DominanceComparator())

        self.c1_min = 1.5
        self.c1_max = 2.0
        self.c2_min = 1.5
        self.c2_max = 2.0
        self.r1_min = 0.0
        self.r1_max = 1.0
        self.r2_min = 0.0
        self.r2_max = 1.0
        self.weight_min = 0.1
        self.weight_max = 0.5
        self.change_velocity1 = -1
        self.change_velocity2 = -1

        self.dominance_comparator = DominanceComparator()

        self.speed = numpy.zeros(
            (
                self.swarm_size,
                self.problem.number_of_variables,
                self.problem.number_of_tests,
            ),
            dtype=float,
        )

    def create_initial_solutions(self) -> List[BinarySolution]:
        return [
            self.swarm_generator.new(self.problem)
            for _ in range(self.swarm_size)
        ]

    def evaluate(self, solution_list: List[BinarySolution]):
        return self.swarm_evaluator.evaluate(solution_list, self.problem)

    def stopping_condition_is_met(self) -> bool:
        return self.termination_criterion.is_met

    def initialize_global_best(self, swarm: List[BinarySolution]) -> None:
        for particle in swarm:
            if self.leaders.add(particle):
                self.epsilon_archive.add(copy(particle))

    def initialize_particle_best(self, swarm: List[BinarySolution]) -> None:
        for particle in swarm:
            particle.attributes["local_best"] = copy(particle)

    def initialize_velocity(self, swarm: List[BinarySolution]) -> None:
        for i in range(self.swarm_size):
            for j in range(self.problem.number_of_variables):
                self.speed[i][j] = 0.0

    def update_velocity(self, swarm: List[BinarySolution]) -> None:
        for i in range(self.swarm_size):
            best_particle = copy(swarm[i].attributes["local_best"])
            best_global = self.select_global_best()

            r1 = round(random.uniform(self.r1_min, self.r1_max), 1)
            r2 = round(random.uniform(self.r2_min, self.r2_max), 1)
            c1 = round(random.uniform(self.c1_min, self.c1_max), 1)
            c2 = round(random.uniform(self.c2_min, self.c2_max), 1)
            w = round(random.uniform(self.weight_min, self.weight_max), 1)

            for var in range(swarm[i].number_of_variables):
                best_particle_diff = numpy.subtract(
                    numpy.array(best_particle.variables[var]),
                    numpy.array(swarm[i].variables[var]),
                    dtype=numpy.float32,
                )
                best_global_diff = numpy.subtract(
                    numpy.array(best_global.variables[var]),
                    numpy.array(swarm[i].variables[var]),
                    dtype=numpy.float32,
                )

                self.speed[i][var] = (w * numpy.array(self.speed[i][var]) +
                                      (c1 * r1 * best_particle_diff) +
                                      (c2 * r2 * best_global_diff))

    def update_position(self, swarm: List[BinarySolution]) -> None:
        for i in range(self.swarm_size):
            particle = swarm[i]

            for j in range(particle.number_of_variables):
                particle.variables[j] = self.compute_position(self.speed[i][j])

    def compute_position(self, speed):
        updated_positions = (numpy.random.random_sample(speed.shape) <
                             self._sigmoid(speed)) * 1
        return list(numpy.array(updated_positions, dtype=bool))

    def _sigmoid(self, x):
        return 1 / (1 + numpy.exp(-x))

    def update_global_best(self, swarm: List[BinarySolution]) -> None:
        for particle in swarm:
            if self.leaders.add(copy(particle)):
                self.epsilon_archive.add(copy(particle))

    def update_particle_best(self, swarm: List[BinarySolution]) -> None:
        for i in range(self.swarm_size):
            flag = self.dominance_comparator.compare(
                swarm[i], swarm[i].attributes["local_best"])
            if flag != 1:
                swarm[i].attributes["local_best"] = copy(swarm[i])

    def perturbation(self, swarm: List[BinarySolution]) -> None:
        for i in range(self.swarm_size):
            if (i % 6) == 0:
                self.mutation_operator.execute(swarm[i])

    def select_global_best(self) -> BinarySolution:
        leaders = self.leaders.solution_list

        if len(leaders) > 2:
            particles = random.sample(leaders, 2)

            if self.leaders.comparator.compare(particles[0], particles[1]) < 1:
                best_global = copy(particles[0])
            else:
                best_global = copy(particles[1])
        else:
            best_global = copy(self.leaders.solution_list[0])

        return best_global

    def init_progress(self) -> None:
        self.evaluations = self.swarm_size
        self.leaders.compute_density_estimator()

        self.initialize_velocity(self.solutions)
        self.initialize_particle_best(self.solutions)
        self.initialize_global_best(self.solutions)

    def update_progress(self) -> None:
        self.evaluations += self.swarm_size
        self.leaders.compute_density_estimator()

        observable_data = self.get_observable_data()
        observable_data["SOLUTIONS"] = self.epsilon_archive.solution_list
        self.observable.notify_all(**observable_data)

    def get_result(self) -> List[BinarySolution]:
        return self.epsilon_archive.solution_list

    def get_name(self) -> str:
        return "my-BMOPSO"
Exemple #7
0
 def __init__(self):
     super(NonDominatedSolutionListArchive, self).__init__()
     self.comparator = DominanceComparator()
Exemple #8
0
class DominanceComparatorTestCases(unittest.TestCase):
    def setUp(self):
        self.comparator = DominanceComparator()

    def test_should_dominance_comparator_raise_an_exception_if_the_first_solution_is_null(
            self):
        solution = None
        solution2 = FloatSolution(3, 2, [], [])
        with self.assertRaises(Exception):
            self.comparator.compare(solution, solution2)

    def test_should_dominance_comparator_raise_an_exception_if_the_second_solution_is_null(
            self):
        solution = FloatSolution(3, 2, [], [])
        solution2 = None
        with self.assertRaises(Exception):
            self.comparator.compare(solution, solution2)

    def test_should_dominance_comparator_return_zero_if_the_two_solutions_have_one_objective_with_the_same_value(
            self):
        solution = FloatSolution(3, 1, [], [])
        solution2 = FloatSolution(3, 1, [], [])

        solution.objectives = [1.0]
        solution2.objectives = [1.0]

        self.assertEqual(0, self.comparator.compare(solution, solution2))

    def test_should_dominance_comparator_return_one_if_the_two_solutions_have_one_objective_and_the_second_one_is_lower(
            self):
        solution = FloatSolution(3, 1, [], [])
        solution2 = FloatSolution(3, 1, [], [])

        solution.objectives = [2.0]
        solution2.objectives = [1.0]

        self.assertEqual(1, self.comparator.compare(solution, solution2))

    def test_should_dominance_comparator_return_minus_one_if_the_two_solutions_have_one_objective_and_the_first_one_is_lower(
            self):
        solution = FloatSolution(3, 1, [], [])
        solution2 = FloatSolution(3, 1, [], [])

        solution.objectives = [1.0]
        solution2.objectives = [2.0]

        self.assertEqual(-1, self.comparator.compare(solution, solution2))

    def test_should_dominance_comparator_work_properly_case_a(self):
        """ Case A: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [2.0, 6.0, 15.0]
        """
        solution = FloatSolution(3, 3, [], [])
        solution2 = FloatSolution(3, 3, [], [])

        solution.objectives = [-1.0, 5.0, 9.0]
        solution2.objectives = [2.0, 6.0, 15.0]

        self.assertEqual(-1, self.comparator.compare(solution, solution2))

    def test_should_dominance_comparator_work_properly_case_b(self):
        """ Case b: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [-1.0, 5.0, 10.0]
        """
        solution = FloatSolution(3, 3, [], [])
        solution2 = FloatSolution(3, 3, [], [])

        solution.objectives = [-1.0, 5.0, 9.0]
        solution2.objectives = [-1.0, 5.0, 10.0]

        self.assertEqual(-1, self.comparator.compare(solution, solution2))

    def test_should_dominance_comparator_work_properly_case_c(self):
        """ Case c: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [-2.0, 5.0, 9.0]
        """
        solution = FloatSolution(3, 3, [], [])
        solution2 = FloatSolution(3, 3, [], [])

        solution.objectives = [-1.0, 5.0, 9.0]
        solution2.objectives = [-2.0, 5.0, 9.0]

        self.assertEqual(1, self.comparator.compare(solution, solution2))

    def test_should_dominance_comparator_work_properly_case_d(self):
        """ Case d: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [-1.0, 5.0, 8.0]
        """
        solution = FloatSolution(3, 3, [], [])
        solution2 = FloatSolution(3, 3, [], [])

        solution.objectives = [-1.0, 5.0, 9.0]
        solution2.objectives = [-1.0, 5.0, 8.0]

        self.assertEqual(1, self.comparator.compare(solution, solution2))

    def test_should_dominance_comparator_work_properly_case_3(self):
        """ Case d: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [-2.0, 5.0, 10.0]
        """
        solution = FloatSolution(3, 3, [], [])
        solution2 = FloatSolution(3, 3, [], [])

        solution.objectives = [-1.0, 5.0, 9.0]
        solution2.objectives = [-2.0, 5.0, 10.0]

        self.assertEqual(0, self.comparator.compare(solution, solution2))

    def test_should_dominance_comparator_work_properly_with_constrains_case_1(
            self):
        """ Case 1: solution1 has a higher degree of constraint violation than solution 2
        """
        solution1 = FloatSolution(3, 3, [], [])
        solution2 = FloatSolution(3, 3, [], [])
        solution1.attributes["overall_constraint_violation"] = -0.1
        solution2.attributes["overall_constraint_violation"] = -0.3

        solution1.objectives = [-1.0, 5.0, 9.0]
        solution2.objectives = [-2.0, 5.0, 10.0]

        self.assertEqual(-1, self.comparator.compare(solution1, solution2))

    def test_should_dominance_comparator_work_properly_with_constrains_case_2(
            self):
        """ Case 2: solution1 has a lower degree of constraint violation than solution 2
        """
        solution1 = FloatSolution(3, 3, [], [])
        solution2 = FloatSolution(3, 3, [], [])
        solution1.attributes["overall_constraint_violation"] = -0.3
        solution2.attributes["overall_constraint_violation"] = -0.1

        solution1.objectives = [-1.0, 5.0, 9.0]
        solution2.objectives = [-2.0, 5.0, 10.0]

        self.assertEqual(1, self.comparator.compare(solution1, solution2))
Exemple #9
0
 def setUp(self):
     self.comparator = DominanceComparator()
 def __init__(self, dominance_comparator: Comparator = DominanceComparator()):
     super(NonDominatedSolutionsArchive, self).__init__()
     self.comparator = dominance_comparator
Exemple #11
0
    def run(self) -> List[S]:
        # selection operator 1
        selection_operator_1 = BinaryTournamentSelection()
        # selection operator 2
        selection_operator_2 = DifferentialEvolutionSelection()
        # crossover operator 1
        crossover_operator_1 = SBXCrossover(1.0, 20.0)
        # crossover operator 2
        crossover_operator_2 = DifferentialEvolutionCrossover(0.2, 0.5, 0.5)
        # crossover operator 3
        crossover_operator_3 = DifferentialEvolutionCrossover(1.0, 0.5, 0.5)
        # mutation operator 1
        mutation_operator_1 = PolynomialMutation(
            1.0 / self.problem.number_of_variables, 20.0)
        # dominance comparator
        dominance = DominanceComparator()

        # array that stores the "generational" HV quality
        generational_hv: List[float] = []

        parent_1: List[FloatSolution] = [None, None]
        parent_2: List[FloatSolution] = []
        parent_3: List[FloatSolution] = []

        # initialize some local and global variables
        pool_1: List[FloatSolution] = []
        pool_2: List[FloatSolution] = []

        # size of elite subset used for fitness sharing between subpopulations
        nrOfDirectionalSolutionsToEvolve = int(self.population_size / 5)
        # subpopulation 1
        pool_1_size = int(self.population_size -
                          (nrOfDirectionalSolutionsToEvolve / 2))
        # subpopulation 2
        pool_2_size = int(self.population_size -
                          (nrOfDirectionalSolutionsToEvolve / 2))

        print(
            str(pool_1_size) + " - " + str(nrOfDirectionalSolutionsToEvolve) +
            " - " + str(self.mix_interval))

        evaluations = 0
        current_gen = 0
        directionalArchiveSize = 2 * self.population_size
        weights = self.__create_uniform_weights(
            directionalArchiveSize, self.problem.number_of_objectives)

        directionalArchive = self.__create_directional_archive(weights)
        neighbourhoods = self.__create_neighbourhoods(directionalArchive,
                                                      self.population_size)

        nrOfReplacements = 1
        iniID = 0

        # Create the initial pools
        # pool1
        pool_1: List[FloatSolution] = []
        for _ in range(pool_1_size):
            new_solution = self.problem.create_solution()
            new_solution = self.problem.evaluate(new_solution)
            evaluations += 1
            pool_1.append(new_solution)

            self.__update_extreme_values(new_solution)
            dr = directionalArchive[iniID]
            dr.curr_sol = new_solution
            iniID += 1
        # pool2
        pool_2: List[FloatSolution] = []
        for _ in range(pool_2_size):
            new_solution = self.problem.create_solution()
            new_solution = self.problem.evaluate(new_solution)
            evaluations += 1
            pool_2.append(new_solution)

            self.__update_extreme_values(new_solution)
            dr = directionalArchive[iniID]
            dr.curr_sol = new_solution
            iniID += 1
        # directional archive initialization
        pool_A: List[FloatSolution] = []
        while iniID < directionalArchiveSize:
            new_solution = self.problem.create_solution()
            new_solution = self.problem.evaluate(new_solution)
            evaluations += 1
            pool_A.append(new_solution)

            self.__update_extreme_values(new_solution)
            dr = directionalArchive[iniID]
            dr.curr_sol = new_solution
            iniID += 1

        mix = self.mix_interval
        h = HyperVolume(reference_point=[1] *
                        self.problem.number_of_objectives)

        insertionRate: List[float] = [0, 0, 0]
        bonusEvals: List[int] = [0, 0, nrOfDirectionalSolutionsToEvolve]
        testRun = True

        # record the generational HV of the initial population
        combiAll: List[FloatSolution] = []
        cGen = int(evaluations / self.report_interval)
        if cGen > 0:
            combiAll = pool_1 + pool_2 + pool_A
            combiAll = self.r.replace(
                combiAll[:pool_1_size + pool_2_size],
                combiAll[pool_1_size + pool_2_size:],
            )
            hval = h.compute([s.objectives for s in combiAll])
            for _ in range(cGen):
                generational_hv.append(hval)
            current_gen = cGen

        # the main loop of the algorithm
        while evaluations < self.max_evaluations:
            offspringPop1: List[FloatSolution] = []
            offspringPop2: List[FloatSolution] = []
            offspringPop3: List[FloatSolution] = []

            dirInsertPool1: List[FloatSolution] = []
            dirInsertPool2: List[FloatSolution] = []
            dirInsertPool3: List[FloatSolution] = []

            # evolve pool1 - using SPEA2 evolutionary model
            nfe: int = 0
            while nfe < (pool_1_size + bonusEvals[0]):
                parent_1[0] = selection_operator_1.execute(pool_1)
                parent_1[1] = selection_operator_1.execute(pool_1)

                child1a: FloatSolution = crossover_operator_1.execute(
                    parent_1)[0]
                child1a = mutation_operator_1.execute(child1a)

                child1a = self.problem.evaluate(child1a)
                evaluations += 1
                nfe += 1

                offspringPop1.append(child1a)
                dirInsertPool1.append(child1a)

            # evolve pool2 - using DEMO SP evolutionary model
            i: int = 0
            unselectedIDs: List[int] = []
            for ID in range(len(pool_2)):
                unselectedIDs.append(ID)

            nfe = 0
            while nfe < (pool_2_size + bonusEvals[1]):
                index = random.randint(0, len(unselectedIDs) - 1)
                i = unselectedIDs[index]
                unselectedIDs.pop(index)

                parent_2 = selection_operator_2.execute(pool_2)

                crossover_operator_2.current_individual = pool_2[i]
                child2 = crossover_operator_2.execute(parent_2)
                child2 = self.problem.evaluate(child2[0])

                evaluations += 1
                nfe += 1

                result = dominance.compare(pool_2[i], child2)

                if result == -1:  # solution i dominates child
                    offspringPop2.append(pool_2[i])
                elif result == 1:  # child dominates
                    offspringPop2.append(child2)
                else:  # the two solutions are non-dominated
                    offspringPop2.append(child2)
                    offspringPop2.append(pool_2[i])

                dirInsertPool2.append(child2)

                if len(unselectedIDs) == 0:
                    for ID in range(len(pool_2)):
                        unselectedIDs.append(random.randint(
                            0,
                            len(pool_2) - 1))

            # evolve pool3 - Directional Decomposition DE/rand/1/bin
            IDs = self.__compute_neighbourhood_Nfe_since_last_update(
                neighbourhoods, directionalArchive,
                nrOfDirectionalSolutionsToEvolve)

            nfe = 0
            for j in range(len(IDs)):
                if nfe < bonusEvals[2]:
                    nfe += 1
                else:
                    break

                cID = IDs[j]

                chosenSol: FloatSolution = None
                if directionalArchive[cID].curr_sol != None:
                    chosenSol = directionalArchive[cID].curr_sol
                else:
                    chosenSol = pool_1[0]
                    print("error!")

                parent_3: List[FloatSolution] = [None, None, None]

                r1 = random.randint(0, len(neighbourhoods[cID]) - 1)
                r2 = random.randint(0, len(neighbourhoods[cID]) - 1)
                r3 = random.randint(0, len(neighbourhoods[cID]) - 1)
                while r2 == r1:
                    r2 = random.randint(0, len(neighbourhoods[cID]) - 1)
                while r3 == r1 or r3 == r2:
                    r3 = random.randint(0, len(neighbourhoods[cID]) - 1)

                parent_3[0] = directionalArchive[r1].curr_sol
                parent_3[1] = directionalArchive[r2].curr_sol
                parent_3[2] = directionalArchive[r3].curr_sol

                crossover_operator_3.current_individual = chosenSol
                child3 = crossover_operator_3.execute(parent_3)[0]
                child3 = mutation_operator_1.execute(child3)

                child3 = self.problem.evaluate(child3)
                evaluations += 1

                dirInsertPool3.append(child3)

            # compute directional improvements
            # pool1
            improvements = 0
            for j in range(len(dirInsertPool1)):
                testSol = dirInsertPool1[j]
                self.__update_extreme_values(testSol)
                improvements += self.__update_neighbourhoods(
                    directionalArchive, testSol, nrOfReplacements)
            insertionRate[0] += (1.0 * improvements) / len(dirInsertPool1)

            # pool2
            improvements = 0
            for j in range(len(dirInsertPool2)):
                testSol = dirInsertPool2[j]
                self.__update_extreme_values(testSol)
                improvements += self.__update_neighbourhoods(
                    directionalArchive, testSol, nrOfReplacements)
            insertionRate[1] += (1.0 * improvements) / len(dirInsertPool2)

            # pool3
            improvements = 0
            for j in range(len(dirInsertPool3)):
                testSol = dirInsertPool3[j]
                self.__update_extreme_values(testSol)
                improvements += self.__update_neighbourhoods(
                    directionalArchive, testSol, nrOfReplacements)
            # on java, dividing a floating number by 0, returns NaN
            # on python, dividing a floating number by 0, returns an exception
            if len(dirInsertPool3) == 0:
                insertionRate[2] = None
            else:
                insertionRate[2] += (1.0 * improvements) / len(dirInsertPool3)

            for dr in directionalArchive:
                offspringPop3.append(dr.curr_sol)

            offspringPop1 = offspringPop1 + pool_1
            pool_1 = self.r.replace(offspringPop1[:pool_1_size],
                                    offspringPop1[pool_1_size:])
            pool_2 = self.r.replace(offspringPop2[:pool_2_size],
                                    offspringPop2[pool_2_size:])

            combi: List[FloatSolution] = []
            mix -= 1

            if mix == 0:
                mix = self.mix_interval
                combi = combi + pool_1 + pool_2 + offspringPop3
                print("Combi size: " + str(len(combi)))

                combi = self.r.replace(
                    combi[:nrOfDirectionalSolutionsToEvolve],
                    combi[nrOfDirectionalSolutionsToEvolve:],
                )

                insertionRate[0] /= self.mix_interval
                insertionRate[1] /= self.mix_interval
                if insertionRate[2] != None:
                    insertionRate[2] /= self.mix_interval
                """
                print(
                    "Insertion rates: "
                    + str(insertionRate[0])
                    + " - "
                    + str(insertionRate[1])
                    + " - "
                    + str(insertionRate[2])
                    + " - Test run:"
                    + str(testRun)
                )
                """
                if testRun:
                    if (insertionRate[0] > insertionRate[1]) and (
                            insertionRate[0] > insertionRate[2]):
                        print("SPEA2 win - bonus run!")
                        bonusEvals[0] = nrOfDirectionalSolutionsToEvolve
                        bonusEvals[1] = 0
                        bonusEvals[2] = 0
                    if (insertionRate[1] > insertionRate[0]) and (
                            insertionRate[1] > insertionRate[2]):
                        print("DE win - bonus run!")
                        bonusEvals[0] = 0
                        bonusEvals[1] = nrOfDirectionalSolutionsToEvolve
                        bonusEvals[2] = 0
                    if (insertionRate[2] > insertionRate[0]) and (
                            insertionRate[2] > insertionRate[1]):
                        print("Directional win - no bonus!")
                        bonusEvals[0] = 0
                        bonusEvals[1] = 0
                        bonusEvals[2] = nrOfDirectionalSolutionsToEvolve
                else:
                    print("Test run - no bonus!")
                    bonusEvals[0] = 0
                    bonusEvals[1] = 0
                    bonusEvals[2] = nrOfDirectionalSolutionsToEvolve

                testRun = not testRun

                insertionRate[0] = 0.0
                insertionRate[1] = 0.0
                insertionRate[2] = 0.0

                pool_1 = pool_1 + combi
                pool_2 = pool_2 + combi
                print("Sizes: " + str(len(pool_1)) + " " + str(len(pool_2)))

                pool_1 = self.r.replace(pool_1[:pool_1_size],
                                        pool_1[pool_1_size:])
                pool_2 = self.r.replace(pool_2[:pool_2_size],
                                        pool_2[pool_2_size:])

                self.__clear_Nfe_history(directionalArchive)

            hVal1 = h.compute([s.objectives for s in pool_1])
            hVal2 = h.compute([s.objectives for s in pool_2])
            hVal3 = h.compute([s.objectives for s in offspringPop3])

            newGen = int(evaluations / self.report_interval)

            if newGen > current_gen:
                print("Hypervolume: " + str(newGen) + " - " + str(hVal1) +
                      " - " + str(hVal2) + " - " + str(hVal3))
                combi = combi + pool_1 + pool_2 + offspringPop3
                combi = self.r.replace(combi[:self.population_size * 2],
                                       combi[self.population_size * 2:])
                hval = h.compute([s.objectives for s in combi])
                for j in range(current_gen, newGen):
                    generational_hv.append(hval)
                current_gen = newGen

        # return the final combined non-dominated set of maximum size = (populationSize * 2)
        combiAll: List[FloatSolution] = []
        combiAll = combiAll + pool_1 + pool_2 + pool_A
        combiAll = self.r.replace(combiAll[:self.population_size * 2],
                                  combiAll[self.population_size * 2:])
        return combiAll
Exemple #12
0
 def __init__(self, comparator: Comparator = DominanceComparator()):
     super(Ranking, self).__init__()
     self.number_of_comparisons = 0
     self.ranked_sublists = []
     self.comparator = comparator
Exemple #13
0
 def __init__(self, comparator: Comparator = DominanceComparator()):
     super(FastNonDominatedRanking, self).__init__(comparator)
Exemple #14
0
 def __init__(self, comparator: Comparator = DominanceComparator()):
     super(StrengthRanking, self).__init__(comparator)
Exemple #15
0
class SMPSO(ParticleSwarmOptimization):
    def __init__(
        self,
        problem: FloatProblem,
        swarm_size: int,
        mutation: Mutation,
        leaders: Optional[BoundedArchive],
        termination_criterion: TerminationCriterion = store.
        default_termination_criteria,
        swarm_generator: Generator = store.default_generator,
        swarm_evaluator: Evaluator = store.default_evaluator,
    ):
        """This class implements the SMPSO algorithm as described in

        * SMPSO: A new PSO-based metaheuristic for multi-objective optimization
        * MCDM 2009. DOI: `<http://dx.doi.org/10.1109/MCDM.2009.4938830/>`_.

        The implementation of SMPSO provided in jMetalPy follows the algorithm template described in the algorithm
        templates section of the documentation.

        :param problem: The problem to solve.
        :param swarm_size: Size of the swarm.
        :param max_evaluations: Maximum number of evaluations/iterations.
        :param mutation: Mutation operator (see :py:mod:`jmetal.operator.mutation`).
        :param leaders: Archive for leaders.
        """
        super(SMPSO, self).__init__(problem=problem, swarm_size=swarm_size)
        self.swarm_generator = swarm_generator
        self.swarm_evaluator = swarm_evaluator
        self.termination_criterion = termination_criterion
        self.observable.register(termination_criterion)
        self.mutation_operator = mutation
        self.leaders = leaders

        self.c1_min = 1.5
        self.c1_max = 2.5
        self.c2_min = 1.5
        self.c2_max = 2.5
        self.r1_min = 0.0
        self.r1_max = 1.0
        self.r2_min = 0.0
        self.r2_max = 1.0
        self.min_weight = 0.1
        self.max_weight = 0.1
        self.change_velocity1 = -1
        self.change_velocity2 = -1

        self.dominance_comparator = DominanceComparator()

        self.speed = numpy.zeros(
            (self.swarm_size, self.problem.number_of_variables), dtype=float)
        self.delta_max, self.delta_min = (
            numpy.empty(problem.number_of_variables),
            numpy.empty(problem.number_of_variables),
        )

    def create_initial_solutions(self) -> List[FloatSolution]:
        return [
            self.swarm_generator.new(self.problem)
            for _ in range(self.swarm_size)
        ]

    def evaluate(self, solution_list: List[FloatSolution]):
        return self.swarm_evaluator.evaluate(solution_list, self.problem)

    def stopping_condition_is_met(self) -> bool:
        return self.termination_criterion.is_met

    def initialize_global_best(self, swarm: List[FloatSolution]) -> None:
        for particle in swarm:
            self.leaders.add(copy(particle))

    def initialize_particle_best(self, swarm: List[FloatSolution]) -> None:
        for particle in swarm:
            particle.attributes["local_best"] = copy(particle)

    def initialize_velocity(self, swarm: List[FloatSolution]) -> None:
        for i in range(self.problem.number_of_variables):
            self.delta_max[i] = (self.problem.upper_bound[i] -
                                 self.problem.lower_bound[i]) / 2.0

        self.delta_min = -1.0 * self.delta_max

    def update_velocity(self, swarm: List[FloatSolution]) -> None:
        for i in range(self.swarm_size):
            best_particle = copy(swarm[i].attributes["local_best"])
            best_global = self.select_global_best()

            r1 = round(random.uniform(self.r1_min, self.r1_max), 1)
            r2 = round(random.uniform(self.r2_min, self.r2_max), 1)
            c1 = round(random.uniform(self.c1_min, self.c1_max), 1)
            c2 = round(random.uniform(self.c2_min, self.c2_max), 1)
            wmax = self.max_weight
            wmin = self.min_weight

            for var in range(swarm[i].number_of_variables):
                self.speed[i][var] = self.__velocity_constriction(
                    self.__constriction_coefficient(c1, c2) *
                    ((self.__inertia_weight(wmax) * self.speed[i][var]) +
                     (c1 * r1 *
                      (best_particle.variables[var] - swarm[i].variables[var]))
                     +
                     (c2 * r2 *
                      (best_global.variables[var] - swarm[i].variables[var]))),
                    self.delta_max,
                    self.delta_min,
                    var,
                )

    def update_position(self, swarm: List[FloatSolution]) -> None:
        for i in range(self.swarm_size):
            particle = swarm[i]

            for j in range(particle.number_of_variables):
                particle.variables[j] += self.speed[i][j]

                if particle.variables[j] < self.problem.lower_bound[j]:
                    particle.variables[j] = self.problem.lower_bound[j]
                    self.speed[i][j] *= self.change_velocity1

                if particle.variables[j] > self.problem.upper_bound[j]:
                    particle.variables[j] = self.problem.upper_bound[j]
                    self.speed[i][j] *= self.change_velocity2

    def update_global_best(self, swarm: List[FloatSolution]) -> None:
        for particle in swarm:
            self.leaders.add(copy(particle))

    def update_particle_best(self, swarm: List[FloatSolution]) -> None:
        for i in range(self.swarm_size):
            flag = self.dominance_comparator.compare(
                swarm[i], swarm[i].attributes["local_best"])
            if flag != 1:
                swarm[i].attributes["local_best"] = copy(swarm[i])

    def perturbation(self, swarm: List[FloatSolution]) -> None:
        for i in range(self.swarm_size):
            if (i % 6) == 0:
                self.mutation_operator.execute(swarm[i])

    def select_global_best(self) -> FloatSolution:
        leaders = self.leaders.solution_list

        if len(leaders) > 2:
            particles = random.sample(leaders, 2)

            if self.leaders.comparator.compare(particles[0], particles[1]) < 1:
                best_global = copy(particles[0])
            else:
                best_global = copy(particles[1])
        else:
            best_global = copy(self.leaders.solution_list[0])

        return best_global

    def __velocity_constriction(self, value: float, delta_max: [],
                                delta_min: [], variable_index: int) -> float:
        result = value
        if value > delta_max[variable_index]:
            result = delta_max[variable_index]
        if value < delta_min[variable_index]:
            result = delta_min[variable_index]

        return result

    def __inertia_weight(self, wmax: float):
        return wmax

    def __constriction_coefficient(self, c1: float, c2: float) -> float:
        rho = c1 + c2
        if rho <= 4:
            result = 1.0
        else:
            result = 2.0 / (2.0 - rho - sqrt(pow(rho, 2.0) - 4.0 * rho))

        return result

    def init_progress(self) -> None:
        self.evaluations = self.swarm_size
        self.leaders.compute_density_estimator()

        self.initialize_velocity(self.solutions)
        self.initialize_particle_best(self.solutions)
        self.initialize_global_best(self.solutions)

    def update_progress(self) -> None:
        self.evaluations += self.swarm_size
        self.leaders.compute_density_estimator()

        observable_data = self.get_observable_data()
        observable_data["SOLUTIONS"] = self.leaders.solution_list
        self.observable.notify_all(**observable_data)

    def get_result(self) -> List[FloatSolution]:
        return self.leaders.solution_list

    def get_name(self) -> str:
        return "SMPSO"
Exemple #16
0
class SMPSO(ParticleSwarmOptimization):
    def __init__(self,
                 problem: FloatProblem,
                 swarm_size: int,
                 max_evaluations: int,
                 mutation: Mutation[FloatSolution],
                 leaders: BoundedArchive[FloatSolution],
                 observable: Observable = DefaultObservable(),
                 evaluator: Evaluator[FloatSolution] = SequentialEvaluator[
                     FloatSolution]()):
        super(SMPSO, self).__init__()
        self.problem = problem
        self.swarm_size = swarm_size
        self.max_evaluations = max_evaluations
        self.mutation: Mutation[FloatSolution] = mutation
        self.leaders = leaders
        self.observable = observable
        self.evaluator = evaluator

        self.evaluations = 0

        self.c1_min = 1.5
        self.c1_max = 2.5
        self.c2_min = 1.5
        self.c2_max = 2.5

        self.min_weight = 0.1
        self.max_weight = 0.1

        self.change_velocity1 = -1
        self.change_velocity2 = -1

        self.dominance_comparator = DominanceComparator()

        self.speed = numpy.zeros(
            (self.swarm_size, self.problem.number_of_variables), dtype=float)
        self.delta_max = numpy.empty(problem.number_of_variables)
        self.delta_min = numpy.empty(problem.number_of_variables)
        for i in range(problem.number_of_variables):
            self.delta_max[i] = (self.problem.upper_bound[i] -
                                 self.problem.lower_bound[i]) / 2.0

        self.delta_min = -1.0 * self.delta_max

    def init_progress(self) -> None:
        self.evaluations = self.swarm_size
        self.leaders.compute_density_estimator()

    def update_progress(self) -> None:
        self.evaluations += self.swarm_size
        self.leaders.compute_density_estimator()

        observable_data = {
            'evaluations': self.evaluations,
            'population': self.swarm,
            'computing time': self.get_current_computing_time()
        }
        self.observable.notify_all(**observable_data)

    def is_stopping_condition_reached(self) -> bool:
        return self.evaluations >= self.max_evaluations

    def create_initial_swarm(self) -> List[FloatSolution]:
        swarm = []

        for i in range(self.swarm_size):
            swarm.append(self.problem.create_solution())

        return swarm

    def evaluate_swarm(self,
                       swarm: List[FloatSolution]) -> List[FloatSolution]:
        return self.evaluator.evaluate(swarm, self.problem)

    def initialize_global_best(self, swarm: List[FloatSolution]) -> None:
        for particle in self.swarm:
            self.leaders.add(particle)

    def initialize_particle_best(self, swarm: List[FloatSolution]) -> None:
        for particle in self.swarm:
            particle.attributes["local_best"] = copy(particle)

    def initialize_velocity(self, swarm: List[FloatSolution]) -> None:
        pass  # Velocity initialized in the constructor

    def update_velocity(self, swarm: List[FloatSolution]) -> None:
        for i in range(self.swarm_size):
            particle = copy(self.swarm[i])
            best_particle = copy(self.swarm[i].attributes["local_best"])
            best_global = self.__select_global_best()

            r1 = Random.random()
            r2 = Random.random()

            c1 = Random.uniform(self.c1_min, self.c1_max)
            c2 = Random.uniform(self.c2_min, self.c2_max)

            wmin = self.min_weight
            wmax = self.max_weight

            for var in range(self.problem.number_of_variables):
                self.speed[i][var] = \
                    self.__velocity_constriction(self.__constriction_coefficient(c1, c2) * \
                                                 (wmax * self.speed[i][var] +
                                                  c1 * r1 * (best_particle.variables[var] - particle.variables[var]) +
                                                  c2 * r2 * (best_global.variables[var] - particle.variables[var])),
                                                 var)

    def update_position(self, swarm: List[FloatSolution]) -> None:
        for i in range(self.swarm_size):
            particle = self.swarm[i]

            for j in particle.variables:
                particle.variables[j] += self.speed[i][j]

                if particle.variables[j] < self.problem.lower_bound[j]:
                    particle.variables[j] = self.problem.lower_bound[j]
                    self.speed[i][j] *= self.change_velocity1

                if particle.variables[j] > self.problem.upper_bound[j]:
                    particle.variables[j] = self.problem.upper_bound[j]
                    self.speed[i][j] *= self.change_velocity2

    def perturbation(self, swarm: List[FloatSolution]) -> None:
        for particle in self.swarm:
            self.mutation.execute(particle)

    def update_global_best(self, swarm: List[FloatSolution]) -> None:
        for particle in self.swarm:
            self.leaders.add(copy(particle))

    def update_particle_best(self, swarm: List[FloatSolution]) -> None:
        for i in range(self.swarm_size):
            flag = self.dominance_comparator.compare(
                self.swarm[i], self.swarm[i].attribute["local_best"])

            if flag is not 1:
                swarm[i].attributes["local_best"] = copy(self.swarm[i])

    def get_result(self) -> List[FloatSolution]:
        self.leaders.solution_list

    def __select_global_best(self) -> FloatSolution:
        #pos1 = Random.randint(0, len(self.leaders.solution_list) - 1)
        #pos2 = Random.randint(0, len(self.leaders.solution_list) - 1)
        best_global = None
        particles = Random.sample(self.leaders.solution_list, 2)
        if self.leaders.get_comparator().compare(particles[0],
                                                 particles[1]) < 1:
            best_global = copy(particles[0])
        else:
            best_global = copy(particles[1])

        return best_global

    def __velocity_constriction(self, value: float,
                                variable_index: int) -> float:
        result = None
        if value > self.delta_max[variable_index]:
            result = self.delta_max[variable_index]

        if value < self.delta_min[variable_index]:
            result = self.delta_min[variable_index]

        return result

    def __constriction_coefficient(self, c1: float, c2: float) -> float:
        result = 0.0
        rho = c1 + c2
        if rho <= 4:
            result = 1.0
        else:
            result = 2.0 / (2.0 - rho - numpy.sqrt(pow(rho, 2.0) - 4.0 * rho))

        return result
Exemple #17
0
from jmetal.util.termination_criterion import StoppingByEvaluations

if __name__ == '__main__':
    binary_string_length = 512
    problem = OneMax(binary_string_length)

    max_evaluations = 20000

    algorithm = NSGAII(
        problem=problem,
        population_size=100,
        offspring_population_size=1,
        mutation=BitFlipMutation(probability=1.0 / binary_string_length),
        crossover=SPXCrossover(probability=1.0),
        termination_criterion=StoppingByEvaluations(max=max_evaluations),
        dominance_comparator=DominanceComparator()
    )

    algorithm.observable.register(observer=PrintObjectivesObserver(1000))

    algorithm.run()
    front = algorithm.get_result()

    # Save results to file
    print_function_values_to_file(front, 'FUN.'+ algorithm.get_name()+"-"+problem.get_name())
    print_variables_to_file(front, 'VAR.' + algorithm.get_name()+"-"+problem.get_name())

    print('Algorithm (continuous problem): ' + algorithm.get_name())
    print('Problem: ' + problem.get_name())
    print('Computing time: ' + str(algorithm.total_computing_time))
Exemple #18
0
class StandardPSO(ParticleSwarmOptimization):
    def __init__(self,
                 problem: FloatProblem,
                 swarm_size: int,
                 leaders: Optional[BoundedArchive],
                 termination_criterion: TerminationCriterion = store.
                 default_termination_criteria,
                 swarm_generator: Generator = store.default_generator,
                 swarm_evaluator: Evaluator = store.default_evaluator,
                 omega: float = 0.8,
                 phi_p: float = 1.0,
                 phi_g: float = 1.0,
                 learning_rate: float = 1.0):
        """ This class implements a standard PSO algorithm.
        """
        super(StandardPSO, self).__init__(problem=problem,
                                          swarm_size=swarm_size)
        self.swarm_generator = swarm_generator
        self.swarm_evaluator = swarm_evaluator
        self.termination_criterion = termination_criterion
        self.observable.register(termination_criterion)
        self.leaders = leaders
        self.omega = omega  # Weight of previous speed.
        self.phi_p = phi_p  # How the difference between local best and particle influences the speed change.
        self.phi_g = phi_g  # How the difference between global best and particle influences the speed change.
        self.learning_rate = learning_rate  # How speed influences position change.

        self.dominance_comparator = DominanceComparator()

        self.speed = np.zeros(
            (self.swarm_size, self.problem.number_of_variables), dtype=float)

    def create_initial_solutions(self) -> List[FloatSolution]:
        return [
            self.swarm_generator.new(self.problem)
            for _ in range(self.swarm_size)
        ]

    def evaluate(self, solution_list: List[FloatSolution]):
        return self.swarm_evaluator.evaluate(solution_list, self.problem)

    def stopping_condition_is_met(self) -> bool:
        return self.termination_criterion.is_met

    def initialize_global_best(self, swarm: List[FloatSolution]) -> None:
        for particle in swarm:
            self.leaders.add(copy(particle))

    def initialize_particle_best(self, swarm: List[FloatSolution]) -> None:
        for particle in swarm:
            particle.attributes['local_best'] = copy(particle)

    def initialize_velocity(self, swarm: List[FloatSolution]) -> None:
        pass

    def update_velocity(self, swarm: List[FloatSolution]) -> None:
        for i in range(self.swarm_size):
            best_particle = copy(swarm[i].attributes['local_best'])
            best_global = self.select_global_best()

            for var in range(swarm[i].number_of_variables):
                r_p = random.random()
                r_g = random.random()
                self.speed[i][var] = self.omega * self.speed[i][var] + \
                                     self.phi_p * r_p * (best_particle.variables[var] - swarm[i].variables[var]) + \
                                     self.phi_g * r_g * (best_global.variables[var] - swarm[i].variables[var])

    def update_position(self, swarm: List[FloatSolution]) -> None:
        for i in range(self.swarm_size):
            particle = swarm[i]

            for j in range(particle.number_of_variables):
                particle.variables[j] += self.learning_rate * self.speed[i][j]

                if particle.variables[j] < self.problem.lower_bound[j]:
                    particle.variables[j] = self.problem.lower_bound[j]
                    self.speed[i][j] *= -1

                if particle.variables[j] > self.problem.upper_bound[j]:
                    particle.variables[j] = self.problem.upper_bound[j]
                    self.speed[i][j] *= -1

    def update_global_best(self, swarm: List[FloatSolution]) -> None:
        for particle in swarm:
            self.leaders.add(copy(particle))

    def update_particle_best(self, swarm: List[FloatSolution]) -> None:
        for i in range(self.swarm_size):
            flag = self.dominance_comparator.compare(
                swarm[i], swarm[i].attributes['local_best'])
            if flag != 1:
                swarm[i].attributes['local_best'] = copy(swarm[i])

    def select_global_best(self) -> FloatSolution:
        leaders = self.leaders.solution_list

        if len(leaders) > 2:
            particles = random.sample(leaders, 2)

            if self.leaders.comparator.compare(particles[0], particles[1]) < 1:
                best_global = copy(particles[0])
            else:
                best_global = copy(particles[1])
        else:
            best_global = copy(self.leaders.solution_list[0])

        return best_global

    def init_progress(self) -> None:
        self.evaluations = self.swarm_size
        self.leaders.compute_density_estimator()

        self.initialize_velocity(self.solutions)
        self.initialize_particle_best(self.solutions)
        self.initialize_global_best(self.solutions)

    def step(self):
        self.update_velocity(self.solutions)
        self.update_position(self.solutions)
        self.solutions = self.evaluate(self.solutions)
        self.update_global_best(self.solutions)
        self.update_particle_best(self.solutions)

    def update_progress(self) -> None:
        self.evaluations += self.swarm_size
        self.leaders.compute_density_estimator()

        observable_data = self.get_observable_data()
        observable_data['SOLUTIONS'] = self.leaders.solution_list
        self.observable.notify_all(**observable_data)

    def get_result(self) -> List[FloatSolution]:
        return self.leaders.solution_list[0]

    def get_name(self) -> str:
        return 'StandardPSO'

    def perturbation(self, swarm: List[FloatSolution]) -> None:
        pass