Ejemplo n.º 1
0
class Cluster(object):
    """
    Object used to represent a single cluster as stored
    in the database.

    Attributes:
        cluster_id (_id):
            The Cluster's ID, unique
        representative:
            The ID of the representative StorageGenome.
            All genomes in the cluster are topologically similar
            to it's representative genome.
        fitness:
            The cluster's fitness value.
            This is calculated from the fitness values of the
            contained genomes by a shared fitness approach.
        offspring:
            The amount of offspring that will be generated based
            on genomes from this clusters during the next generation.
        alive:
            Whether the cluster is alive, i.e. if there are any
            genomes in the current population which belong to this
            cluster.
    """

    def __init__(
            self,
    ):
        self._id = ObjectId()  # type: ObjectId
        self.representative = None  # type: ObjectId
        self.fitness = 0  # type: float
        self.offspring = 0  # type: int
        self.alive = True

    def __eq__(self, obj: 'Cluster') -> bool:
        return self._id.__eq__(obj._id) and \
            self.representative.__eq__(obj.representative) and \
            self.fitness.__eq__(obj.fitness) and \
            self.offspring.__eq__(obj.offspring) and \
            self.alive.__eq__(obj.alive)

    @property
    def cluster_id(self):
        return self._id
Ejemplo n.º 2
0
class StorageGenome(object):
    """
    A data structure for storing genome information in a
    compact way.

    Attributes:
        genome_id (_id):
            The Genome's ID, unique in the population.
        inputs:
            A list of the ids of the input nodes. There has to be at least
            one gene per input that is connected to it. Represented as a list
            of tuples of the form (Input_Label, Node-ID).
        outputs:
            A list of the ids of the output nodes. There has to be at least
            one gene per output that is connected to it. Represented as a list
            of tuples of the form (Output_Label, Node-ID).
        genes:
            A list of all genes, that make up the genome. Presented as a tu-
            ple of Gene-ID, a boolean that is true, if the gene is disabled
            and a Fraction that stores the weight of the gene.
        analysis_result:
            A result object that is generated when analyzing the genome.
            This is empty per default.
        cluster:
            The cluster to which the Genome belongs.
    """

    def __init__(
            self,
            genome: 'StorageGenome' = None,
            inputs: List[str] = None,
            outputs: List[str] = None
    ):
        """
        :param genome: If genome is given, its inputs are copied
            (except for id)
        :param inputs: A list of strings, representing the inputs nodes' labels
        """
        self._id = ObjectId()
        self.is_alive = True if genome is None else genome.is_alive
        self.fitness = 0 if genome is None else genome.fitness  # type: float
        self.inputs = {} if genome is None else deepcopy(genome.inputs)  # type: Dict[str, int]
        self.outputs = {} if genome is None else deepcopy(genome.outputs)  # type: Dict[str, int]
        self.genes = {} if genome is None else deepcopy(genome.genes)  # type: Dict[int, Tuple[bool, Fraction]]
        self.analysis_result = AnalysisResult() if genome is None \
            else AnalysisResult(genome.analysis_result)
        self.cluster = ObjectId() if genome is None else genome.cluster
        if inputs and outputs:
            self._init_with_nodes(inputs, outputs)

    def _init_with_nodes(self, inputs: List[str], outputs: List[str]):
        node_id = 0
        for input_label in inputs:
            self.inputs[input_label] = node_id
            node_id += 1
        for output_label in outputs:
            self.outputs[output_label] = node_id
            node_id += 1

    def __eq__(self, obj: 'StorageGenome'):
        if not self._id.__eq__(obj._id) \
                or not self.is_alive.__eq__(obj.is_alive) \
                or not self.inputs.__eq__(obj.inputs) \
                or not self.outputs.__eq__(obj.outputs) \
                or not self.genes.__eq__(obj.genes) \
                or not self.analysis_result.__eq__(obj.analysis_result) \
                or not self.fitness.__eq__(obj.fitness) \
                or not self.cluster.__eq__(obj.cluster):
            return False
        return True

    @property
    def genome_id(self):
        return self._id