Visualizzazione dei risultati da 1 a 5 su 5
  1. #1

    [Python] "Donnola di Dawkins"

    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.

  2. #2
    Forse ho risolto il problema: deve essere un problema legato agli alias.

  3. #3
    Utente bannato
    Registrato dal
    Apr 2012
    Messaggi
    1
    edit

  4. #4
    Non riesco a seguire granché la logica del programma, ma ad occhio sembrerebbe il classico problema derivante dal fatto che in Python le liste di base non sono copiate, ma se assegni una lista ad un'altra variabile rimane sempre un riferimento alla stessa lista (per copiarla, devi crearne esplicitamente una nuova, ad esempio a = list(b)).

    Per inciso, il codice che hai scritto non è granché "Pythonico", dovresti evitare tutti quei range quando puoi iterare direttamente sugli oggetti.
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Ho provato a cambiare l'ultima parte del codice in
    codice:
    for x in range(gen-1):
            boss.append(boss[0])
        bos=list(boss)
    ma non funziona comunque.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.