Sto provanto a realizzare il programma spiegato in questa pagina: http://en.wikipedia.org/wiki/Weasel_program, ma ho riscontrato un problema che non riesco a spiegarmi; il codice sorgente è questo:
codice:
def main (frase,gen,mut): #'frase' è la frase di arrivo, 'gen' il numero di "figli", 1/mut la probabilità di mutazione
def StrToArr (string): #trasforma una stringa in un array i cui elementi sono le lettere della parola
arr=[]
i=0
for n in string: #percorre 'string' e mette ogni lettera alla fine dell'array
arr[i:]=n
i=i+1
return arr
tot_Chars=StrToArr(" qwertyuiopasdfghjklzxcvbnm")
arr=StrToArr(frase)
boss=range(gen) #si crea un array contenitore, in modo che ad ogni numero di 'boss' si possa sostituire un array formato da len(arr) lettere
###Crea l'array madre, sul quale poi si lavorerà
for x in boss: #non c'è bisogno di un contatore in quanto x è un numero
caso=[] #N.B.: 'caso' e 'i' si riazzerano ogni volta che x aumenta di 1, ovvero ad ogni giro (infatti ogni elemento di 'boss' è maggiore di uno del precedente)
i=0
while i<(len(arr)): #crea un array della lunghezza di 'frase' in cui ogni elemento è un carattere casuale dell'alfabeto o uno spazio
caso[i:]=tot_Chars[random.randint(0,len(tot_Chars)-1)]
i=i+1
boss[x]=caso
#########################1
def mutatore (madre):
global data
data={} #ogni array è indicato da una chiave che è uguale, per comodità, alla sua posizione in "madre", e a cui corrisponde un valore che indica le lettere che ha in comune e nella stessa posizione con "arr"
for x in range(len(madre)): #scorre ogni array contenuto in 'madre'
data[x]=0
for n in range(len(madre[x])): #all'interno di ogni array c'è il "1/mut" di probabilità che ogni carattere muti
a=random.randint(0,mut-1)
##"""
if a==0: #se a=0 (c'è 1/mut di probabilità che sia così) il carattere muta
madre[x][n]=tot_Chars[random.randint(0,len(tot_Chars)-1)]
if madre[x][n]==arr[n]: #se il carattere che occupa la posizione "n" nell'array che occupa la posizione "x" in "madre" è uguale a quello che occupa la posizione "n" in "arr", il valore di "data" corrispondente all'array aumenta di uno
data[x]=data[x]+1
print madre
return madre
boss=mutatore(boss)
valori=data.values() #crea un array a cui corrispondono i valori di "data", ovvero gli indici di somiglianza
valori.sort() #mette in ordine i valori in modo che l'ultimo sia il più alto
coppie=data.items()
for x in range(len(coppie)-1): #all'intero dell'array di turple nella forma (chiave,valore) ricerca le turple in cui il secondo termine, ovvero il valore, è uguale all'ultimo elemento di "valori", ovvero il valore più alto; una volta fatto ciò individua la chiave corrispondente per poi aggiungerla al termine di "boss"
if coppie[x][1]==valori[-1]:
boss.append(boss[coppie[x][0]])
boss[0]=boss[-1] #gli array più simili ad "arr" sono quelli che seguono "arr[gen-1]"; anche nel caso ci siano più array con un punteggio identico, si preleva l'ultimo per comodità (e per simulare la presenza del caso)
del boss[1:] #con l'istruzione "boss=boss[-1]" non si ottengono sotto-array
boss=[["k","l","d"]] #parte non funzionale al prgramma, inserita come test
bos=range(gen)
for x in range(gen):
bos[x]=boss[0]
print mutatore(bos)
c="met"
main(c,5,5)
Il succo del problema è che l'istruzione "mutatore(bos)" mi restituisce sotto array sempre uguali fra loro, che si uniformano (non capisco perché) con l'istruzione "madre[x][n]=tot_Chars[random.randint(0,len(tot_Chars)-1)]"; una cosa che ho trovato anche più strana è che se dopo la riga "bos[x]=bos[0]" inserisco, a capo e quindi non dipendente da "range", questa istruzione
codice:
bos=[["k","l","d"],["k","l","d"],["k","l","d"],["k","l","d"],["k","l","d"]]
tutto funziona come mi aspetto.