[python 2.7] Geneiies Programmeren

Status
Niet open voor verdere reacties.

blua tigro

Gebruiker
Lid geworden
21 apr 2009
Berichten
48
dit is mijn 2 de poging tot t komen tot GP in python

GP wat :
- t creeren van n functie omschijving uit n gegeven grafiek

GP hoe :
- 1 : creer n aantal functies [ write ]
- 2 : bereken fitnes [ fout tov gewenst ] [ run ]
- 3 : sorteer op fitnes
- 4 : neem kind functies van beste functies [ mix ]
- 5 : muteer deel van kind functies [ mutate ]
- 6 : if generaties < aantal or fitnes > gewenst : goto 2

error :
- als ik setInputMax gebuik krijg ik n index out of bounds list error
- tewijl in iisInput check of het atom een inputletter is
- als ik de POW code aanzet krijg ik n error

Code:
import math 
import random 
ADD       = "[ + # # # ]" 
SUBTRACT = "[ - # # # ]" 
MULTIPLY = "[ * # # # ]" 
DIVIDE   = "[ / # # # ]" 
MOD       = "[ % # # # ]" 
#POW       = "[ ** # # # ]" 
FLOOR    = "[ floor # # # ]" 
FABS     = "[ fabs # # # ]" 
SQRT     = "[ sqrt # # # ]" 
EXP       = "[ exp # # # ]" 
LOG10    = "[ log10 # # # ]" 
LN         = "[ ln # # # ]" 
LOGX     = "[ logx # # # ]" 
# dont use : not jet ready 
#IF        = "[ ? # # # ]" 
#EQUAL    = "[ == # # # ]" 
#UNEQUAL  = "[ != # # # ]" 
#GREAT    = "[ > # # # ]" 
#SMALL    = "[ < # # # ]" 
#BETWEEN  = "[ <a< # # # ]" 
#TAN      = "[ tan # # # ]" 
#SIN      = "[ sin # # # ]" 
#COS      = "[ cos # # # ]" 
#ATAN    = "[ atan # # # ]" 
#ATAN2    = "[ atan2 # # # ]"
class CGP( object ) : 
    
    def __init__( self ) : 
            
        self.genes = [] 
        self.numbermode = 0 
        self.inputmax = 0 
        self.invoer = []
        self.inputs = "abcdefghj"

    def set_inputmax( self , no ) : 
       a = self.inputs
       i = 0 
       while i < len( a ) and i <= no - 1 : 
           self.use( a[ i ] ) 
           i += 1 
       for i in xrange( len( a ) + 2 ) : 
           self.invoer.append( 0. ) 
    def set_input( self , no , x ) : 
           if no < 0 or no > len( self.invoer ) - 1 : 
                   self.invoer[ no ] = x 
    def isNumber( self , x ) :
         return x[ 0 ] in "0123456789"
    def isInput( self , x ) :
         return x in self.inputs 
                    
    def run( self , prog ) :
        l = self.inputs
        while "]" in prog : 
            eind = prog.find( "]" ) 
            begin = eind - 1 
            while prog[ begin ] != "[" : 
                begin -= 1 
            deel = prog[ begin : eind + 1 ] 
            q = deel.split() 
            func = q[ 1 ] 
                    
            if self.isInput( q[ 2 ] ) : 
                a = self.invoer[ l.find( q[ 2 ] ) ] 
            elif self.isNumber( q[ 2 ] ) :
                a = float( q[ 2 ] )
            else :
                return "error"
            if self.isInput( q[ 3 ] ) : 
                b = self.invoer[ l.find( q[ 3 ] ) ] 
            elif self.isNumber( q[ 3 ] ) :
                b = float( q[ 3 ] )
            else :
                return "error"
            if self.isInput( q[ 4 ] ) : 
                c = self.invoer[ l.find( q[ 4 ] ) ] 
            elif self.isNumber( q[ 4 ] ) :
                 c = float( q[ 4 ] )
            else :
                 return "error"
            if func == "+" : 
                ab = a + b 
            elif func == "*" : 
                ab = a * b 
            elif func == "-" : 
                ab = a - b 
            elif func == "/" : 
                if b == 0.0 : 
                    return "error" 
                else : 
                    ab = a / b 
            elif func == "%" : 
                if b == 0 : 
                    return "error" 
                else : 
                    ab = a % b 
            elif func == "sqrt" : 
                if a < 0 : 
                    return "error" 
                else : 
                   ab = math.sqrt( a ) 
            elif func == "floor" : 
                ab = math.floor( a ) 
            elif func == "fabs" : 
                ab = math.fabs( a ) 
            elif func == "exp" : 
                if math.fabs( a ) > 32 : 
                    return "error" 
                else : 
                    ab = math.exp( a ) 
            elif func == "log10" : 
                if a <= 0 : 
                    return "error" 
                else : 
                    ab = math.log( a , 10. ) 
            elif func == "ln" : 
                if a <= 0 : 
                    return "error" 
                else : 
                    ab = math.log( a , math.e ) 
            elif func == "logx" : 
                if a <= 0 or b <= 0 or b == 1 : 
                    return "error" 
                else : 
                   ab = math.log( a , b ) 
            #elif func == "**" : 
            #    if math.fabs( math.log( a , 10. ) 
            #    * math.log( b , 10. ) ) > 13. : 
            #        return "error"
            #    else :
            #        ab = a ** b
            else : 
                return "error" 
            l = prog[ : begin ] 
            m = `ab` 
            r = prog[ eind + 1 : ] 
            prog = l + m + r 
        return prog 
    
    def write( self , hooks ) : 
            
        dice = random.randint( 0 , len( self.genes )-1 ) 
        while not "[" in self.genes[ dice ] : 
            dice = random.randint( 0 , len( self.genes )-1 ) 
        prog = self.genes[ dice ] 
            
        tel = 0 
        while "#" in prog and tel < hooks : 
            p = prog.find( "#" ) 
            dice = random.randint( 0 , len( self.genes ) - 1 ) 
            m = self.genes[ dice ] 
            if "#" in m : 
                tel += 1 
            l = prog[ : p ] 
            r = prog[ p + 1 : ] 
            prog = l + m + r 
                    
        while "#" in prog : 
            p = prog.find( "#" ) 
            dice = random.randint( 0 , len( self.genes ) - 1 ) 
            while "[" in self.genes[ dice ] : 
                dice = random.randint( 0 ,
                len( self.genes ) - 1 ) 
            m = self.genes[ dice ] 
            l = prog[ : p ] 
            r = prog[ p + 1 : ] 
            prog = l + m + r 
        return prog 
    def mix( self , a , b ) : 
        if random.randint( 0 , 2 ) > 1 :
            h = a
            a = b
            b = h
        la = [] 
        for i in xrange( len( a ) ) : 
            if a[ i ] == "[" : 
                la.append( i ) 
        lb = [] 
        for i in xrange( len( b ) ) : 
            if b[ i ] == "[" : 
                lb.append( i ) 
        dice = random.randint( 0 , len( la ) - 1 ) 
        begina = la[ dice ] 
        fl = 1 
        i = begina + 1 
        while fl > 0 and i < len( a ) : 
            if a[ i ] == "[" : fl += 1 
            if a[ i ] == "]" : fl -= 1 
            i += 1 
        einda = i 
        dice = random.randint( 0 , len( lb ) - 1 ) 
        beginb = lb[ dice ] 
        fl = 1 
        i = beginb + 1 
        while fl > 0 and i < len( b ) : 
            if b[ i ] == "[" : fl += 1 
            if b[ i ] == "]" : fl -= 1 
            i += 1 
        eindb = i 
        l = a[ : begina ] 
        m = b[ beginb : eindb + 1 ] 
        r = a[ einda : ] 
        return l + m + r 
    def mutate( self , prog ) : 
        a = "abcdefghij" 
        lp = prog.split() 
        dice = random.randint( 0 , len( lp ) - 1 ) 
        atom = lp[ dice ] 
        while atom in ( "[" , "]" ) : 
            dice = random.randint( 0 , len( lp ) - 1 ) 
            atom = lp[ dice ] 
        # atom is number 
        if self.isNumber( atom ) : 
            f = float( atom ) 
            if self.inputmax > 0 : 
                if random.randint( 0 , 10 ) == 0 : 
                    lp[ dice ] = a[ random.randint( 0 , len( a ) - 1 ) ] 
                else : 
                    if self.numbermode == 1 : 
                        if random.randint( 0 , 2 ) == 0 : 
                            f += 2**random.randint( 0 , 32 ) 
                        else : 
                            f -= 2**random.randint( 0 , 32 ) 
                    else : 
                        if random.randint( 0 , 2 ) == 0 : 
                            f += 2**random.randint( -31 , 32 ) 
                        else : 
                            f -= 2**random.randint( -31 , 32 ) 
                lp[ dice ] = str( f ) 
            else : 
                if self.numbermode == 1 : 
                    if random.randint( 0 , 2 ) == 0 : 
                        f += 2**random.randint( 0 , 32 ) 
                    else : 
                        f -= 2**random.randint( 0 , 32 ) 
                else : 
                    if random.randint( 0 , 2 ) == 0 : 
                        f += 2**random.randint( -31 , 32 ) 
                    else : 
                        f -= 2**random.randint( -31 , 32 ) 
                lp[ dice ] = str( f ) 
        elif self.isInput( atom ) : 
            if random.randint( 0 , 10 ) > 0 : 
                lp[ dice ] = a[ random.randint( 0 , len( a ) - 1 )] 
            else : 
                if self.numbermode == 1 : 
                    if random.randint( 0 , 2 ) == 0 : 
                        f += 2**random.randint( 0 , 32 )
                    else : 
                        f -= 2**random.randint( 0 , 32 ) 
                else : 
                    if random.randint( 0 , 2 ) == 0 : 
                        f += 2**random.randint( -31 , 32 ) 
                    else : 
                        f -= 2**random.randint( -31 , 32 ) 
                lp[ dice ] = str( f ) 
        else : # atom is function 
            d = random.randint( 0 , len( self.genes ) - 1 ) 
            while not "[" in self.genes[ d ] : 
                d = random.randint( 0 , len( self.genes ) - 1 ) 
            l = self.genes[ d ].split() 
                    
            lp[ dice ] = l[ 1 ]
        prog = "" 
        for i in xrange( len( lp ) ) : 
            prog += lp[ i ] + " " 
        return prog 
    def use( self , gen ) : 
        self.genes.append( gen ) 
    def intlist( self ) : 
        for i in xrange( 32 ) : 
            self.use( str( 2**i ) ) 
        self.numbermode = 1 
    def dbllist( self ) : 
        for i in range( -31 , 31 ) : 
            self.use( str( 2**i ) ) 
        self.numbermode = 2
        
gp = CGP() 
gp.use( ADD ) 
gp.use( SUBTRACT ) 
gp.use( MULTIPLY ) 
gp.use( DIVIDE ) 
gp.use( MOD ) 
#gp.use( POW ) 
gp.use( FLOOR ) 
gp.use( FABS ) 
gp.use( SQRT ) 
gp.use( EXP ) 
gp.use( LOG10 ) 
gp.use( LN ) 
gp.use( LOGX ) 
gp.intlist() 
#gp.set_inputmax( 3 ) 
lprog = [] 
lfout = [] 
for i in xrange( 1000 ) : 
    lprog.append( gp.write( 6 ) ) 
    lfout.append( 0. )
einde = 100
for i in xrange( einde ) : 
    for t in xrange( len( lprog ) - 1 ) : 
        uit_str = gp.run( lprog[ t ] ) 
        if uit_str[ 0 ] not in "0123456789" : 
            uit = 1e300
        else : 
            uit = float( uit_str ) 
        lfout[ t ] = math.fabs( uit - math.pi ) 
    for h in xrange( len( lprog ) - 1 ) : 
        for l in range( 0 , h ) : 
            if lfout[ l ] > lfout[ h ] : 
                hp = lprog[ l ] 
                lprog[ l ] = lprog[ h ] 
                lprog[ h ] = hp 
                hf = lfout[ l ] 
                lfout[ l ] = lfout[ h ] 
                lfout[ h ] = hf 
    if i % ( einde / 6 ) == 0 :
        print lprog[ 0 ]
        print "<< " , gp.run( lprog[ 0 ] ) , " >> " , lfout[ 0 ]
    
    for i in range( 10 , len( lprog ) ) : 
        a = lprog[ random.randint( 0 , 9 ) ] 
        b = lprog[ random.randint( 0 , 9 ) ] 
        lprog[ i ] = gp.mix( a , b ) 
        if random.randint( 0 , 10 ) < 2 : 
            lprog[ i ] = gp.mutate( lprog[ i ] )

            
#a = "[ + 1 [ - 2 3 4 ] 5 ]"
#b = "[ / 6 [ * 7 8 9 ] 10 ]"
#print "a = " , a
#print "b = " , b
#print "run a =" , gp.run( a )
#print "run b =" , gp.run( b )
#for i in xrange( 5 ) :
#    print "mix a b = " , gp.mix( a , b )
#print "mutate a = " , gp.mutate( a )
#print "mutate b = " , gp.mutate( b )
 
Laatst bewerkt:
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan