Esempio n. 1
0
class Terminator(TerminationCriterion):
    # initialize
    def __init__(self, tolerance, max_evaluation):
        super().__init__()
        # store the parameters
        self.max_evaluation = max_evaluation
        # self.timeout = timeout
        self.tolerance = tolerance
        # prepare members
        self.evaluations = 0
        # self.seconds = 0.0
        self.counter = 0
        self.front = NonDominatedSolutionsArchive()
        self.last_violation = None
        self.last_front_size = None

    # check violation
    def violation_count(self, solutions):
        count = 0
        for solution in solutions:
            if not all([c >= 0.0 for c in solution.constraints]):
                count += 1
        return count

    # update the front
    def update_front(self, solutions):
        new_solution_num = 0
        for solution in solutions:
            # solution.objectives = [round(o, 0) for o in solution.objectives]
            if self.front.add(solution):
                new_solution_num += 1
        return new_solution_num

    # update
    def update(self, *args, **kwargs):
        self.evaluations = kwargs['EVALUATIONS']
        if self.evaluations % 500 == 0:
            print(self.evaluations)
        # self.seconds = kwargs['COMPUTING_TIME']
        solutions = kwargs['SOLUTIONS']
        # check 
        front_size = self.update_front(solutions)
        violation = self.violation_count(solutions)
        if self.last_front_size == self.front.size() and self.last_violation == violation:
            self.counter += 1
        else:
            self.counter = 0
        # update
        self.last_front_size = self.front.size()
        self.last_violation = violation
        print('counter: ', self.counter, ' front_size: ', self.front.size(), ' violation: ', violation)
        # print(self.violation_count(solutions))

    # finish condition
    @property
    def is_met(self):
        # if self.evaluations >= self.max_evaluation:
        #     return True
        # return self.seconds >= self.timeout or self.counter >= self.tolerance
        return self.front.size() == POPULATION_SIZE and self.counter >= self.tolerance
Esempio n. 2
0
    def __init__(
        self, problem: Problem[S], termination_criterion: TerminationCriterion = store.default_termination_criteria
    ):
        super().__init__()
        self.problem = problem
        self.termination_criterion = termination_criterion
        self.observable.register(termination_criterion)

        self.archive = NonDominatedSolutionsArchive()
Esempio n. 3
0
    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)
Esempio n. 4
0
class RandomSearch(Algorithm[S, R]):
    def __init__(self,
                 problem: Problem[S],
                 termination_criterion: TerminationCriterion = store.
                 default_termination_criteria):
        super().__init__()
        self.problem = problem
        self.termination_criterion = termination_criterion
        self.observable.register(termination_criterion)

        self.archive = NonDominatedSolutionsArchive()

    def get_observable_data(self) -> dict:
        ctime = time.time() - self.start_computing_time
        return {
            'PROBLEM': self.problem,
            'EVALUATIONS': self.evaluations,
            'SOLUTIONS': self.get_result(),
            'COMPUTING_TIME': ctime
        }

    def create_initial_solutions(self) -> List[S]:
        return [self.problem.create_solution()]

    def evaluate(self, solution_list: List[S]) -> List[S]:
        return [self.problem.evaluate(solution_list[0])]

    def init_progress(self) -> None:
        self.evaluations = 1

        observable_data = self.get_observable_data()
        self.observable.notify_all(**observable_data)

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

    def step(self) -> None:
        new_solution = self.problem.create_solution()
        self.problem.evaluate(new_solution)
        self.archive.add(new_solution)

    def update_progress(self) -> None:
        self.evaluations += 1

        observable_data = self.get_observable_data()
        self.observable.notify_all(**observable_data)

    def get_result(self) -> List[S]:
        return self.archive.solution_list

    def get_name(self) -> str:
        return 'Random Search'

    @property
    def label(self) -> str:
        return f'{self.get_name()}.{self.problem.get_name()}'
Esempio n. 5
0
 def build_true_front(\
     true_front : NonDominatedSolutionsArchive, \
     true_front_map : Dict[str, Solution], \
     solution_list : List[Solution]) -> Tuple[NonDominatedSolutionsArchive, Dict[str, Solution]]:
     # make true front
     for solution in solution_list:
         true_front.add(solution)
         true_front_map[str(solution.objectives)] = solution
     # return them
     return true_front, true_front_map
Esempio n. 6
0
 def __init__(self, tolerance, max_evaluation):
     super().__init__()
     # store the parameters
     self.max_evaluation = max_evaluation
     # self.timeout = timeout
     self.tolerance = tolerance
     # prepare members
     self.evaluations = 0
     # self.seconds = 0.0
     self.counter = 0
     self.front = NonDominatedSolutionsArchive()
     self.last_violation = None
     self.last_front_size = None
Esempio n. 7
0
def get_non_dominated_solutions(solutions: List[Solution]) -> List[Solution]:
    archive: Archive = NonDominatedSolutionsArchive()

    for solution in solutions:
        archive.add(solution)

    return archive.solution_list
Esempio n. 8
0
 def build_each_true_front(self, name: str) -> None:
     self.__true_front[name] = NonDominatedSolutionsArchive()
     self.__true_front_map[name] = dict()
     for ite in range(self.ite_num):
         solutions = self.result[name][str(ite)]['solutions']
         self.__true_front[name], self.__true_front_map[name] = \
                 self.build_true_front(self.__true_front[name], self.__true_front_map[name], solutions)
Esempio n. 9
0
 def build_all_true_front(self) -> None:
     for project_name, name_list in self.which_names.items():
         self.__true_front[project_name] = NonDominatedSolutionsArchive()
         self.__true_front_map[project_name] = dict()
         for name in name_list:
             for ite in range(self.ite_num):
                 solutions = self.result[name][str(ite)]['solutions']
                 self.__true_front[project_name], self.__true_front_map[project_name] = \
                     self.build_true_front(self.__true_front[project_name], self.__true_front_map[project_name], solutions)
Esempio n. 10
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"
Esempio n. 11
0
 def setUp(self):
     self.archive = NonDominatedSolutionsArchive()
Esempio n. 12
0
class NonDominatedSolutionListArchiveTestCases(unittest.TestCase):
    def setUp(self):
        self.archive = NonDominatedSolutionsArchive()

    def test_should_constructor_create_a_non_null_object(self):
        self.assertIsNotNone(self.archive)

    def test_should_adding_one_solution_work_properly(self):
        solution = Solution(1, 1)
        self.archive.add(solution)
        self.assertEqual(1, self.archive.size())
        self.assertEqual(solution, self.archive.solution_list[0])

    def test_should_adding_two_solutions_work_properly_if_one_is_dominated(self):
        dominated_solution = Solution(1, 2)
        dominated_solution.objectives = [2.0, 2.0]

        dominant_solution = Solution(1, 2)
        dominant_solution.objectives = [1.0, 1.0]

        self.archive.add(dominated_solution)
        self.archive.add(dominant_solution)

        self.assertEqual(1, self.archive.size())
        self.assertEqual(dominant_solution, self.archive.solution_list[0])

    def test_should_adding_two_solutions_work_properly_if_both_are_non_dominated(self):
        solution1 = Solution(1, 2)
        solution1.objectives = [1.0, 0.0]

        solution2 = Solution(1, 2)
        solution2.objectives = [0.0, 1.0]

        self.archive.add(solution1)
        self.archive.add(solution2)

        self.assertEqual(2, self.archive.size())
        self.assertTrue(solution1 in self.archive.solution_list and solution2 in self.archive.solution_list)

    def test_should_adding_four_solutions_work_properly_if_one_dominates_the_others(self):
        solution1 = Solution(1, 2)
        solution1.objectives = [1.0, 1.0]

        solution2 = Solution(1, 2)
        solution2.objectives = [0.0, 2.0]

        solution3 = Solution(1, 2)
        solution3.objectives = [0.5, 1.5]

        solution4 = Solution(1, 2)
        solution4.objectives = [0.0, 0.0]

        self.archive.add(solution1)
        self.archive.add(solution2)
        self.archive.add(solution3)
        self.archive.add(solution4)

        self.assertEqual(1, self.archive.size())
        self.assertEqual(solution4, self.archive.solution_list[0])

    def test_should_adding_three_solutions_work_properly_if_two_of_them_are_equal(self):
        solution1 = Solution(1, 2)
        solution1.objectives = [1.0, 1.0]

        solution2 = Solution(1, 2)
        solution2.objectives = [0.0, 2.0]

        solution3 = Solution(1, 2)
        solution3.objectives = [1.0, 1.0]

        self.archive.add(solution1)
        self.archive.add(solution2)
        result = self.archive.add(solution3)

        self.assertEqual(2, self.archive.size())
        self.assertFalse(result)
        self.assertTrue(solution1 in self.archive.solution_list or solution3 in self.archive.solution_list)