Last active
August 29, 2015 14:25
-
-
Save jogonba2/f3c6c46cb34c48836c25 to your computer and use it in GitHub Desktop.
Problemas de lógica mediante genéticos (Einstein y avenida complicada)
This file contains 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
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# genetico_logica.py | |
# Author: Overxfl0w13 # | |
from random import shuffle,randint,uniform | |
#from premisas_avenida import PREMISAS | |
from premisas_einstein import PREMISAS | |
MAX_PREMISES = 0 | |
""" Búsqueda completa intratable O((n!)^m) / n es el número de casas y m es el número de atributos | |
(5!)^5 = 24883200000 combinaciones inicialmente (se reducen con las premisas dadas) | |
""" | |
def genetico(): | |
poblacion = generar_inicial() | |
evaluacion = evaluacion_genetico(poblacion) | |
while convergencia_genetico(evaluacion)==False: | |
poblacionaux = poblacion[:] | |
poblacion = [] | |
for x in xrange(len(poblacionaux)/2): | |
padres = seleccion(poblacionaux,evaluacion) | |
padre_1,padre_2 = padres[0],padres[1] | |
hijos = cruce_2_puntos(padre_1,padre_2) | |
hijo_1,hijo_2 = hijos[0],hijos[1] | |
hijo_1,hijo_2 = mutacion(hijo_1),mutacion(hijo_2) | |
poblacion.append(hijo_1) | |
poblacion.append(hijo_2) | |
evaluacion = evaluacion_genetico(poblacion) | |
print "Solucion -> ", poblacion[evaluacion.index(len(PREMISAS))] | |
def generar_inicial(): | |
""" Genera una población inicial de individuos (|poblacion| € [l,2l] / l = |cromosoma|) """ | |
pob,longpob = [],randint(25,50) | |
print longpob | |
for x in xrange(50): | |
rand = [[x for x in xrange(0,5)] for i in xrange(0,5)] | |
for cgen in rand: shuffle(cgen) | |
pob.append(sum(([]+rand),[])) | |
return pob | |
def weighted_choice(choices): | |
total = sum(w for c, w in choices) | |
r = uniform(0, total) | |
upto = 0 | |
for c, w in choices: | |
if upto + w > r: | |
return c | |
upto += w | |
def seleccion(poblacion,evaluacion): | |
fevaltotal = sum(evaluacion) | |
pobaux = poblacion[:] | |
choices = [(i,float(evaluacion[i])/fevaltotal) for i in xrange(len(evaluacion))] | |
c1,c2 = pobaux[weighted_choice(choices)],pobaux[weighted_choice(choices)] | |
return (c1,c2) | |
def mutacion(cromosoma): | |
""" Mutacion por permutación entre 2 genes dentro de rangos [n,n+5] / n%5==0 """ | |
""" P(mutacion) = |cromosoma|**-1 = 0.04 """ | |
l = [x for x in xrange(len(cromosoma))] | |
shuffle(l) | |
p1,p2,p3,p4,p5 = cromosoma[0:5],cromosoma[5:10],cromosoma[10:15],cromosoma[15:20],cromosoma[20:25] | |
p = [p1,p2,p3,p4,p5] | |
res = [] | |
for part in p: | |
for i in xrange(len(part)): | |
rand = l[randint(0,len(l)-1)] # P(rand==x / x€l | l) = |cromosoma|**-1 = 0.04 | |
if rand==1: | |
pos = randint(0,len(part)-1) | |
part[i],part[pos] = part[pos],part[i] | |
res += part | |
return res | |
def cruce_2_puntos(padre_1,padre_2): | |
""" Puntos de cruce solo posibles si el indice es multiplo de 5 """ | |
puntos_posibles = [5,10,15,20] | |
shuffle(puntos_posibles) | |
p1,p2 = puntos_posibles.pop(randint(0,len(puntos_posibles)-1)),puntos_posibles.pop(randint(0,len(puntos_posibles)-1)) | |
p1,p2 = min(p1,p2),max(p1,p2) | |
h1 = padre_1[0:p1]+padre_2[p1:p2]+padre_1[p2:] | |
h2 = padre_2[0:p1]+padre_1[p1:p2]+padre_2[p2:] | |
return (h1,h2) | |
def evaluacion_complete(cromosoma): | |
feval = 0 | |
for premisa in PREMISAS: | |
if premisa(cromosoma): feval += 1 | |
return feval | |
def evaluacion_genetico(poblacion): | |
feval,c = [],0 | |
for cromosoma in poblacion: | |
c = 0 | |
for premisa in PREMISAS: | |
try: | |
if premisa(cromosoma): c+=1 | |
except: # Evitar ajustar las comprobaciones en los limites, y si se excede se cuenta como False (sin pérdida de generalidad) # | |
continue | |
feval.append(c) | |
return feval | |
def convergencia_genetico(evaluacion): return True if len(PREMISAS) in evaluacion else False | |
if __name__ == "__main__": | |
genetico() | |
############################################################################################################################### | |
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# | |
# premisas_avenida.py | |
# Author: Overxfl0w13 | |
VERDE,GRIS,BLANCA,AZUL,ROJA = 0,1,2,3,4 | |
FORD,MERCEDES,VOLKSWAGEN,CADILLAC,CHEVROLET = 0,1,2,3,4 | |
PINYA,LIMONADA,PEPSI,COCACOLA,CAFE = 0,1,2,3,4 | |
CACHORRO,GATO,CONEJOS,CABALLO,VACA = 0,1,2,3,4 | |
ARGENTINO,PERUANO,BRASILENYO,CHILENO,MEXICANO = 0,1,2,3,4 | |
COLOR = [VERDE,GRIS,BLANCA,AZUL,ROJA] | |
COCHE = [FORD,MERCEDES,VOLKSWAGEN,CADILLAC,CHEVROLET] | |
BEBIDA = [PINYA,LIMONADA,PEPSI,COCACOLA,CAFE] | |
ANIMAL = [CACHORRO,GATO,CONEJOS,CABALLO,VACA] | |
PROPIETARIO = [ARGENTINO,PERUANO,BRASILENYO,CHILENO,MEXICANO] | |
""" 801 803 805 807 809 | |
color 0 1 2 3 4 | |
coche 5 6 7 8 9 | |
bebida 10 11 12 13 14 | |
animal 15 16 17 18 19 | |
propietario 20 21 22 23 24 | |
Individuo -> V € {0,1,2,3,4}^25 | |
""" | |
def all_index(l,el): return [i for i,val in enumerate(l) if val==el] | |
def get_casa(cromosoma,color): return all_index(cromosoma,color)[0] | |
def get_coche(cromosoma,coche): return all_index(cromosoma,coche)[1] | |
def get_bebida(cromosoma,bebida): return all_index(cromosoma,bebida)[2] | |
def get_animal(cromosoma,animal): return all_index(cromosoma,animal)[3] | |
def get_propietario(cromosoma,propietario): return all_index(cromosoma,propietario)[4] | |
def premisa_1(cromosoma): | |
""" Mexicano vive en la casa roja """ | |
mexicano = get_propietario(cromosoma,MEXICANO) | |
return True if cromosoma[mexicano-20]==ROJA else False | |
def premisa_2(cromosoma): | |
""" Peruano tiene un mercedes """ | |
peruano = get_propietario(cromosoma,PERUANO) | |
return True if cromosoma[peruano-15]==MERCEDES else False | |
def premisa_3(cromosoma): | |
""" Argentino tiene un cachorro """ | |
argentino = get_propietario(cromosoma,ARGENTINO) | |
return True if cromosoma[argentino-5]==CACHORRO else False | |
def premisa_4(cromosoma): | |
""" Chileno toma coca-cola """ | |
chileno = get_propietario(cromosoma,CHILENO) | |
return True if cromosoma[chileno-10]==COCACOLA else False | |
def premisa_5(cromosoma): | |
""" Conejos misma distancia cadillac y limonada """ | |
conejo = get_animal(cromosoma,CONEJOS) | |
if conejo==19 or conejo==15: return False | |
if conejo==16 or conejo==18: | |
if cromosoma[conejo-11]==CADILLAC and cromosoma[conejo-4]==LIMONADA: return True | |
if cromosoma[conejo-9]==CADILLAC and cromosoma[conejo-6]==LIMONADA: return True | |
if conejo==17: | |
if cromosoma[conejo-11]==CADILLAC and cromosoma[conejo-4]==LIMONADA: return True | |
if cromosoma[conejo-9]==CADILLAC and cromosoma[conejo-6]==LIMONADA: return True | |
if cromosoma[conejo-12]==CADILLAC and cromosoma[conejo-3]==LIMONADA: return True | |
if cromosoma[conejo-8]==CADILLAC and cromosoma[conejo-7]==LIMONADA: return True | |
return False | |
def premisa_6(cromosoma): | |
""" Gato no toma cafe ni vive en la casa azul """ | |
gato = get_animal(cromosoma,GATO) | |
return True if (cromosoma[gato-5]!=CAFE) and (cromosoma[gato-15]!=AZUL) else False | |
def premisa_7(cromosoma): | |
""" En la casa verde se toma zumo de piña """ | |
casa_verde = get_casa(cromosoma,VERDE) | |
return True if (cromosoma[casa_verde+10])==PINYA else False | |
def premisa_8(cromosoma): | |
""" La vaca es vecina de la casa donde se toma coca-cola """ | |
vaca = get_animal(cromosoma,VACA) | |
if vaca==15: | |
if cromosoma[vaca-4]==COCACOLA: return True | |
elif vaca==19: | |
if cromosoma[vaca-6]==COCACOLA: return True | |
else: | |
if cromosoma[vaca-6]==COCACOLA or cromosoma[vaca-4]==COCACOLA: return True | |
return False | |
def premisa_9(cromosoma): | |
""" La casa verde tiene como vecina a la derecha a la casa gris """ | |
casa_verde = get_casa(cromosoma,VERDE) | |
return True if cromosoma[casa_verde+1]==GRIS else False | |
def premisa_10(cromosoma): | |
""" El peruano y el argentino son vecinos """ | |
peruano = get_propietario(cromosoma,PERUANO) | |
return True if (peruano>20 and cromosoma[peruano-1]==ARGENTINO) or (cromosoma[peruano+1]==ARGENTINO) else False | |
def premisa_11(cromosoma): | |
""" El propietario del volkswagen cria conejos """ | |
volkswagen = get_coche(cromosoma,VOLKSWAGEN) | |
return True if (cromosoma[volkswagen+10]==CONEJOS) else False | |
def premisa_12(cromosoma): | |
""" El chevrolet pertenece a la casa roja """ | |
casa_roja = get_casa(cromosoma,ROJA) | |
return True if (cromosoma[casa_roja+5]==CHEVROLET) else False | |
def premisa_13(cromosoma): | |
""" Se toma pepsi-cola en la tercera casa """ | |
return True if cromosoma[12]==PEPSI else False | |
def premisa_14(cromosoma): | |
""" El brasileño es vecino de la casa azul """ | |
brasilenyo = get_propietario(cromosoma,BRASILENYO) | |
if brasilenyo==20: | |
if cromosoma[brasilenyo-19]==AZUL: return True | |
elif brasilenyo==24: | |
if cromosoma[brasilenyo-21]==AZUL: return True | |
else: | |
if cromosoma[brasilenyo-19]==AZUL: return True | |
if cromosoma[brasilenyo-21]==AZUL: return True | |
return False | |
def premisa_15(cromosoma): | |
""" El propietario del ford toma limonada """ | |
ford = get_coche(cromosoma,FORD) | |
return True if cromosoma[ford+5]==LIMONADA else False | |
def premisa_16(cromosoma): | |
""" El propietario de la vaca es vecino del dueño del cadillac """ | |
vaca = get_animal(cromosoma,VACA) | |
if vaca==15: | |
if cromosoma[vaca-9]==CADILLAC: return True | |
elif vaca==19: | |
if cromosoma[vaca-11]==CADILLAC: return True | |
else: | |
if cromosoma[vaca-9]==CADILLAC: return True | |
if cromosoma[vaca-11]==CADILLAC: return True | |
return False | |
def premisa_17(cromosoma): | |
""" El propietario del chevrolet es vecino del dueño del caballo """ | |
chevrolet = get_coche(cromosoma,CHEVROLET) | |
if chevrolet==5: | |
if cromosoma[chevrolet+11]==CABALLO: return True | |
elif chevrolet==9: | |
if cromosoma[chevrolet+9]==CABALLO: return True | |
else: | |
if cromosoma[chevrolet+11]==CABALLO: return True | |
if cromosoma[chevrolet+9]==CABALLO: return True | |
return False | |
def premisa_18(cromosoma): | |
""" La casa blanca es del brasileño """ | |
casa_blanca = get_casa(cromosoma,BLANCA) | |
return True if (cromosoma[casa_blanca+20]==BRASILENYO) else False | |
PREMISAS = [premisa_1,premisa_2,premisa_3,premisa_4,premisa_5,premisa_6, | |
premisa_7,premisa_8,premisa_9,premisa_10,premisa_11,premisa_12, | |
premisa_13,premisa_14,premisa_15,premisa_16,premisa_17,premisa_18] | |
############################################################################################################################### | |
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# | |
# premisas_einstein.py | |
# | |
# Author: Overxfl0w13 | |
# | |
ROJA,VERDE,AMARILLA,BLANCA,AZUL = 0,1,2,3,4 | |
PALLMALL,DUNHILL,BRENDS,BLUEMASTERS,PRINCE = 0,1,2,3,4 | |
TE,CAFE,LECHE,CERVEZA,AGUA = 0,1,2,3,4 | |
PERRO,PAJARO,GATO,PEZ,CABALLO = 0,1,2,3,4 | |
BRITANICO,SUECO,NORUEGO,DANES,ALEMAN = 0,1,2,3,4 | |
""" 801 803 805 807 809 | |
color 0 1 2 3 4 | |
fuma 5 6 7 8 9 | |
bebida 10 11 12 13 14 | |
animal 15 16 17 18 19 | |
propietario 20 21 22 23 24 | |
Individuo -> V € {0,1,2,3,4}^25 | |
""" | |
def all_index(l,el): return [i for i,val in enumerate(l) if val==el] | |
def get_casa(cromosoma,color): return all_index(cromosoma,color)[0] | |
def get_fuma(cromosoma,fuma): return all_index(cromosoma,fuma)[1] | |
def get_bebida(cromosoma,bebida): return all_index(cromosoma,bebida)[2] | |
def get_animal(cromosoma,animal): return all_index(cromosoma,animal)[3] | |
def get_propietario(cromosoma,propietario): return all_index(cromosoma,propietario)[4] | |
def premisa_1(cromosoma): | |
""" Britanico en la casa roja """ | |
britanico = get_propietario(cromosoma,BRITANICO) | |
return True if cromosoma[britanico-20]==ROJA else False | |
def premisa_2(cromosoma): | |
""" El sueco tiene un perro """ | |
sueco = get_propietario(cromosoma,SUECO) | |
return True if cromosoma[sueco-5]==PERRO else False | |
def premisa_3(cromosoma): | |
""" El danes toma te """ | |
danes = get_propietario(cromosoma,DANES) | |
return True if cromosoma[danes-10]==TE else False | |
def premisa_4(cromosoma): | |
""" La casa verde esta a la izquierda de la blanca """ | |
casa_blanca = get_casa(cromosoma,BLANCA) | |
if casa_blanca==0: return False | |
else: | |
if cromosoma[casa_blanca-1]==VERDE: return True | |
return False | |
def premisa_5(cromosoma): | |
""" El dueño de la casa verde toma cafe """ | |
casa_verde = get_casa(cromosoma,VERDE) | |
return True if cromosoma[casa_verde+10]==CAFE else False | |
def premisa_6(cromosoma): | |
""" La persona que fuma pallmall tiene un pajaro """ | |
pallmall = get_fuma(cromosoma,PALLMALL) | |
return True if cromosoma[pallmall+10]==PAJARO else False | |
def premisa_7(cromosoma): | |
""" El dueño de la casa amarilla fuma dunhill """ | |
casa_amarilla = get_casa(cromosoma,AMARILLA) | |
return True if cromosoma[casa_amarilla+5]==DUNHILL else False | |
def premisa_8(cromosoma): | |
""" El que vive en la casa del centro toma leche """ | |
return True if cromosoma[12]==LECHE else False | |
def premisa_9(cromosoma): | |
""" El noruego vive en la primera casa """ | |
return True if cromosoma[20]==NORUEGO else False | |
def premisa_10(cromosoma): | |
""" La persona que fuma brends vive junto a la persona que tiene un gato """ | |
brends = get_fuma(cromosoma,BRENDS) | |
if brends==5: | |
if cromosoma[brends+11]==GATO: return True | |
elif brends==9: | |
if cromosoma[brends+9]==GATO: return True | |
else: | |
if cromosoma[brends+11]==GATO: return True | |
if cromosoma[brends+9]==GATO: return True | |
return False | |
def premisa_11(cromosoma): | |
""" La persona que tiene un caballo vive junto a la que fuma dunhill """ | |
dunhill = get_fuma(cromosoma,DUNHILL) | |
if dunhill==5: | |
if cromosoma[dunhill+11]==CABALLO: return True | |
elif dunhill==9: | |
if cromosoma[dunhill+9]==CABALLO: return True | |
else: | |
if cromosoma[dunhill+11]==CABALLO: return True | |
if cromosoma[dunhill+9]==CABALLO: return True | |
return False | |
def premisa_12(cromosoma): | |
""" El que fuma bluemasters bebe cerveza """ | |
bluemasters = get_fuma(cromosoma,BLUEMASTERS) | |
return True if cromosoma[bluemasters+5]==CERVEZA else False | |
def premisa_13(cromosoma): | |
""" El aleman fuma prince """ | |
aleman = get_propietario(cromosoma,ALEMAN) | |
return True if cromosoma[aleman-15]==PRINCE else False | |
def premisa_14(cromosoma): | |
""" El noruego vive junto a la casa azul """ | |
noruego = get_propietario(cromosoma,NORUEGO) | |
if noruego==20: | |
if cromosoma[noruego-19]==AZUL: return True | |
elif noruego==24: | |
if cromosoma[noruego-21]==AZUL: return True | |
else: | |
if cromosoma[noruego-19]==AZUL: return True | |
if cromosoma[noruego-21]==AZUL: return True | |
return False | |
def premisa_15(cromosoma): | |
""" El que fuma brends tiene un vecino que bebe agua """ | |
brends = get_fuma(cromosoma,BRENDS) | |
if brends==5: | |
if cromosoma[brends+6]==AGUA: return True | |
elif brends==9: | |
if cromosoma[brends+4]==AGUA: return True | |
else: | |
if cromosoma[brends+6]==AGUA: return True | |
if cromosoma[brends+4]==AGUA: return True | |
return False | |
PREMISAS = [premisa_1,premisa_2,premisa_3,premisa_4,premisa_5,premisa_6, | |
premisa_7,premisa_8,premisa_9,premisa_10,premisa_11,premisa_12, | |
premisa_13,premisa_14,premisa_15] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment