From e772e7cc818384d252a108be16f9da005ca09ec1 Mon Sep 17 00:00:00 2001 From: Matheus Duarte Date: Tue, 11 Oct 2022 10:06:32 -0300 Subject: [PATCH 1/2] Create README.md --- README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..91c6640 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# genetic_algorithm From b98514bd86b59b5d3d20d3456f077f8a5cab8cb3 Mon Sep 17 00:00:00 2001 From: Matheus Duarte Date: Tue, 11 Oct 2022 14:13:29 -0300 Subject: [PATCH 2/2] first commit --- __pycache__/bag.cpython-310.pyc | Bin 0 -> 461 bytes __pycache__/ga.cpython-310.pyc | Bin 0 -> 2140 bytes bag.py | 5 ++++ ga.py | 37 ++++++++++++++++++++++++----- main.py | 40 +++++++++++++++++++++----------- 5 files changed, 63 insertions(+), 19 deletions(-) create mode 100644 __pycache__/bag.cpython-310.pyc create mode 100644 __pycache__/ga.cpython-310.pyc create mode 100644 bag.py diff --git a/__pycache__/bag.cpython-310.pyc b/__pycache__/bag.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d996ff296a2283b82f9780691e48d31d9b79867d GIT binary patch literal 461 zcmY*UJ5Izf5FOiLiK1+?Lfj!uQqmx_;@fS5Xwq0AHX$O3gPjzhRIr!f2wcT2x1eGs ztCg0K=8b2@@A=s*ml0rmo15|j>kl=DA+T9vx)s75C{S#R`N?xo{2mff;{0E5?ADm> z1VKa26y#hn#kY_PC6E(%aamMlfct&WnTS`I?i68S6G)giBAWyvSAbNuNrVqN(`p~| z+8KY;n{F^D893cMS<#{agV_^rKU7K=jbvL-|*4US<(w!da zQWi~RY&|@;*<(?q{hJS^th;)Ul5`zuE!cuZ>^;U0r2FLtpU0bB(P}AuBxP&V*w8ta v@^vhl-NuHIyDL!B^wPL_i5eq)i$vA*c4#G5wBj^Gxbaa>P2^Fg7B#0|lG!<2arg}wF zQ*~%+YC$zlSX@_&s)=?%wbZg&IpJ|b@mLvpmmv{F1#ZX&IjO{9_YEb1Z(c*zv77ZToh6seYg@G=; zdse7VCL)vk-9$y;Phgg(Fbu%Soomx+DtX>6O>d#Yq8OXrZfb4d5-^EX}v?({8kNiyg0DT4Q5tkl}T98=cuyzri{8{BP`N zs@Q=H>$hrhFJHU;)yEoQ^ncGYw=uyV(dKbL#x-|ln#*UHyU@K$`nOOW-<$i-e_r0a z{hD3KYVVMKjVhA5gn3pXbSn7BO4gt%*eSxKWCucV3gZ4~jUJl3@?ckNetaC)4C50_e!P3VODGtlNK>>&=a!9yHj>6}&B5Uaew*Ej`% zc@L^<*@%D=SP%6VbUakxLOuf6Q>oz9g!fDUE^rb$4|rpY`~&zN=pDitDELCj{@np0wZY${pzcVSG-lZl#$T4fHl;y2)RF UHF#AtL`$}Aw*veVn$6q)0&AMk3jhEB literal 0 HcmV?d00001 diff --git a/bag.py b/bag.py new file mode 100644 index 0000000..4b33e71 --- /dev/null +++ b/bag.py @@ -0,0 +1,5 @@ +class Bag: + def __init__(self, nome, peso, ponto): + self.nome = nome + self.peso = peso + self.ponto = ponto \ No newline at end of file diff --git a/ga.py b/ga.py index 4efbc7a..200f475 100644 --- a/ga.py +++ b/ga.py @@ -1,13 +1,38 @@ import sys +from typing import List import numpy as np +from bag import Bag -def cal_pop_fitness(equation_inputs, pop): + +def cal_pop_fitness(itens: List[Bag], pop): # Cálculo do ‘fitness’ de cada solução na população atual # A função ‘fitness’ calcula a soma dos produtos entre cada # entrada e seu peso correspondente - return np.sum(pop * equation_inputs, axis=1) + pontos = get_pontos(itens) + pesos = get_pesos(itens) + + soma_pontos = np.sum(pop * pontos, axis=1) + soma_pesos = np.sum(pop * pesos, axis=1) + + resultados = [] + + for idx, ponto in enumerate(soma_pontos): + if soma_pesos[idx] > 30: + ponto = 0 + + resultados.append(ponto) + + return resultados + + +def get_pontos(itens: List[Bag]): + return [item.ponto for item in itens] + + +def get_pesos(itens: List[Bag]): + return [item.peso for item in itens] def select_mating_pool(pop, fitness, num_parents): @@ -34,7 +59,7 @@ def crossover(parents, offspring_size): # índice do primeiro genitor parent1_idx = k % parents.shape[0] # índice do segundo genitor - parent2_idx = (k+1) % parents.shape[0] + parent2_idx = (k + 1) % parents.shape[0] # o novo filho terá a primeira parte de seus genes # oriunda do primeiro genitor offspring[k, 0:crossover_point] = parents[parent1_idx, 0:crossover_point] @@ -52,7 +77,7 @@ def mutation(offspring_crossover, mutation_rate=0.3): if np.random.random() < mutation_rate: # O valor aleatório a ser adicionado random_idx = np.random.randint(0, offspring_crossover.shape[1]) - random_value = np.random.uniform(-1.0, 1.0, 1) - offspring_crossover[idx, random_idx] = offspring_crossover[idx, random_idx] + random_value + random_value = np.random.randint(2) + offspring_crossover[idx, random_idx] = random_value - return offspring_crossover + return offspring_crossover \ No newline at end of file diff --git a/main.py b/main.py index 2ccc125..24e1aec 100644 --- a/main.py +++ b/main.py @@ -1,21 +1,28 @@ import numpy as np import ga +from bag import Bag + def main(): - # entradas da equação - equation_inputs = [4, -2, 3.5, 5, -11, -4.7] - # número de pesos a otimizar - num_weights = 6 + saco_de_dormir = Bag('Saco de dormir', 15, 15) + corda = Bag('Corda', 3, 10) + canivete = Bag('Canivete', 2, 10) + tocha = Bag('Tocha', 5, 5) + garrafa = Bag('Garrafa', 9, 8) + comida = Bag('Comida', 20, 17) + + itens = [saco_de_dormir, corda, canivete, tocha, garrafa, comida] + + num_weights = 6 sol_per_pop = 8 # população tem sol_per_pop cromossomos com num_weights gens pop_size = (sol_per_pop, num_weights) # População inicial - new_population = np.random.uniform(low=-4.0, high=4.0, size=pop_size) - + new_population = np.random.randint(2, size=pop_size) # Algoritmo genético num_generations = 100 num_parents_mating = 4 @@ -24,7 +31,7 @@ def main(): print(f"Geração: {generation}") # medir o ‘fitness’ de cada cromossomo na população - fitness = ga.cal_pop_fitness(equation_inputs, new_population) + fitness = ga.cal_pop_fitness(itens, new_population) print("Valores de fitness:") print(fitness) @@ -32,7 +39,7 @@ def main(): # Selecionar os melhores pais na população para o cruzamento parents = ga.select_mating_pool(new_population, fitness, num_parents_mating) - print("Genitores selecionados:") + print("Genitores selecionados(pais):") print(parents) # formar a próxima geração usando crossover @@ -51,15 +58,22 @@ def main(): new_population[0:parents.shape[0], :] = parents new_population[parents.shape[0]:, :] = offspring_mutation - best_result = np.max(np.sum(new_population*equation_inputs, axis=1)) - print(f"Melhor resultado depois da geração {generation}: {best_result}") + # best_result = np.max(np.sum(new_population*equation_inputs, axis=1)) + # print(f"Melhor resultado depois da geração {generation}: {best_result}") - fitness = ga.cal_pop_fitness(equation_inputs, new_population) - best_match_idx = np.where(fitness == np.max(fitness)) + fitness = ga.cal_pop_fitness(itens, new_population) + best_match_idx = np.where(fitness == np.max(fitness))[0][0] print("Melhor solução: ", new_population[best_match_idx, :]) print("Fitness da melhor solução: ", fitness[best_match_idx]) + printar_nome_itens_selecionados(best_match_idx, itens, new_population) + + +def printar_nome_itens_selecionados(best_match_idx, itens, new_population): + for idx, item in enumerate(itens): + if new_population[best_match_idx, idx] == 1: + print(item.nome) if __name__ == '__main__': - main() + main() \ No newline at end of file