Changeset 1337


Ignore:
Timestamp:
05/06/25 23:01:37 (2 days ago)
Author:
Maciej Komosinski
Message:

Added a comment discussing details of f9 deterministic "body noise"

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/genetics/f9/f9_conv.cpp

    r1336 r1337  
    204204void GenoConv_f90::perturbPartLocations(Model &m) //deterministic "body noise", see APPLY_DETERMINISTIC_BODY_NOISE
    205205{
     206        // If you want to know why some structures that have different f9 genotypes, but "look the same", still get different fitness values, read on!
     207        //
     208        // For the purpose of the following discussion, consider 4 genotypes and the resulting structures as examples:
     209        // 1. square                        /*9*/LFRB
     210        // 2. square overlapping twice      /*9*/LFRBLFRB
     211        // 3. reverse square                /*9*/LRFLB
     212        // 4. cyclic permutation square     /*9*/FRBL
     213        //
     214        // All these structures "look the same" (i.e., the phenotypes are squares and a human does not distinguish any differences).
     215        // However, due to noise added to location of Parts based on the consecutive number of a Part,
     216        // only the phenotypes of 1. and 2. are truly, perfectly identical.
     217        //
     218        // Since the noise is determined by consecutive Part numbers, it is possible to create structures that "look the same",
     219        // but since Parts in them are created in different order, the structures would have slightly differently disturbed
     220        // coordinates (and thus fitness).
     221        //
     222        // To avoid this effect, the noise could instead be generated from x,y,z (i.e., XYZ_LOC) of Parts so that structures that
     223        // "look the same" have exactly the same noise added to each Part (and thus identical fitness), but then the structures that are
     224        // shifted, rotated, or mirrored would still have different noise added to each Part, even though they could also be considered as
     225        // "looking the same".
     226        // In that approach, 3. would be the same as 1. and 2., because it is specifically constructed to use the same x,y,z Part coordinates as 1.
     227        // However, 4. would still be different from 1. and 2., because it is a rotated version of 1, and coordinates of Parts are different.
     228        //
     229        // So there is no quick and simple way to add exactly the same noise to structures that "look the same" independently of
     230        // various potential transformations. Also, what is considered "the same" may vary: is the structure (e.g. a tetrahedron) turned
     231        // upside-down "the same" and do we require the same noise disturbance? It depends on the context and what we use this structure for.
     232        // So that's the question of identifying transformation-invariant features in the structure that would become the source of the noise.
     233        //
     234        // With the current approach, structures that have precisely the same randomly perturbed Part coordinates (and thus fitness) are
     235        // those that have the same Part coordinates before random perturbations AND the order of creating Parts is the same (their genotypes
     236        // may still be different though, like 1. and 2.). Structures which have the same order of created Parts and are only shifted
     237        // relative to each other (i.e., all Parts uniformly shifted) can also be considered precisely the same (ignoring floating point
     238        // differences). There is no such example provided here because it is impossible to make in f9, because we always start
     239        // "drawing" Part #0 from (0,0,0) - it is not possible in f9 to start "drawing" Part #0 from another initial point in space.
     240        //
     241        // A simple alternative (quite opposite to the current approach) could be to add the same amount of shift (noise) to each Part
     242        // depending only on their vertical coordinate - then only vertical transformations would influence that shift, while Part creation
     243        // order and all horizontal shifts, rotations, and reflections would not matter.
     244        // Another determinant of randomness could be the structure of the phenotype graph, traversed depth-first, from some specific Part
     245        // (i.e., closest to the centroid).
     246        // Another determinant of randomness could be the integer (avoiding floating point operations if possible) squared distance from
     247        // the structure center/centroid of Parts (likely displaced by some constant to avoid symmetry and ties in distances, e.g. for
     248        // a vertical stick).
     249        // Another (best?) approach: [start] calculate centroid of current structure, calculate distances from centroid to all Parts, take closest Part, add noise to its coordinates based on its distance from centroid and stddev(x),stddev(y),stddev(z) for all Parts in the entire phenotype (this ensures that noise depends on the orientation of the entire phenotype, i.e., a "horizontal square" and a "vertical square", after added noise, still "look the same"), then go back to [start]. In case many Parts have identical distance, take Part with lowest number (id) - i.e., use the same number as we currently use as the only source of noise, assuming that the same distance from centroid for many Parts means "any of them could be taken as first, it does not matter which one we take". Note that this approach starts to resemble some mechanisms used in the similarity estimation measures - PCA to align/"normalize" the phenotype in 3D etc.
     250
     251        // For now, the source of the noise stays as it is because:
     252        // 1) the source is integer (consecutive number of a Part), not distances or other stats prone to floating point inaccuracies
     253        // 2) the idea is extremely simple
     254        // 3) "complaints/surprises" detailed above are only due to the fact that we know what is the phenotype (solution) and we have some specific expectations (like "rotated or mirrored or shifted or alternatively encoded structures should be equivalent, should behave the same way in simulation, and thus should have the same fitness"). For the optimization algorithm it does not matter and it has no such assumptions, because genotypes for "rotated or mirrored or shifted or alternatively encoded structures" are actually different, so since they are formally different solutions, it is perfectly fine that they may get a different fitness value. Also, while they are extremely close in the phenotype space, they are not neccessarily close in the f9 genotype space where the search takes place.
    206255        for (int i = 0; i < m.getPartCount(); i++)
    207256        {
Note: See TracChangeset for help on using the changeset viewer.