def change(d): ## this function returns new state for dimension d ## depending on acting forces of other masses class TempWrapper: def __init__(self, pd, dacceleration): self.pd = pd self.fitness = Fitness(values=(dacceleration,)) pass ## get all forces which act from all other participating masses to mass p ## for all vectors of force save force value and point in discrete dimension where it is dforces = [TempWrapper(mass[d], f[d]/p.mass) for f, mass in fvm[p.uid]] #dforces = [tw for tw in dforces if tw.fitness.values[0] < 0] ## case without changing of current place in space ## acts like yet another divicion for roulette # not_changing = sum([mass.mass for _, mass in fvm[p.uid]])/(p.mass*len(fvm[p.uid])) # if not_changing < 1: # dforces.append(TempWrapper(p[d], sum([x.fitness.values[0] for x in dforces]) * not_changing)) if sum([t.fitness.values[0] for t in dforces]) == 0: ## corner case, when all accelerations(fitnesses) equal 0 return p[d] else: el = tools.selRoulette(dforces, 1)[0] # el = tools.selTournament(dforces, 1, 2)[0] return el.pd
def roulette(ctx, pop): for p in pop: p.fitness = Fitness((1/-1*p.fitness)*100) result = tools.selRoulette(pop, len(pop)) for p in pop: p.fitness = (1/(p.fitness.values[0]/100)*-1) return result
def roulette(ctx, pop): for p in pop: p.fitness = Fitness((1 / -1 * p.fitness) * 100) result = tools.selRoulette(pop, len(pop)) for p in pop: p.fitness = (1 / (p.fitness.values[0] / 100) * -1) return result
def select(pop,pop_size) : # Roulette selection offsprings = list(map(toolbox.clone,tools.selRoulette(pop,pop_size))) # Elite selection max_os_fit = np.max([ind.fitness.values[0] for ind in offsprings]) max_pop_fit = np.max([ind.fitness.values[0] for ind in pop]) replace_choices = list(range(pop_size)) if max_pop_fit > max_os_fit : for ind in sorted(pop, key=lambda x: x.fitness.values[0],reverse=True) : if ind.fitness.values[0] > max_os_fit : choice = np.random.choice(replace_choices) offsprings[choice] = tools.clone(ind) replace_choices.remove(choice) # To Stop replacing the best ones that we already replaced else : break; return offsprings
def runGA(visable=True): # Read your ANN structure from "config.py": num_inputs = config.nnet['n_inputs'] num_hidden_nodes = config.nnet['n_h_neurons'] num_outputs = config.nnet['n_outputs'] my_game = game.Game() creator.create("FitnessMax", base.Fitness, weights=(1.0,)) creator.create("Individual", list, fitness=creator.FitnessMax) toolbox = base.Toolbox() # Prepare your individuals below. # Let's assume that you have a one-hidden layer neural network with 2 hidden nodes: # You would need to define a list of floating numbers of size: 16 (10+6) toolbox.register("attr_real", random.random) toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_real, n=((num_inputs+1)*num_hidden_nodes)+((num_hidden_nodes+1)*num_outputs)) toolbox.register("population", tools.initRepeat, list, toolbox.individual, n=config.game['n_agents']) # Fitness Evaluation: def evalANN(individual): return my_game.get_ind_fitness(individual), # comma at the end is necessarys since DEAP stores fitness values as a tuple toolbox.register("evaluate", evalANN) # Define your selection, crossover and mutation operators below: toolbox.register("mate", tools.cxBlend, alpha=0.05) toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=0.2, indpb=0.05) toolbox.register("select", tools.selTournament, tournsize=3) stats = tools.Statistics(key=lambda ind: ind.fitness.values) stats.register("average", numpy.mean) stats.register("standard dev", numpy.std) stats.register("min", numpy.min) stats.register("max", numpy.max) logbook = tools.Logbook() # Define EA parameters: n_gen, pop_size, prob_xover, prob_mut: # You can define them in the "config.py" file too. CXPB, MUTPB, NGEN = 0.5, 0.2, 300 pop = toolbox.population() # Create initial population (each individual represents an agent or ANN): for ind in pop: # ind (individual) corresponds to the list of weights # ANN class is initialized with ANN parameters and the list of weights ann = ANN(num_inputs, num_hidden_nodes, num_outputs, ind) my_game.add_agent(ann) # Let's evaluate the fitness of each individual. # First, simulation should be run! my_game.game_loop(visable) # Set it to "False" for headless mode; #recommended for training, otherwise learning process will be very slow! # Let's collect the fitness values from the simulation using fitnesses = list(map(toolbox.evaluate, pop)) for ind, fit in zip(pop, fitnesses): ind.fitness.values = fit record = stats.compile(pop) logbook.record(gen=my_game.generation, **record) for g in range(1, NGEN): my_game.generation += 1 my_game.reset()# # Start creating the children (or offspring) # First, Apply selection: offspring = toolbox.select(pop, len(pop)) # Apply variations (xover and mutation), Ex: algorithms.varAnd(?, ?, ?, ?) offspring = algorithms.varAnd(offspring, toolbox, CXPB, MUTPB) # Repeat the process of fitness evaluation below. You need to put the recently # created offspring-ANN's into the game (Line 55-69) and extract their fitness values: for ind in offspring: # ind (individual) corresponds to the list of weights # ANN class is initialized with ANN parameters and the list of weights ann = ANN(num_inputs, num_hidden_nodes, num_outputs, ind) my_game.add_agent(ann) # Let's evaluate the fitness of each individual. # First, simulation should be run! my_game.game_loop(visable) # Set it to "False" for headless mode; #recommended for training, otherwise learning process will be very slow! # Let's collect the fitness values from the simulation using fitnesses = list(map(toolbox.evaluate, offspring)) for ind, fit in zip(offspring, fitnesses): ind.fitness.values = fit # One way of implementing elitism is to combine parents and children to give them equal chance to compete: # For example: pop[:] = pop + offspring # Otherwise you can select the parents of the generation from the offspring population only: pop[:] = offspring offspring.remove(tools.selRoulette(offspring, 1)[0]) pop[:] = offspring + tools.selBest(pop, 1) record = stats.compile(pop) logbook.record(gen=my_game.generation, **record) # This is the end of the "for" loop (end of generations!) logbook.header = "gen", "average", "standard dev", "max", "min" return [logbook, tools.selBest(pop, 1)] ##print "Training is over" ###raw_input("Training is over!") ##while True: ## my_game.game_loop(True) ## ## pygame.quit()
def defaultSel(population, howMany): return tools.selRoulette(individuals=population, k=howMany, fit_attr='fitness')
def selectReproduction(pop): return tools.selRoulette(pop, len(pop))
# Evaluate the entire population fitnesses = map(toolbox.evaluate, pop) for ind, fit in zip(pop, fitnesses): ind.fitness.values = fit CXPB, MUTPB, NGEN = 0.5, 0.2, 100 for g in range(NGEN): image_copy = np.ndarray.copy(image) operators.apply_noise(image_copy, pop[0]) img = (np.expand_dims(image_copy, 0)) predictions = model.predict(img) print(np.argmax(predictions)) print(test_labels[0]) # Select the next generation individuals offspring = tools.selRoulette(pop, len(pop)) # Clone the selected individuals offspring = list(map(toolbox.clone, offspring)) # Apply crossover and mutation on the offspring for child1, child2 in zip(offspring[::2], offspring[1::2]): if np.random.random() < CXPB: fitness_child1 = child1.fitness.values[0] fitness_child2 = child2.fitness.values[0] tools.cxUniform(child1, child2, fitness_child1 / (fitness_child1 + fitness_child2)) del child1.fitness.values del child2.fitness.values for mutant in offspring: if np.random.random() < MUTPB: operators.mutate(mutant, 0.5, DELTA)
def genetic(rts, cpus): def func_X(a, b): """ length of messages transmitted from a towards b or from b towards a """ comm_load = 0 if "p" in a: for p in a["p"]: if p["id"] == b["id"]: comm_load += p["payload"] # This part consideres incoming msgs from other tasks (so that task is the successor, b->a) # if "p" in b: # for p in b["p"]: # if p["id"] == a["id"]: # comm_load += p["payload"] return comm_load def func_Xc(cpu_h, cpu_k): """ length of all messages (in bytes) to be transmitted between processors h and k through the network """ summ = 0 for task_h in cpu_h["tasks"]: for task_j in cpu_k["tasks"]: summ += func_X(task_h, task_j) return summ def func_Y(i, rts): """ load of the communication control network that the task i produces """ comm_load = 0 other_tasks = [t for t in rts if t is not i] for j in other_tasks: comm_load += func_X(i, j) return comm_load def func_Vp(cpus): """ total amount of information to be transferred over the network """ summ = 0 for cpu in cpus.values(): other_cpus = [c for c in cpus.values() if c is not cpu] for other_cpu in other_cpus: summ += func_Xc(cpu, other_cpu) return summ def func_B(rts): """ Total amount of data to be transferred between predecessor and successors throught the network """ summ = 0 for task in rts: summ += func_Y(task, rts) return summ def func_cost_p(rts, cpus): return func_Vp(cpus) / func_B(rts) def get_cpu_alloc(individual): cpus_alloc = dict() for cpu_id in cpus.keys(): cpus_alloc[cpu_id] = {"tasks": [], "uf": 0} # tasks assigned to this cpu # A stack is assembled containing the tasks ordered by the value of the gene in decreasing order. task_stack = [] for task_id, gene in enumerate(individual): task_stack.append((gene, rts[task_id])) task_stack.sort(key=lambda t: t[0], reverse=True) # sort by gene value # clear previous task assignation #for cpu in cpus_alloc.values(): # cpu["tasks"].clear() # aux list -- for easy sorting cpu_stack = [cpu for cpu in cpus_alloc.values()] # partition for _, max_task in task_stack: if "cpu" in max_task: cpu_id = max_task["cpu"] cpus_alloc[cpu_id]["tasks"].append(max_task) else: # create auxiliary stack with all task j that communicate with i aux_stack = [] # add the succesors if "p" in max_task: for p in max_task["p"]: for task in rts: if task["id"] == p["id"]: aux_stack.append((func_Y(task, rts), task)) # add other tasks that communicate with the task (the task will be the succesor) # for task in [t for t in rts if t is not max_task]: # if "p" in task: # for p in task["p"]: # if p["id"] == max_task["id"]: # aux_stack.append((func_Y(task, rts), task)) cpu_a = None # order by func_y if aux_stack: aux_stack.sort(key=lambda t: t[0], reverse=True) aux_max_task = aux_stack[0] # find the cpu at which the aux_max_task is allocated for cpu in cpus_alloc.values(): if aux_max_task in cpu["tasks"]: cpu_a = cpu # if not aux_stack or cpu_a is None: if cpu_a is None: # update uf factors and allocate task to cpu with min uf for cpu in cpus_alloc.values(): cpu["uf"] = sum([t["uf"] for t in cpu["tasks"]]) cpu_stack.sort(key=lambda c: c["uf"]) cpu_stack[0]["tasks"].append(max_task) else: cpu_a["tasks"].append(max_task) # return the task allocation performed using the chromosome return cpus_alloc def cost(individual): # apply the cost function to the chromosome based in the cpu allocation produced return func_cost_p(rts, get_cpu_alloc(individual)) def init_population(individual, rts, n): # generate initial population p_list = [] # generate first chromosome chromosome = [] for task in rts: g = func_Y(task, rts) * int(random.uniform(0, 1) * len(rts)) chromosome.append(g) p_list.append(chromosome) # remaining chromosomes for _ in range(n - 1): new_chromosome = [] nu = max(chromosome) / 10 for g1 in chromosome: g2 = abs(g1 + int(random.uniform(-nu, nu))) new_chromosome.append(g2) p_list.append(new_chromosome) return [individual(c) for c in p_list] creator.create("FitnessMin", base.Fitness, weights=(-1.0,)) # Defines each individual as a list creator.create("Individual", list, fitness=creator.FitnessMin) toolbox = base.Toolbox() # Initialize the population toolbox.register("population", init_population, creator.Individual, rts) # Applies a gaussian mutation of mean mu and standard deviation sigma on the input individual. The indpb argument # is the probability of each attribute to be mutated. toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=1, indpb=0.01) # Use map to pass values toolbox.register("evaluate", cost) # Generate the initial population (first generation) population = toolbox.population(n=6) # Evaluate the first generation fitnesses = map(toolbox.evaluate, population) for ind, fit in zip(population, fitnesses): ind.fitness.values = (fit,) for _ in range(120): # generations # Select the k worst individuals among the input individuals. population_worst = tools.selWorst(population, int(len(population) / 2)) # Perform a roulette selection and apply a crossover to the selected individuals for _ in range(len(population_worst)): pair = tools.selRoulette(population_worst, 2) # roulette tools.cxOnePoint(pair[0], pair[1]) # one point crossover # Mutate for c in population_worst: toolbox.mutate(c) del c.fitness.values # delete the fitness value # Evaluate again the entire population fitnesses = map(toolbox.evaluate, population) for ind, fit in zip(population, fitnesses): ind.fitness.values = (fit,) # print the final population print_population(population) # memory constraint verification for i, ind in enumerate(population): valid_cpu = True ch_cpus = get_cpu_alloc(ind) for cpuid, cpu in ch_cpus.items(): if cpus[cpuid]["capacity"] < sum([t["r"] for t in cpu["tasks"]]): valid_cpu = False if valid_cpu: print_results(i, rts, ch_cpus) else: print("Chromosome {0} -- Invalid assignation found.".format(i))