Exemple #1
0
    def execute(self, solution: IntegerSolution) -> IntegerSolution:
        Check.that(issubclass(type(solution), IntegerSolution),
                   "Solution type invalid")

        for i in range(solution.number_of_variables):
            if random.random() <= self.probability:
                y = solution.variables[i]
                yl, yu = solution.lower_bound[i], solution.upper_bound[i]

                if yl == yu:
                    y = yl
                else:
                    delta1 = (y - yl) / (yu - yl)
                    delta2 = (yu - y) / (yu - yl)
                    mut_pow = 1.0 / (self.distribution_index + 1.0)
                    rnd = random.random()
                    if rnd <= 0.5:
                        xy = 1.0 - delta1
                        val = 2.0 * rnd + (1.0 - 2.0 * rnd) * (xy**(
                            self.distribution_index + 1.0))
                        deltaq = val**mut_pow - 1.0
                    else:
                        xy = 1.0 - delta2
                        val = 2.0 * (1.0 - rnd) + 2.0 * (rnd - 0.5) * (xy**(
                            self.distribution_index + 1.0))
                        deltaq = 1.0 - val**mut_pow

                    y += deltaq * (yu - yl)
                    if y < solution.lower_bound[i]:
                        y = solution.lower_bound[i]
                    if y > solution.upper_bound[i]:
                        y = solution.upper_bound[i]

                solution.variables[i] = int(round(y))
        return solution
Exemple #2
0
    def execute(self, solution: FloatSolution) -> FloatSolution:
        Check.that(type(solution) is FloatSolution, "Solution type invalid")

        for i in range(solution.number_of_variables):
            if random.random() <= self.probability:
                rand = random.random()

                if rand <= 0.5:
                    tmp = self.__delta(
                        solution.upper_bound[i] - solution.variables[i],
                        self.perturbation)
                else:
                    tmp = self.__delta(
                        solution.lower_bound[i] - solution.variables[i],
                        self.perturbation)

                tmp += solution.variables[i]

                if tmp < solution.lower_bound[i]:
                    tmp = solution.lower_bound[i]
                elif tmp > solution.upper_bound[i]:
                    tmp = solution.upper_bound[i]

                solution.variables[i] = tmp

        return solution
Exemple #3
0
    def execute(self, solution: FloatSolution) -> FloatSolution:
        Check.that(issubclass(type(solution), FloatSolution), "Solution type invalid")
        for i in range(solution.number_of_variables):
            rand = random.random()

            if rand <= self.probability:
                y = solution.variables[i]
                yl, yu = solution.lower_bound[i], solution.upper_bound[i]

                if yl == yu:
                    y = yl
                else:
                    delta1 = (y - yl) / (yu - yl)
                    delta2 = (yu - y) / (yu - yl)
                    rnd = random.random()
                    mut_pow = 1.0 / (self.distribution_index + 1.0)
                    if rnd <= 0.5:
                        xy = 1.0 - delta1
                        val = 2.0 * rnd + (1.0 - 2.0 * rnd) * (pow(xy, self.distribution_index + 1.0))
                        deltaq = pow(val, mut_pow) - 1.0
                    else:
                        xy = 1.0 - delta2
                        val = 2.0 * (1.0 - rnd) + 2.0 * (rnd - 0.5) * (pow(xy, self.distribution_index + 1.0))
                        deltaq = 1.0 - pow(val, mut_pow)

                    y += deltaq * (yu - yl)
                    if y < solution.lower_bound[i]:
                        y = solution.lower_bound[i]
                    if y > solution.upper_bound[i]:
                        y = solution.upper_bound[i]

                solution.variables[i] = y

        return solution
Exemple #4
0
    def execute(self, solution: CompositeSolution) -> CompositeSolution:
        Check.is_not_none(solution)

        mutated_solution_components = []
        for i in range(solution.number_of_variables):
            mutated_solution_components.append(self.mutation_operators_list[i].execute(solution.variables[i]))

        return CompositeSolution(mutated_solution_components)
Exemple #5
0
    def execute(self, solution: FloatSolution) -> FloatSolution:
        Check.that(type(solution) is FloatSolution, "Solution type invalid")

        for i in range(solution.number_of_variables):
            rand = random.random()
            if rand <= self.probability:
                solution.variables[i] = solution.lower_bound[i] + \
                                        (solution.upper_bound[i] - solution.lower_bound[i]) * random.random()
        return solution
Exemple #6
0
def feasibility_ratio(solutions: [Solution]):
    """
    Returns the percentage of feasible solutions in a solution list
    :param solutions:
    :return:
    """
    Check.that(len(solutions) > 0, "The solution list is empty")

    return sum(1 for solution in solutions if is_feasible(solution)) / len(solutions)
Exemple #7
0
    def execute(self, solution: BinarySolution) -> BinarySolution:
        Check.that(type(solution) is BinarySolution, "Solution type invalid")

        for i in range(solution.number_of_variables):
            for j in range(len(solution.variables[i])):
                rand = random.random()
                if rand <= self.probability:
                    solution.variables[i][j] = True if solution.variables[i][j] is False else False

        return solution
Exemple #8
0
    def execute(self, solution: PermutationSolution) -> PermutationSolution:
        Check.that(type(solution) is PermutationSolution, "Solution type invalid")

        rand = random.random()

        if rand <= self.probability:
            pos_one, pos_two = random.sample(range(solution.number_of_variables - 1), 2)
            solution.variables[pos_one], solution.variables[pos_two] = \
                solution.variables[pos_two], solution.variables[pos_one]

        return solution
Exemple #9
0
    def execute(self, solutions: List[CompositeSolution]) -> List[CompositeSolution]:
        Check.is_not_none(solutions)
        Check.that(len(solutions) == 2, "The number of parents is not two: " + str(len(solutions)))

        offspring1 = []
        offspring2 = []

        number_of_solutions_in_composite_solution = solutions[0].number_of_variables

        for i in range(number_of_solutions_in_composite_solution):
            parents = [solutions[0].variables[i], solutions[1].variables[i]]
            children = self.crossover_operators_list[i].execute(parents)
            offspring1.append(children[0])
            offspring2.append(children[1])

        return [CompositeSolution(offspring1), CompositeSolution(offspring2)]
Exemple #10
0
    def execute(self, solution: PermutationSolution) -> PermutationSolution:
        Check.that(
            type(solution) is PermutationSolution, "Solution type invalid")
        rand = random.random()

        if rand <= self.probability:

            if self.randMut == 1:
                # pos_one, pos_two = random.sample(range(solution.number_of_variables - 1), 2)
                # there is no use for the -1 above in the original algorithm
                pos_one, pos_two = random.sample(
                    range(solution.number_of_variables), 2)

            elif self.randMut == 2:
                path = solution.variables
                pos_one, pos_two, length = bestMutation2(
                    self.D, self.n, path, self.first)

            solution.variables[pos_one], solution.variables[
                pos_two] = solution.variables[pos_two], solution.variables[
                    pos_one]

        return solution
Exemple #11
0
    def __init__(self, mutation_operator_list:[Mutation]):
        super(CompositeMutation,self).__init__(probability=1.0)

        Check.is_not_none(mutation_operator_list)
        Check.collection_is_not_empty(mutation_operator_list)

        self.mutation_operators_list = []
        for operator in mutation_operator_list:
            Check.that(issubclass(operator.__class__, Mutation), "Object is not a subclass of Mutation")
            self.mutation_operators_list.append(operator)
Exemple #12
0
    def __init__(self, crossover_operator_list:[Crossover]):
        super(CompositeCrossover, self).__init__(probability=1.0)

        Check.is_not_none(crossover_operator_list)
        Check.collection_is_not_empty(crossover_operator_list)

        self.crossover_operators_list = []
        for operator in crossover_operator_list:
            Check.that(issubclass(operator.__class__, Crossover), "Object is not a subclass of Crossover")
            self.crossover_operators_list.append(operator)
Exemple #13
0
    def __init__(self, solutions: List[Solution]):
        super(CompositeSolution,
              self).__init__(len(solutions), solutions[0].number_of_objectives,
                             solutions[0].number_of_constraints)
        Check.is_not_none(solutions)
        Check.collection_is_not_empty(solutions)

        for solution in solutions:
            Check.that(
                solution.number_of_objectives ==
                solutions[0].number_of_objectives,
                "The solutions in the list must have the same number of objectives: "
                + str(solutions[0].number_of_objectives))
            Check.that(
                solution.number_of_constraints ==
                solutions[0].number_of_constraints,
                "The solutions in the list must have the same number of constraints: "
                + str(solutions[0].number_of_constraints))

        self.variables = solutions
Exemple #14
0
    def execute(self, parents: List[BinarySolution]) -> List[BinarySolution]:
        Check.that(type(parents[0]) is BinarySolution, "Solution type invalid")
        Check.that(type(parents[1]) is BinarySolution, "Solution type invalid")
        Check.that(
            len(parents) == 2,
            'The number of parents is not two: {}'.format(len(parents)))

        offspring = [copy.deepcopy(parents[0]), copy.deepcopy(parents[1])]
        rand = random.random()

        if rand <= self.probability:
            # 1. Get the total number of bits
            total_number_of_bits = parents[0].get_total_number_of_bits()

            # 2. Calculate the point to make the crossover
            crossover_point = random.randrange(0, total_number_of_bits)

            # 3. Compute the variable containing the crossover bit
            variable_to_cut = 0
            bits_count = len(parents[1].variables[variable_to_cut])
            while bits_count < (crossover_point + 1):
                variable_to_cut += 1
                bits_count += len(parents[1].variables[variable_to_cut])

            # 4. Compute the bit into the selected variable
            diff = bits_count - crossover_point
            crossover_point_in_variable = len(
                parents[1].variables[variable_to_cut]) - diff

            # 5. Apply the crossover to the variable
            bitset1 = copy.copy(parents[0].variables[variable_to_cut])
            bitset2 = copy.copy(parents[1].variables[variable_to_cut])

            for i in range(crossover_point_in_variable, len(bitset1)):
                swap = bitset1[i]
                bitset1[i] = bitset2[i]
                bitset2[i] = swap

            offspring[0].variables[variable_to_cut] = bitset1
            offspring[1].variables[variable_to_cut] = bitset2

            # 6. Apply the crossover to the other variables
            for i in range(variable_to_cut + 1,
                           parents[0].number_of_variables):
                offspring[0].variables[i] = copy.deepcopy(
                    parents[1].variables[i])
                offspring[1].variables[i] = copy.deepcopy(
                    parents[0].variables[i])

        return offspring
Exemple #15
0
 def test_should_that_raise_an_exception_if_the_expression_is_false(
         self) -> None:
     with self.assertRaises(InvalidConditionException):
         Check.that(False, "The expression is false")
Exemple #16
0
 def test_should_is_value_in_range_raise_an_exception_if_the_value_is_higher_than_the_upper_bound(
         self) -> None:
     with self.assertRaises(ValueOutOfRangeException):
         Check.value_is_in_range(7, 3, 5)
Exemple #17
0
 def test_should_is_valid_probability_raise_an_exception_if_the_value_is_higher_than_one(
         self) -> None:
     with self.assertRaises(InvalidProbabilityValueException):
         Check.probability_is_valid(1.1)
Exemple #18
0
 def test_should_is_valid_probability_raise_an_exception_if_the_value_is_negative(
         self) -> None:
     with self.assertRaises(InvalidProbabilityValueException):
         Check.probability_is_valid(-1.0)
Exemple #19
0
    def execute(self, parents: List[IntegerSolution]) -> List[IntegerSolution]:
        Check.that(
            type(parents[0]) is IntegerSolution, "Solution type invalid")
        Check.that(
            type(parents[1]) is IntegerSolution, "Solution type invalid")
        Check.that(
            len(parents) == 2,
            'The number of parents is not two: {}'.format(len(parents)))

        offspring = [copy.deepcopy(parents[0]), copy.deepcopy(parents[1])]
        rand = random.random()

        if rand <= self.probability:
            for i in range(parents[0].number_of_variables):
                value_x1, value_x2 = parents[0].variables[i], parents[
                    1].variables[i]

                if random.random() <= 0.5:
                    if abs(value_x1 - value_x2) > self.__EPS:
                        if value_x1 < value_x2:
                            y1, y2 = value_x1, value_x2
                        else:
                            y1, y2 = value_x2, value_x1

                        lower_bound, upper_bound = parents[0].lower_bound[
                            i], parents[1].upper_bound[i]

                        beta = 1.0 + (2.0 * (y1 - lower_bound) / (y2 - y1))
                        alpha = 2.0 - pow(beta,
                                          -(self.distribution_index + 1.0))

                        rand = random.random()
                        if rand <= (1.0 / alpha):
                            betaq = pow(rand * alpha,
                                        (1.0 /
                                         (self.distribution_index + 1.0)))
                        else:
                            betaq = pow(1.0 / (2.0 - rand * alpha),
                                        1.0 / (self.distribution_index + 1.0))

                        c1 = 0.5 * (y1 + y2 - betaq * (y2 - y1))
                        beta = 1.0 + (2.0 * (upper_bound - y2) / (y2 - y1))
                        alpha = 2.0 - pow(beta,
                                          -(self.distribution_index + 1.0))

                        if rand <= (1.0 / alpha):
                            betaq = pow(
                                (rand * alpha),
                                (1.0 / (self.distribution_index + 1.0)))
                        else:
                            betaq = pow(1.0 / (2.0 - rand * alpha),
                                        1.0 / (self.distribution_index + 1.0))

                        c2 = 0.5 * (y1 + y2 + betaq * (y2 - y1))

                        if c1 < lower_bound:
                            c1 = lower_bound
                        if c2 < lower_bound:
                            c2 = lower_bound
                        if c1 > upper_bound:
                            c1 = upper_bound
                        if c2 > upper_bound:
                            c2 = upper_bound

                        if random.random() <= 0.5:
                            offspring[0].variables[i] = int(c2)
                            offspring[1].variables[i] = int(c1)
                        else:
                            offspring[0].variables[i] = int(c1)
                            offspring[1].variables[i] = int(c2)
                    else:
                        offspring[0].variables[i] = value_x1
                        offspring[1].variables[i] = value_x2
                else:
                    offspring[0].variables[i] = value_x1
                    offspring[1].variables[i] = value_x2
        return offspring
Exemple #20
0
 def test_should_is_not_null_raise_an_exception(self) -> None:
     with self.assertRaises(NoneParameterException):
         Check.is_not_none(None)
    def execute(self, solution: FloatSolution) -> FloatSolution:
        Check.that(issubclass(type(solution), FloatSolution),
                   "Solution type invalid")
        copied_solution = solution.__copy__()
        if copied_solution not in self.follow_solutions:
            self.follow_solutions.append(copied_solution)
        self.follow_solutions.sort(key=lambda x: x.objectives[0],
                                   reverse=False)
        self.follow_solutions = self.follow_solutions[:self.others_number]

        if (self.avg_counter % self.others_number == 0):
            self.avg_counter = 0

        self.avg = (self.avg * self.avg_counter +
                    copied_solution.objectives[0]) / (self.avg_counter + 1)
        self.avg_counter += 1
        self.steps += 1

        vector = self.get_follow_vector()

        for i in range(solution.number_of_variables):
            rand = random.random()

            # v not enough solutions to calculate avg
            if rand <= self.probability or self.steps < self.others_number:
                y = solution.variables[i]
                yl, yu = solution.lower_bound[i], solution.upper_bound[i]

                if yl == yu:
                    y = yl
                else:
                    delta1 = (y - yl) / (yu - yl)
                    delta2 = (yu - y) / (yu - yl)
                    rnd = random.random()
                    mut_pow = 1.0 / (self.distribution_index + 1.0)
                    if rnd <= 0.5:
                        xy = 1.0 - delta1
                        val = 2.0 * rnd + (1.0 - 2.0 * rnd) * (pow(
                            xy, self.distribution_index + 1.0))
                        deltaq = pow(val, mut_pow) - 1.0
                    else:
                        xy = 1.0 - delta2
                        val = 2.0 * (1.0 - rnd) + 2.0 * (rnd - 0.5) * (pow(
                            xy, self.distribution_index + 1.0))
                        deltaq = 1.0 - pow(val, mut_pow)

                    y += deltaq * (yu - yl)
                    if y < solution.lower_bound[i]:
                        y = solution.lower_bound[i]
                    if y > solution.upper_bound[i]:
                        y = solution.upper_bound[i]

                solution.variables[i] = y
            elif rand <= self.probability + self.look_at_others_probability:
                diff = vector[i] - solution.variables[i]
                calculated_value = solution.variables[i] + 0.1 * diff
                solution.variables[i] = max(
                    min(calculated_value, solution.upper_bound[i]),
                    solution.lower_bound[i])

        return solution
Exemple #22
0
    def get_neighbors(self, index: int,
                      solution_list: List[Solution]) -> List[Solution]:
        Check.is_not_null(solution_list)
        Check.that(len(solution_list) != 0, "The list of solutions is empty")

        return self.__find_neighbors(solution_list, index, self.neighborhood)