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
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
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
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
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
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
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
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