예제 #1
0
def create_individual(dados,size):
    while True:
        my_individual = Individual()
        for i in range(size):
            holder_schedule = Schedule(dados,i)
            try:
                holder_schedule.initialize()
            except:
                pass
            holder_schedule.initialize()
            my_individual.add_schedule(holder_schedule)
        if my_individual.get_total_classes_num() == 120:
            return my_individual
예제 #2
0
def create_individual(size):
    dados   = Dados()
    counter = 0
    my_individual = Individual()
    while counter < 120:
        for i in range(size):
            holder_schedule = Schedule(dados,i)
            holder_schedule.initialize()
            print('\n\n',holder_schedule.get_classes_num(),'\n\n')
            if holder_schedule.get_classes_num() == 20:
                my_individual.add_schedule(holder_schedule)
                counter += holder_schedule.get_classes_num()
    return my_individual
예제 #3
0
def crossover(nodes, parents, pc=0.7):
    offsprings = []
    for i, indv in enumerate(parents):
        if random.random() > pc:
            while True:
                tmp = copy.deepcopy(indv)
                chromosome = exchange_chromosome(nodes, tmp.chromosome)
                if nodes.is_feasible(chromosome):
                    break
            offspring = Individual(i + 1, chromosome)
        else:
            offspring = Individual(i + 1, indv.chromosome)
        offsprings.append(offspring)
    return offsprings
예제 #4
0
def weightVectors(N):  #Obtains the weight vector's
    #First, we are gonna do the weights. We need N vectors of two elements
    poblation = []  #Return an array of individuals with their weights
    equidistance = 1 / N  #The distance between the first element of the vectors
    j = 0  #Loop's initialization

    while j < N:  #A loop for the vectors
        if (len(poblation) < 1):  #First iteration
            weights = [0.0]
        else:
            weights = [(len(poblation)) * equidistance]

        weights.append(1 - weights[0])  #The y element of the weigths vector
        ind = Individual(weights)
        poblation.append(ind)
        j = j + 1

    return poblation
예제 #5
0
def create_individual(dados, size):
    while True:
        my_individual = Individual()
        for i in range(size):
            holder_schedule = Schedule(dados,i)
            holder_schedule.initialize()
            if holder_schedule.get_classes_num() != 20:
                continue
            else:
                my_individual.add_schedule(holder_schedule)
        print('\n\n\n', my_individual.get_total_classes_num(),'\n\n')
        if my_individual.get_total_classes_num() == 120:
            return my_individual
예제 #6
0
def pareto_ranking(nodes, parents, factor=10):
    community_fitness = functions.community_fitness(nodes, parents)
    offsprings = []
    fitnesses = [element[1] for element in community_fitness]
    fitnesses = fitnesses / np.sum(fitnesses)

    def random_pick(some_list, probabilities):
        x = random.uniform(0, 1)
        cumulative_probability = 0.0
        for item, item_probability in zip(some_list, probabilities):
            cumulative_probability += item_probability
            if x < cumulative_probability: break
        return item

    for i in range(len(parents)):
        offspring = random_pick(parents, fitnesses)
        offspring = Individual(i + 1, offspring.chromosome)
        offsprings.append(offspring)

    return offsprings
예제 #7
0
def differentialEvolution(ind, F, GR, z, individuals, minValue, maxValue):
    #F -> Mutation rate [0,2]
    #GR -> Recombination rate (0,1)

    poblationIndex = ind.neighbors  #Index of the neighbors in the individuals vector
    poblation = []
    for p in poblationIndex:
        poblation.append(individuals[p])
    NP = len(poblation)

    #Mutation
    #Target vectors
    xa = random.choice(poblation)
    xb = random.choice(poblation)
    while xb == xa:
        xb = random.choice(poblation)
    xc = random.choice(poblation)
    while xc == xb or xc == xa:
        xc = random.choice(poblation)

    i = 0  #Loop's iterator
    ngp = []
    while i < len(xa.chromosome):
        op = xc.chromosome[i] + F * (xa.chromosome[i] - xb.chromosome[i])
        if (op < minValue or op > maxValue):  #We don't want negative values
            op = random.uniform(minValue, maxValue)
        ngp.append(op)
        i = i + 1

    #Recombination
    j = 0  #Loop's iterator
    tgp = []
    k = random.randint(0, len(poblation) - 1)  #We choose a neighbor randomly
    xgp = poblation[k]
    while j < len(xa.chromosome):
        rand = random.uniform(0.01, 1)
        if (rand > GR):
            tgp.append(xgp.chromosome[j])
        else:
            tgp.append(ngp[j])
        j = j + 1

    #Selection
    l = 0  #Loop's iterator
    while l < len(poblation):  #It is the moment to update the neighbors
        #We have tgp (the chromosome)
        cNeighbor = poblation[l]
        cWeights = cNeighbor.weights
        newInd = Individual(cWeights)
        newInd.add_chromosome(tgp)
        newInd.neighbors = cNeighbor.neighbors
        newInd = functionZDT3(newInd)  #Obtains the fitness of the new element
        z = updateZ(z, newInd)  #Update the z vector

        absxf1 = cNeighbor.f1 - z[0]
        xg1 = cWeights[0] * abs(absxf1)
        absxf2 = cNeighbor.f2 - z[1]
        xg2 = cWeights[1] * abs(absxf2)
        gtex = max(xg1, xg2)  #Getting the Tchebychef function of the neighbor

        absyf1 = newInd.f1 - z[0]
        yg1 = cWeights[0] * abs(absyf1)
        absyf2 = newInd.f2 - z[1]
        yg2 = cWeights[1] * abs(absyf2)
        gtey = max(yg1, yg2)  #Getting the Tchebychef function of the newInd

        if (gtey <= gtex):
            index = poblationIndex[l]
            individuals[index] = newInd
        l = l + 1

    return [individuals, z]  #We can use it in the future
def gen_indv(cross_type, mut_type, num_stations, num_operations):

    code = [randint(0, num_stations - 1) for i in range(num_operations)]
    return Individual(num_operations, num_stations, code, cross_type=cross_type, mut_type=mut_type)
def engine(k, num_operations, graph, times, num_stations=10,
           pop_size=100, iterations=100,
           perc_elitism=0.1, perc_mat=0.1, sel_type='roulette', cross_type='SP',
           mutation_rate=0.05, mut_type='random'
           ):
    """
    Performs the genetic algorithm

    Args:
        k (float): Time of the slowest station
        num_operations (int): Number of operations
        graph (dict): Precedence graph of the problem
        times (list(float)): List containing the times of the stations
        num_stations (int): Number of stations
        pop_size (int): Number of individuals in each population
        iterations (int): Number of generations
        perc_elitism (float): Percentage of the best individuals of the current generation that will carry over the next
                              Default to 0.1
        perc_mat (float): Percentage of the best individuals of the current generation that will have a chance to be
                          selected as a parent. Default to 0.1
        sel_type (String): Selection method that will be used.
                           OPTIONS: - roulette (default)
                                    - tournament
                                    - rank
        cross_type (String): Crossover operator that will be used
                             OPTIONS : - SP -> Single point crossover (default)
                                       - DP -> Double point crossover
                                       - UX -> Uniform crossover
        mutation_rate (float): Mutation rate. Default to 0.05
        mut_type (String): Mutation operator
                           OPTIONS: - random -> Random mutation (gives a random value to a random element) (default)
                                    - heur -> Heuristic mutation
                                    - swap -> Swap mutation (select 2 elemtents and swaps them)
                                    - scramble -> scramble subset
                                    - inverse -> Inverse subset

    Returns:
        (Individual): Best individual
        (list(float)): Fitness of the bests solutions for every generation. Useful for plotting
        (list(float)): Mean fitness of the population for every generation. Useful for plotting
    """

    population = rank_population(k, graph, times,
                                 create_population(pop_size, cross_type, mut_type, num_stations, num_operations),
                                 0)

    best = []
    mean = []

    select = eval('select_by_' + sel_type)

    for i in range(iterations):

        best.append(population[0].fitness)
        mean.append(reduce(lambda x, y: x + y.fitness, population, 0)/pop_size)
        if population[0].gen < i - 50:
            break

        # Elitism
        new_generation = population[:int(perc_elitism*pop_size)]

        # Selection
        the_chosen_ones = select(population[:int(pop_size * perc_mat)], num=(pop_size - int(perc_elitism*pop_size)))

        mut = 2
        # Crossover
        for j in range(0, len(the_chosen_ones), 2):

            if j == len(the_chosen_ones) - 1:
                new_generation.append(Individual(num_operations, num_stations, copy.deepcopy(the_chosen_ones[j].code),
                                                 cross_type=cross_type, mut_type=mut_type))
                mut = 1
            else:
                new_generation.extend(the_chosen_ones[j].crossover(the_chosen_ones[j+1]))

            # Mutation
            for indv in new_generation[-mut:]:
                if random() < mutation_rate:
                    if mut_type == 'heur':
                        indv.mutate(graph)
                    else:
                        indv.mutate()

        # Evaluation
        population = rank_population(k, graph, times, new_generation, i)

    if (population[0].calc_violations(graph)) > 0:
        print("SOLUCION NO VALIDA: ", population[0].calc_violations(graph))

    print(f"Parameters of the best solution : {[i+1 for i in population[0].code]}")
    print(f"Best solution reached after {population[0].gen} generations.")
    print(f"Fitness of the best solution : {population[0].fitness}")

    return population[0], best, mean
예제 #10
0
def create_individual(nodes, index):
    customers_id_list = nodes.get_customers_id_list()
    deliver_list = customers_id_list[:int(len(customers_id_list) / 2)]
    n_vehicle = len(nodes.vehicles)

    def create_route_from_nodes(route_nodes):
        if len(route_nodes) != 0:
            route = []
            valid = []
            valid.append(route_nodes[0])
            for _ in range(len(route_nodes) * 2):
                route.append(random.sample(valid, 1)[0])
                the_last = route[-1]

                if the_last in route_nodes:
                    the_last_index_nodes = route_nodes.index(the_last)
                    if the_last_index_nodes < (len(route_nodes) - 1):
                        valid.append(route_nodes[the_last_index_nodes + 1])
                    valid.append(the_last + len(deliver_list))
                valid.remove(the_last)
            route = {(index + 1): node_id
                     for (index, node_id) in enumerate(route)}
        else:
            route = {}
        return route

    chromosome = []
    tmp_deliver_list = copy.deepcopy(deliver_list)
    customer_size = len(tmp_deliver_list)

    for i in range(n_vehicle - 1):
        while True:
            limitation = min(30, len(tmp_deliver_list))
            min_val = min(2, limitation)
            max_val = max(2, limitation)
            route_nodes_size = random.randint(min_val, max_val)
            if limitation <= 1:
                route_nodes_size = len(tmp_deliver_list)
            if i >= 12:
                route_nodes_size = random.randint(0, limitation)
            route_nodes = random.sample(tmp_deliver_list, route_nodes_size)
            route = create_route_from_nodes(route_nodes)

            if not nodes.is_feasible_route(route, i):
                continue
            else:
                tmp_deliver_list = [
                    element for element in tmp_deliver_list
                    if element not in route_nodes
                ]
                break
        chromosome.append(route)
        customer_size = customer_size - route_nodes_size

    j = 0
    while True:
        j += 1
        if j > 200:
            return None
        route_nodes = random.sample(tmp_deliver_list, len(tmp_deliver_list))
        route = create_route_from_nodes(route_nodes)
        if nodes.is_feasible_route(route, i + 1):
            break
    chromosome.append(route)
    individual = Individual(index, chromosome)
    return individual