Skip to content

Instantly share code, notes, and snippets.

@demacdolincoln
Created September 21, 2015 19:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save demacdolincoln/d7aa0bcd0685ae10d09b to your computer and use it in GitHub Desktop.
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
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