Changeset 1265 for framspy


Ignore:
Timestamp:
06/29/23 16:55:28 (10 months ago)
Author:
Maciej Komosinski
Message:

Added a function to assess the number of Parts, Joints, Neurons and Connections of a genotype, and a function to assess the fulfillment of complexity constraints of a genotype

File:
1 edited

Legend:

Unmodified
Added
Removed
  • framspy/FramsticksLib.py

    r1221 r1265  
    7777        def getSimplest(self, genetic_format) -> str:
    7878                return frams.GenMan.getSimplest(genetic_format).genotype._string()
     79
     80
     81        def getPJNC(self, genotype: str):
     82                """
     83                Returns the number of elements of a phenotype built from the provided genotype (without any simulation).
     84
     85                :param genotype: the genotype to assess
     86                :return: a tuple of (numparts,numjoints,numneurons,numconnections) or None if the genotype is invalid.
     87                """
     88                model = frams.Model.newFromString(genotype)
     89                if model.is_valid._int() == 0:
     90                        return None
     91                return (model.numparts._int(), model.numjoints._int(), model.numneurons._int(), model.numconnections._int())
     92
     93
     94        def satisfiesConstraints(self, genotype: str, max_numparts: int, max_numjoints: int, max_numneurons: int, max_numconnections: int, max_numgenochars: int) -> bool:
     95                """
     96                Verifies if the genotype satisfies complexity constraints without actually simulating it.
     97                For example, if the genotype represents a phenotype with 1000 Parts, it will be much faster to check it using this function than to simulate the resulting creature using evaluate() only to learn that the number of its Parts exceeds your defined limit.
     98
     99                :param genotype: the genotype to check
     100                :return: False if any constraint is violated or the genotype is invalid, else True. The constraint value of None means no constraint.
     101                """
     102
     103
     104                def value_within_constraint(actual_value, constraint_value):
     105                        if constraint_value is not None:
     106                                if actual_value > constraint_value:
     107                                        return False
     108                        return True
     109
     110
     111                PJNC = self.getPJNC(genotype)
     112                if PJNC is None:
     113                        return False  # Let's treat invalid genotypes as not satisfying constraints
     114                P, J, N, C = PJNC
     115
     116                valid = True
     117                valid &= value_within_constraint(len(genotype), max_numgenochars)
     118                valid &= value_within_constraint(P, max_numparts)
     119                valid &= value_within_constraint(J, max_numjoints)
     120                valid &= value_within_constraint(N, max_numneurons)
     121                valid &= value_within_constraint(C, max_numconnections)
     122                return valid
    79123
    80124
     
    341385        print('\tValidity (genetic) of Parent1, Parent 2, and Offspring:', framsLib.isValid([parent1, parent2, offspring]))
    342386        print('\tValidity (simulation) of Parent1, Parent 2, and Offspring:', framsLib.isValidCreature([parent1, parent2, offspring]))
     387        print('\tValidity (constraints) of Offspring:', framsLib.satisfiesConstraints(offspring, 2, None, 5, 10, None))
    343388        print('\tRandom genotype:', framsLib.getRandomGenotype(simplest, 2, 6, 2, 4, 100, True))
Note: See TracChangeset for help on using the changeset viewer.