示例#1
0
def initialize_randomly(problem, population_size):
    """
    Initialize a population of solutions (feasible solution) for an evolutionary algorithm
    
    Required:
    
    @ problem - problem's build solution function knows how to create an individual in accordance with the encoding.
    
    @ population_size - to define the size of the population to be returned. 
    """
    solution_list = []

    i = 0
    # generate a population of admissible solutions (individuals)
    for _ in range(0, population_size):
        s = problem.build_solution()

        # check if the solution is admissible
        while not problem.is_admissible(s):
            s = problem.build_solution()

        s.id = [0, i]
        i += 1
        problem.evaluate_solution(s)

        solution_list.append(s)

    # print([x.fitness for x in solution_list])

    population = Population(problem=problem,
                            maximum_size=population_size,
                            solution_list=solution_list)

    return population
示例#2
0
def initialize_using_hc(problem, population_size):
    """
    Initialize a population of solutions (feasible solution) for an evolutionary algorithm using Hill Climbing

    Required:
    @ problem - problem's build solution function knows how to create an individual in accordance with the encoding.
    @ population_size - to define the size of the population to be returned.
    """
    solution_list = []

    # generate a population of admissible solutions (individuals)
    for i in range(0, population_size):
        s = problem.build_solution(method='Hill Climbing')

        # check if the solution is admissible
        while not problem.is_admissible(s):
            s = problem.build_solution(method='Hill Climbing')

        s.id = [0, i]

        problem.evaluate_solution(s)

        solution_list.append(s)

    population = Population(
        problem = problem,
        maximum_size = population_size,
        solution_list = solution_list
    )

    return population
示例#3
0
def initialize_using_multiple(problem, population_size):
    """
    Initialize a population of solutions (feasible solution) for an evolutionary algorithm using multiple algorithms:
    - One solution from greedy initialization
    - One solution from hill climbing initialization
    - The rest of the solutions from random initialization

    Required:
    @ problem - problem's build solution function knows how to create an individual in accordance with the encoding.
    @ population_size - to define the size of the population to be returned.
    """
    solution_list = []

    i = 0
    # generate a population of admissible solutions (individuals)
    if population_size >= 10:
        while i in range(0, population_size):
            if i > 10:
                s = problem.build_solution(method='Random')
            elif i < 5:
                s = problem.build_solution(method='Greedy')
            else:
                s = problem.build_solution(method='Hill Climbing')

            if problem.is_admissible(s):
                s.id = [0, i]

                problem.evaluate_solution(s)

                solution_list.append(s)

                i += 1
    else:
        while i in range(0, population_size):
            if i > 2:
                s = problem.build_solution(method='Random')
            elif i == 0:
                s = problem.build_solution(method='Greedy')
            else:
                s = problem.build_solution(method='Hill Climbing')

            if problem.is_admissible(s):
                s.id = [0, i]

                problem.evaluate_solution(s)

                solution_list.append(s)

                i += 1

    population = Population(
        problem = problem,
        maximum_size = population_size,
        solution_list = solution_list
    )

    return population
示例#4
0
def initialize_using_sa(problem, population_size):
    params = {"Internal-Loop-Iterations": 20, "Max-Iterations": 250}
    sa = SimulatedAnnealing(
        problem_instance=problem,
        neighborhood_function=problem.get_neighbors,
        feedback=None,
        config=params,
    )
    solution_list = []

    population = Population(problem=problem,
                            maximum_size=population_size,
                            solution_list=solution_list)

    return population
示例#5
0
def initialize_using_sa(problem, population_size, params={}):
    """
    Initialize a population of solutions (feasible solution) for an evolutionary algorithm
    
    Required:
    
    @ problem - problem's build solution function knows how to create an individual in accordance with the encoding.
    
    @ population_size - to define the size of the population to be returned. 

    @ params - the parameters to create the Simulated Annealing object (default: empty dictionary)
    """

    solution_list = []

    neighborhood_function = params["Neighborhood-Function"]

    # generate a population of admissible solutions (individuals)
    for _ in range(0, population_size):
        # initialize the Simulated Annealing class
        # notice that we need to create a new Simulated Annealing object for every iteration
        # because the initial value of C has to be always the same
        sa = SimulatedAnnealing(problem_instance=problem,
                                neighborhood_function=neighborhood_function,
                                params=params)

        # search for the optimal solution using Simulated Annealing
        s = sa.search()

        # there's no need to check if the solution is admissible
        # because Simulated Annealing already generates admissible solutions

        # get the fitness of the solution
        problem.evaluate_solution(s)

        # add the solution to the population
        solution_list.append(s)

    # create the Population object
    population = Population(problem=problem,
                            maximum_size=population_size,
                            solution_list=solution_list)

    return population
示例#6
0
def initialize_using_ta(problem, population_size):
    params = {"Internal-Loop-Iterations": 50, "Max-Iterations": 800}
    ta = ThresholdAcceptance(
        problem_instance=problem,
        neighborhood_function=problem.get_single_neighbor,
        feedback=None,
        config=params,
    )
    solution_list = []
    for i in range(0, population_size):
        nn = ta.search()
        nn.id = [0, i]
        solution_list.append(nn)

    population = Population(problem=problem,
                            maximum_size=population_size,
                            solution_list=solution_list)

    return population
示例#7
0
def initialize_using_ts(problem, population_size, params={}):
    """
    Initialize a population of solutions (feasible solution) for an evolutionary algorithm
    
    Required:
    
    @ problem - problem's build solution function knows how to create an individual in accordance with the encoding.
    
    @ population_size - to define the size of the population to be returned. 

    @ params - the parameters to create the Tabu Search object (default: empty dictionary)
    """
    solution_list = []

    neighborhood_function = params["Neighborhood-Function"]

    # initialize the Tabu Search class
    ts = TabuSearch(problem_instance=problem,
                    neighborhood_function=neighborhood_function,
                    params=params)

    # generate a population of admissible solutions (individuals)
    for _ in range(0, population_size):
        # find the optimal solution using Tabu Search
        s = ts.search()

        # there's no need to check if the solution is admissible
        # because Tabu Search already generates admissible solutions

        # get the fitness of the solution
        problem.evaluate_solution(s)

        # add the solution to the population
        solution_list.append(s)

    # create the Population object
    population = Population(problem=problem,
                            maximum_size=population_size,
                            solution_list=solution_list)

    return population
示例#8
0
def initialize_using_hc(problem, population_size):
    params = {
        "Maximum-Iterations": 200,
        "Stop-Conditions": "Classical",
        "Neighborhood-Size": -1,
    }

    hc = HillClimbing(
        problem_instance=problem,
        neighborhood_function=problem.get_neighbors,
        feedback=None,
        params=params,
    )
    solution_list = []
    for i in range(0, population_size):
        nn = hc.search()
        nn.id = [0, i]
        solution_list.append(nn)

    population = Population(problem=problem,
                            maximum_size=population_size,
                            solution_list=solution_list)

    return population
    def search(self):
        """
            Genetic Algorithm - Search Algorithm
            1. Initial population

            2. Repeat n generations )(#1 loop )
                
                2.1. Repeat until generate the next generation (#2 loop )
                    1. Selection
                    2. Try Apply Crossover (depends on the crossover probability)
                    3. Try Apply Mutation (depends on the mutation probability)
                
                2.2. Replacement

            3. Return the best solution    
        """
        problem         = self._problem_instance
        select          = self._selection_approach
        cross           = self._crossover_approach
        mutate          = self._mutation_approach
        replace         = self._replacement_approach
        is_admissible   = self._problem_instance.is_admissible

        self._generation = 0
        self._notify(message="Genetic Algorithm")

        # 1. Initial population
        self._population = self._initialize(problem, self._population_size)
        self._fittest = self._population.fittest
        self._best_solution = self._fittest


        self._notify()

        #2. Repeat n generations )(#1 loop )
        for self._generation in range(1, self._number_of_generations + 1):
            new_population = Population(problem=problem, maximum_size=self._population_size, solution_list=[])
            i = 0

            # 2.1. Repeat until generate the next generation (#2 loop )
            while new_population.has_space:
                # 2.1.1. Selection
                parent1, parent2 = select(self._population, problem.objective, self._params)
                offspring1 = deepcopy(parent1)  # parent1.clone()
                offspring2 = deepcopy(parent2)  # parent2.clone()
                # 2.1.2. Try Apply Crossover (depends on the crossover probability)
                if self.apply_crossover: 
                    offspring1, offspring2 = cross(problem, parent1, parent2)
                    offspring1.id = [self._generation, i]
                    i += 1
                    offspring2.id = [self._generation, i]
                    #i += 2
                    i += 1

                # 2.1.3. Try Apply Mutation (depends on the mutation probability)
                if self.apply_mutation: 
                    offspring1 = mutate(problem, offspring1)
                    offspring1.id = [self._generation, i]
                    i += 1
                if self.apply_mutation: 
                    offspring2 = mutate(problem, offspring2)
                    offspring2.id = [self._generation, i]
                    i += 1

                # in our opinion the id's should be added after applying crossover and/or mutation, but we will not
                # change because it is not relevant

                # add the offsprings in the new population (New Generation)
                if new_population.has_space and is_admissible(offspring1):
                    problem.evaluate_solution(offspring1)
                    new_population.solutions.append(offspring1)
                
                if new_population.has_space and is_admissible(offspring2):
                    problem.evaluate_solution(offspring2)
                    new_population.solutions.append(offspring2)
                    #print(f'Added O2 - {offspring2.id}-{offspring2.representation}')

            self._population = replace(problem, self._population, new_population)

            self._fittest = self._population.fittest

            self.find_best_solution()

            self._notify()

        self._notify(message="Fittest Solution")
        return self._fittest    
示例#10
0
    def search(self):
        """
            Genetic Algorithm - Search Algorithm
            1. Initial population

            2. Repeat n generations )(#1 loop )
                
                2.1. Repeat until generate the next generation (#2 loop )
                    1. Selection
                    2. Try Apply Crossover (depends on the crossover probability)
                    3. Try Apply Mutation (depends on the mutation probability)
                
                2.2. Replacement

            3. Return the best solution    
        """
        problem = self._problem_instance
        select = self._selection_approach
        cross = self._crossover_approach
        mutate = self._mutation_approach
        replace = self._replacement_approach
        is_admissible = self._problem_instance.is_admissible

        self._generation = 0
        self._notify(message="Genetic Algorithm")

        # 1. Initial population
        self._population = self._initialize(problem, self._population_size)
        self._fittest = self._population.fittest

        self._notify()
        self._store_population()

        # 2. Repeat n generations )(#1 loop )
        for self._generation in range(1, self._number_of_generations + 1):

            new_population = Population(problem=problem,
                                        maximum_size=self._population_size,
                                        solution_list=[])
            i = 0

            # 2.1. Repeat until generate the next generation (#2 loop )
            while new_population.has_space:
                # 2.1.1. Selection
                parent1, parent2 = select(self._population, problem.objective,
                                          self._params)
                offspring1 = problem.fast_solution_copy(
                    parent1.representation)  # parent1.clone()
                offspring2 = problem.fast_solution_copy(
                    parent2.representation)  # parent1.clone()
                # offspring1 = problem.build_solution(parent1.representation[:]) # parent2.clone()
                # offspring2 = problem.build_solution(parent2.representation[:]) # parent2.clone()
                # 2.1.2. Try Apply Crossover (depends on the crossover probability)
                if self.apply_crossover:
                    offspring1, offspring2 = cross(
                        problem, offspring1, offspring2
                    )  # I guess this was wrong here, I've replaced 'solution' by 'offspring'
                    offspring1.id = [self._generation, i]
                    i += 1
                    offspring2.id = [self._generation, i]
                    i += 1

                # 2.1.3. Try Apply Mutation (depends on the mutation probability)
                if self.apply_mutation:
                    offspring1 = mutate(problem, offspring1)
                    offspring1.id = [self._generation, i]
                    i += 1
                if self.apply_mutation:
                    offspring2 = mutate(problem, offspring2)
                    offspring2.id = [self._generation, i]
                    i += 1

                # # Don't allow Twins
                # solReps = [x.representation for x in new_population.solutions]
                # if offspring1.representation in solReps:
                #     offspring1 = problem.get_single_neighbor(offspring1, problem)

                # if offspring2.representation in solReps:
                #     offspring2 = problem.get_single_neighbor(offspring2, problem)

                # add the offsprings in the new population (New Generation)
                if new_population.has_space and is_admissible(offspring1):
                    problem.evaluate_solution(offspring1)
                    new_population.solutions.append(offspring1)

                if new_population.has_space and is_admissible(offspring2):
                    problem.evaluate_solution(offspring2)
                    new_population.solutions.append(offspring2)
                    # print(f'Added O2 - {offspring2.id}-{offspring2.representation}')

            self._population = replace(problem, self._population,
                                       new_population)

            self._fittest = self._population.fittest
            self._notify()
            self._store_population()

        self._notify(message="Fittest Solution")
        return self._fittest