Changeset 81

Show
Ignore:
Timestamp:
08/21/07 21:26:22 (1 year ago)
Author:
edsuom
Message:

Resuming work on gevolver as part of asyncluster

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • projects/AsynCluster/trunk/gevolver/grammar.py

    r16 r81  
    1 # pbGE: 
    2 # Grammatical Evolution (GE) run by a "master" server and a bunch of "worker" 
    3 # clients via Twisted's Perspective Broker (PB). Computations are dispatched 
    4 # and carried out asynchronously using Twisted's deferred processing 
    5 # capabilities. 
     1# AsynCluster: gevolver 
     2# Python-based Grammatical Evolution with attribute grammars 
    63# 
    7 # Copyright (C) 2006 by Edwin A. Suominen, http://www.eepatents.com 
     4# Copyright (C) 2006-2007 by Edwin A. Suominen, http://www.eepatents.com 
    85# 
    9 
    10 # This code is not currently released for any public use. 
     6# This program is free software; you can redistribute it and/or modify it under 
     7# the terms of the GNU General Public License as published by the Free Software 
     8# Foundation; either version 2 of the License, or (at your option) any later 
     9# version. 
     10#  
     11# This program is distributed in the hope that it will be useful, but WITHOUT 
     12# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
     13# FOR A PARTICULAR PURPOSE.  See the file COPYING for more details. 
     14#  
     15# You should have received a copy of the GNU General Public License along with 
     16# this program; if not, write to the Free Software Foundation, Inc., 51 
     17# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 
    1118 
    1219""" 
     
    1724""" 
    1825 
    19 # Imports 
    2026import copy 
    21 from twisted.internet.defer import Deferred 
    2227 
    2328 
     
    6570            self._data = {'sentence':Sentence()} 
    6671 
    67     def __getattr__(self, name): 
     72    def __getattribute__(self, name): 
    6873        """ 
    6974        Returns all requested attributes from the state dict except for class 
    7075        attributes (importantly, my methods) and private instance attributes 
    7176        """ 
    72         isAttr = not name.startswith('_') and \ 
    73                  not name in self.__class__.__dict__ 
    74         if isAttr: 
    75             return self._data[name] 
    76         else: 
    77             return object.__getattr__(self, name) 
     77        if name.startswith('_') or \ 
     78               name in object.__getattribute__(self, '__class__').__dict__: 
     79            return object.__getattribute__(self, name) 
     80        return object.__getattribute__(self, '_data')[name] 
    7881 
    7982    def __setattr__(self, name, value): 
     
    8285        private instance attributes. 
    8386        """ 
    84         isAttr = not name.startswith('_') and \ 
    85                  not name in self.__class__.__dict__ 
    86         if isAttr: 
    87             self._data[name] = value 
    88         else: 
    89             object.__setattr__(self, name, value) 
     87        if name.startswith('_') or \ 
     88               name in object.__getattribute__(self, '__class__').__dict__: 
     89            return object.__setattr__(self, name, value) 
     90        self._data[name] = value 
    9091 
    9192    def __delattr__(self, name): 
     
    9495        private instance attributes. 
    9596        """ 
    96         isAttr = not name.startswith('_') and \ 
    97                  not name in self.__class__.__dict__ 
    98         if isAttr: 
    99             del self._data[name] 
    100         else: 
    101             object.__delattr__(self, name) 
    102  
    103     def copy(self): 
    104         """ 
    105         """ 
    106         return Attribute(self) 
    107      
     97        if name.startswith('_') or \ 
     98               name in object.__getattribute__(self, '__class__').__dict__: 
     99            return object.__delattr__(self, name) 
     100        del self._data[name] 
     101 
    108102    def terminals(self): 
    109103        """ 
     
    117111        Returns the next I{N} terminals in the sentence (for terminals only) 
    118112        """ 
    119         return self.sentence[self._k + 1 : self._k + 1 + N] 
    120  
    121  
    122 class Terminal: 
     113        k = self._k + 1 
     114        return self.sentence[ : self._k + 1 + N] 
     115 
     116 
     117class Terminal(object): 
    123118    """ 
    124119    The GE-derived individual program consists of a sentence of instances of 
    125120    me. 
    126121    """ 
    127     def __init__(self, value, label=""): 
    128         """ 
    129         Constructs a new terminal with the supplied value-producing object I{value) 
    130         and an optionally specified text label. 
     122    def __init__(self, valuer, label=""): 
     123        """ 
     124        Constructs a new terminal with the supplied value-producing object 
     125        I{valuer} and an optionally specified text label. 
    131126 
    132127        The value-producing object can be callable, in which case its result is 
     
    144139                
    145140        """ 
     141        self.valuer = valuer 
    146142        self.label = label 
    147         if callable(value): 
    148             self.value = value 
    149         else: 
    150             self.value = lambda s, a: value 
    151143 
    152144    def __str__(self): 
    153145        """ 
     146        My string depiction is simply my text label, if any. 
    154147        """ 
    155148        return self.label 
     
    160153        terminal function. 
    161154        """ 
    162         this = self.f.__name__ 
    163         if this < other: 
    164             return -1 
    165         elif this > other
    166             return 1 
    167         else: 
    168             return 0 
     155        args = tuple([x.f.__name__ for x in (self, other)]) 
     156        return cmp(*args) 
     157 
     158    def value(self, s)
     159        if callable(self.valuer): 
     160            return self.valuer(s, a) 
     161        return value 
    169162 
    170163 
     
    215208        """ 
    216209        @param T: A subclass of L{T} that defines a terminal set for this 
    217             production rule set. 
     210          production rule set. 
    218211 
    219212        @param S: One of my production rule methods to start with 
     
    229222        and the root attribute container I{a}. 
    230223 
    231         The mapping process runs in a thread and returns a C{Deferred}, which 
    232         fires with the completed sentence of terminal objects when no rules are 
    233         left to apply, 
     224        The mapping process runs recursively and finally returns with the 
     225        completed sentence of terminal objects when no rules are left to apply, 
    234226 
    235227        @param genome: A sequence of codons defining the genome for one 
    236             individual program. 
     228          individual program. 
    237229             
    238230        """ 
    239         def done(null): 
    240             return self.rootAttributes.sentence 
    241  
    242         def oops(failure): 
    243             """TODO""" 
    244             raise Exception() 
    245  
    246231        self.genome  = genome 
    247232        self.rootAttributes = a 
     
    262247        # The resulting production rules are applied to the first of probably 
    263248        # many recursive next() calls with that container 
    264         return deferToThread(next, a, initialRules).addCallbacks(done, oops) 
     249        self.next(a, initialRules) 
     250        # The final result... 
     251        return self.rootAttributes.sentence 
    265252 
    266253    def codon(self, N=1): 
  • projects/AsynCluster/trunk/gevolver/individual.py

    r10 r81  
    1 # pbGE: 
    2 # Grammatical Evolution (GE) run by a "master" server and a bunch of "worker" 
    3 # clients via Twisted's Perspective Broker (PB). Computations are dispatched 
    4 # and carried out asynchronously using Twisted's deferred processing 
    5 # capabilities. 
     1# AsynCluster: gevolver 
     2# Python-based Grammatical Evolution with attribute grammars 
    63# 
    7 # Copyright (C) 2006 by Edwin A. Suominen, http://www.eepatents.com 
     4# Copyright (C) 2006-2007 by Edwin A. Suominen, http://www.eepatents.com 
    85# 
    9 # This code is not currently released for any public use. 
     6# This program is free software; you can redistribute it and/or modify it under 
     7# the terms of the GNU General Public License as published by the Free Software 
     8# Foundation; either version 2 of the License, or (at your option) any later 
     9# version. 
     10#  
     11# This program is distributed in the hope that it will be useful, but WITHOUT 
     12# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
     13# FOR A PARTICULAR PURPOSE.  See the file COPYING for more details. 
     14#  
     15# You should have received a copy of the GNU General Public License along with 
     16# this program; if not, write to the Free Software Foundation, Inc., 51 
     17# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 
    1018 
    1119""" 
     
    1523# Imports 
    1624import copy 
    17 from twisted.internet.task import coiterate 
    18 from twisted.internet import defer 
    1925 
    2026 
     
    4652            raise StopIteration 
    4753 
    48     def getState(self): 
    49         """ 
    50         """ 
    51         return self.state 
    52  
    5354 
    5455class Individual(object): 
     
    5758    them to supplied genomes and evaluating the resulting individual program. 
    5859    """ 
    59     def evaluate(self, sentence, inputStates, 
    60                  errorFunction=None, fitnessFunction=None): 
     60    def evaluate(self, sentence, inputStates, f): 
    6161        """ 
    62         Evaluates the program defined by the supplied I{sentence} of terminals 
    63         and a sequence of I{inputStates} supplied as args, and either an 
    64         I{errorFunction} or a I{fitnessFunction} supplied as a keyword. 
     62        Evaluates the program defined by the supplied I{sentence} of terminals, 
     63        sequence of I{inputStates}, and fitness function I{f}. 
    6564         
    66         Returns a deferred that fires with a numerical value reflecting the 
    67         total fitness for all the input states supplied. 
     65        Returns the mean fitness for all the input states supplied. 
    6866        """ 
    69         def meanError(null): 
    70             inverseErrors = [1.0/abs(x) for x in results if x != 0] 
    71             return len(inverseErrors) / sum(inverseErrors) 
    72  
    73         def meanFitness(null): 
    74             return sum(abs(results)) / len(results) 
    75  
    76         @defer.deferredGenerator 
    77         def function(): 
    78             for inputState in inputStates: 
    79                 wfd = defer.waitForDeferred(self.run(sentence, state)) 
    80                 yield wfd 
    81                 resultState = wfd.getResult() 
    82                 results.append(f(inputState, resultState)) 
    83              
    8467        results = [] 
    85         if errorFunction is not None and fitnessFunction is not None: 
    86             raise ConditionError( 
    87                 "Conflicting evaluation function specification") 
    88         elif callable(errorFunction): 
    89             f = errorFunction 
    90             callback = meanError 
    91         elif callable(fitnessFunction): 
    92             f = fitnessFunction 
    93             callback = meanFitness 
    94         else: 
    95             raise ConditionError("No error or fitness function supplied") 
    96         return function().addCallback(callback) 
     68        for inputState in inputStates: 
     69            resultState = self.run(sentence, inputState) 
     70            fitness = f(inputState, resultState) 
     71            results.append(fitness) 
     72        return sum(abs(results)) / len(results) 
    9773 
    9874    def run(self, sentence, inputState): 
     
    10278        modify. 
    10379 
    104         Returns a deferred that fires when the end of the terminal sentence is 
    105         reached. At that point, the program will have finished running and 
    106         making modifications to its copy of the state, a reference to which the 
    107         deferred supplies as the argument to its callback function. 
     80        When done, returns a reference to the program's copy of the state, as 
     81        modified by the program. 
    10882        """ 
    109         ti = Termiterator(sentence, inputState) 
     83        for terminal in sentence: 
     84            terminal.value(self.state) 
     85 
     86        Termiterator(sentence, inputState) 
    11087        return coiterate(ti).addCallback(ti.getState)