Created
September 21, 2015 19:36
-
-
Save demacdolincoln/d7aa0bcd0685ae10d09b to your computer and use it in GitHub Desktop.
uma adaptação do PSO que busca uma palavra, apenas um simples exercício para ajudar a esclarecer seu funcionamento. como se trata de valores aleatórios e como eu não me preocupei com muitos detalhes, pode ser que algumas vezes o algoritmo não funcione
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from string import ascii_uppercase as ascii_up | |
from random import choice, uniform | |
from copy import deepcopy | |
class Particle(object): | |
def __init__(self, dim, limit_max, limit_min): | |
self._position = [ord(choice(ascii_up)) for _ in range(dim)] | |
self._best_posit = self._position[::] | |
self._fitness = None | |
self._best_fitness = None | |
self._velocity = [0] * dim | |
def __repr__(self): | |
best_posit = "" | |
for p in self._position: | |
best_posit += chr(p) | |
return best_posit | |
def fitness(particle, alvo): | |
fit = 0 | |
for i in range(len(alvo)): | |
result = particle._position[i] - alvo[i] | |
fit += abs(result) | |
return fit | |
def atualiza_velocide(particle, gbest, dim, l_min, l_max): | |
nv = [] # nova velocidade | |
for p in range(dim): | |
rand = uniform(0, 1) * 2.05 | |
inercia = 0.4 * particle._velocity[p] | |
cog = particle._best_posit[p] - particle._position[p] | |
soc = gbest._position[p] - particle._position[p] | |
new = inercia + (rand * cog) + (rand * soc) | |
# controlando a velocidade | |
# if new > l_max: | |
# new = l_min | |
# elif new < l_min: | |
# new = l_max | |
nv.append(new) | |
particle._velocity = nv[::] | |
def atualiza_posicao(particle, dim, l_min, l_max): | |
np = [] # nova posicao | |
for p in range(dim): | |
new = particle._position[p] + particle._velocity[p] | |
if new > l_max: | |
new = l_max | |
elif new < l_min: | |
new = l_min | |
np.append(int(new)) | |
particle._position = np[::] | |
if __name__ == "__main__": | |
# confs iniciais | |
alvo_str = "Lincoln".upper() | |
alvo_list = list(map(lambda x: ord(x) ,list(alvo_str))) | |
dim = len(alvo_str) | |
l_min = ord(ascii_up[0]) | |
l_max = ord(ascii_up[-1]) | |
n_populacao = 30 # tamanho da população | |
# imprimindo as confs em tela: | |
print("populacao = ", n_populacao) | |
print("alvo = ", alvo_str) | |
# criando populacao inicial | |
populacao = [Particle(dim, l_max, l_min) for _ in range(n_populacao)] | |
print("populacao:") | |
for i in populacao: print(i, end=" - ") | |
print("\n", "=" * 30, "\n") | |
# atualizando o fitness da populacao inicial | |
for p in populacao: | |
fit = fitness(p, alvo_list) | |
p._fitness = fit | |
p._best_fitness = fit | |
# seleciona o gbest | |
gbest = deepcopy(sorted(populacao, key=lambda x: x._fitness)[0]) | |
iteracoes = 0 | |
# aplica a topologia global | |
while gbest._best_fitness > 0: | |
for p in populacao: | |
# atualiza o vetor velocidade | |
atualiza_velocide(p, gbest, dim, l_min, l_max) | |
# atualiza a posicao | |
atualiza_posicao(p, dim, l_min, l_max) | |
# atualiza o fitness de novo | |
p._fitness = fitness(p, alvo_list) | |
fit = p._fitness | |
if fit < p._best_fitness: | |
p._best_fitness = fit | |
p._best_posit = p._position[::] | |
# ordena a populacao pelo fitness | |
populacao.sort(key=lambda x: x._fitness) | |
# atualiza o gbest | |
# gbest = deepcopy(populacao[0]) | |
gbest_cand = deepcopy(populacao[0]) | |
if gbest_cand._fitness < gbest._fitness: | |
gbest = gbest_cand | |
iteracoes += 1 | |
print(gbest) | |
print("fitness = ", gbest._fitness) | |
print("iteracoes = ", iteracoes) | |
print("-"*30) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment