class MapConnectionGene(BaseGene): #Various parameters for defining a connection. _gene_attributes = [ BoolAttribute('one_to_one'), #1-to-1 or 1-to-all scheme BoolAttribute('is_gaussian'), #Gaussian or uniform distribution FloatAttribute( 'weight' ), #Weigth is used as the mean of the normal distribution for 1-to-all FloatAttribute('sigma'), #The standard deviation for the gaussian BoolAttribute('enabled') ] #<- maybe remove this trait def __init__(self, key): assert isinstance( key, tuple ), "DefaultConnectionGene key must be a tuple, not {!r}".format(key) BaseGene.__init__(self, key) #Define the distance between two genes def distance(self, other, config): d = abs(self.sigma - other.sigma) + abs(self.weight - other.weight) + int( self.one_to_one != other.one_to_one) +int(self.is_gaussian != other.is_gaussian) return d * config.compatibility_weight_coefficient
class GuidedMapConnectionGene(BaseGene): #Various parameters for defining a connection. _gene_attributes = [ BoolAttribute( 'one2one' ), #if true then the connection scheme is one to one, else one to all BoolAttribute('extended'), BoolAttribute('uniform'), #step or uniform FloatAttribute( 'weight' ), #Weigth is used as the mean of the normal distribution for 1-to-all BoolAttribute('enabled'), BoolAttribute('is_mod') ] def __init__(self, key): assert isinstance( key, tuple ), "DefaultConnectionGene key must be a tuple, not {!r}".format(key) BaseGene.__init__(self, key) #Define the distance between two genes def distance(self, other, config): d = abs(self.weight - other.weight) + int(self.one2one == other.one2one) \ + int(self.uniform == other.uniform) + int(self.enabled == other.enabled) + int(self.is_mod == other.is_mod) \ + int(self.extended == other.extended) return d * config.compatibility_weight_coefficient
class ExtendedMapNodeGene(DefaultNodeGene): _gene_attributes = [FloatAttribute('bias'), #The bias of the neuron StringAttribute('activation', options='sigmoid'), # The activation function, tunable from the config StringAttribute('aggregation', options='sum'), #The aggregation function BoolAttribute('is_isolated'), #Map vs isolated neuron BoolAttribute('is_switch')] def distance(self, other, config): #Heavier weights for activation and aggregation functions - force neat to put identical networks with different] #functions on the output neuron to different species d = abs(self.bias - other.bias) + 5 * int(self.activation == other.activation) + 5 * int(self.aggregation == other.aggregation) \ + int(self.is_isolated == other.is_isolated) + int(self.is_switch - other.is_switch) return d * config.compatibility_weight_coefficient
class SwitchConnectionGene(DefaultConnectionGene): _gene_attributes = [ FloatAttribute('weight'), BoolAttribute('is_mod'), BoolAttribute('enabled') ] #The neat package complains if this attribute is not present. def distance(self, other, config): d = abs(self.weight - other.weight) if self.enabled != other.enabled: d += 1.0 if self.is_mod != other.is_mod: d += 1 return d * config.compatibility_weight_coefficient
class FormConnectionGene(BaseGene): __gene_attributes__ = [ MatrixAttribute('transform', default=np.identity(4)), # BoolAttribute('copy'), BoolAttribute('negate'), BoolAttribute('enabled') ] def distance(self, other, config): d = np.linalg.norm(self.transform - other.transform) # d += self.copy != other.copy d += self.negate != other.negate d += self.enabled != other.enabled return d * config.compatibility_weight_coefficient
class GuidedMapNodeGene(DefaultNodeGene): _gene_attributes = [ FloatAttribute('bias'), #The bias of the neuron StringAttribute('activation', options='sigmoid' ), # The activation function, tunable from the config StringAttribute('aggregation', options='sum'), #The aggregation function BoolAttribute('is_isolated'), #Map vs isolated neuron BoolAttribute('is_switch') ] def distance(self, other, config): d = abs(self.bias - other.bias) + int(self.activation == other.activation) + int(self.aggregation == other.aggregation) \ + int(self.is_isolated == other.is_isolated) + int(self.is_switch - other.is_switch) return d * config.compatibility_weight_coefficient
class TransitionGene(BaseGene): """ Class representing the gene of a transition in the state machine. """ _gene_attributes = [ ConditionsAttribute('conditions'), BoolAttribute('enabled') ] def __init__(self, key): assert isinstance( key, tuple), "TransitionGene key must be an tuple, not {!r}".format(key) BaseGene.__init__(self, key) def distance(self, other, config): assert isinstance(other, TransitionGene) # TODO: add difference with maximal value for difference of condition being 1. # TODO: Track conditions (possibly) return config.compatibility_difference_coefficient * abs( len(other.conditions) - len(self.conditions)) def copy(self): transition = TransitionGene(self.key) transition.conditions = copy.deepcopy(self.conditions) transition.enabled = self.enabled return transition
class DefaultConnectionGene(BaseGene): __gene_attributes__ = [FloatAttribute('weight'), BoolAttribute('enabled')] def distance(self, other, config): d = abs(self.weight - other.weight) if self.enabled != other.enabled: d += 1.0 return d * config.compatibility_weight_coefficient
class SharedConnectionGene(DefaultConnectionGene): _gene_attributes = [EmptyAttribute('weight'), BoolAttribute('enabled')] def __init__(self, key): BaseGene.__init__(self, key) def get_weight(self): return self.weight.weight
class CircuitConnectionGene(BaseGene): __gene_attributes__ = [StringAttribute('component'), FloatAttribute('value'), BoolAttribute('enabled')] def distance(self, other, config): d = abs(self.value - other.value) if self.component != other.component: d += 1.0 if self.enabled != other.enabled: d += 1.0 return d * config.compatibility_weight_coefficient
class DefaultConnectionGene(BaseGene): __gene_attributes__ = [FloatAttribute('weight'), BoolAttribute('enabled')] @classmethod def parse_config(cls, config, param_dict): return DefaultGeneConfig(cls.__gene_attributes__, param_dict) def distance(self, other, config): d = abs(self.weight - other.weight) if self.enabled != other.enabled: d += 1.0 return d * config.compatibility_weight_coefficient
class DefaultConnectionGene(BaseGene): _gene_attributes = [FloatAttribute('weight'), BoolAttribute('enabled')] def __init__(self, key): assert isinstance(key, tuple), "DefaultConnectionGene key must be a tuple, not {!r}".format(key) BaseGene.__init__(self, key) def distance(self, other, config): d = abs(self.weight - other.weight) if self.enabled != other.enabled: d += 1.0 return d * config.compatibility_weight_coefficient
class CircuitConnectionGene(BaseGene): __gene_attributes__ = [ StringAttribute('component'), FloatAttribute('value'), BoolAttribute('enabled') ] @classmethod def parse_config(cls, config, param_dict): return DefaultGeneConfig(cls.__gene_attributes__, param_dict) def distance(self, other, config): d = abs(self.value - other.value) if self.component != other.component: d += 1.0 if self.enabled != other.enabled: d += 1.0 return d * config.compatibility_weight_coefficient
class SwitchNodeGene(DefaultNodeGene): _gene_attributes = [ FloatAttribute('bias'), StringAttribute('activation', options='sigmoid'), StringAttribute('aggregation', options='sum'), BoolAttribute('is_switch') ] def distance(self, other, config): d = abs(self.bias + other.bias) if self.activation != other.activation: d += 1.0 if self.aggregation != other.aggregation: d += 1.0 if self.is_switch != other.is_switch: d = 3 return d * config.compatibility_weight_coefficient
class DefaultConnectionGene(BaseGene): _gene_attributes: List[BaseAttribute] = [ FloatAttribute("weight"), BoolAttribute("enabled"), ] def __init__(self, key: Tuple[int, int]): assert isinstance( key, tuple ), "DefaultConnectionGene key must be a tuple, not {!r}".format(key) BaseGene.__init__(self, key) def distance(self, other: DefaultConnectionGene, config: DefaultGenomeConfig) -> float: d = abs(self.weight - other.weight) if self.enabled != other.enabled: d += 1.0 return d * config.compatibility_weight_coefficient
class MapNodeGene(DefaultNodeGene): _gene_attributes = [ FloatAttribute('bias'), #The bias of the neuron StringAttribute('activation', options='sigmoid' ), # The activation function, tunable from the config StringAttribute('aggregation', options='sum'), #The aggregation function BoolAttribute('is_isolated') ] #Map vs isolated neuron def distance(self, other, config): d = 0 if self.activation != other.activation: d += 1.0 if self.aggregation != other.aggregation: d += 1.0 if self.is_isolated != other.is_isolated: d += 1 return d * config.compatibility_weight_coefficient