Changeset 751


Ignore:
Timestamp:
02/28/18 23:41:58 (6 years ago)
Author:
Maciej Komosinski
Message:

More versatile mutation function for numbers

Location:
cpp/frams/genetics
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/genetics/oper_fx.cpp

    r749 r751  
    8080double GenoOperators::mutateNeuProperty(double current, Neuro *n, int i)
    8181{
    82         if (i == -1) return mutateCreepNoLimit('f', current, -10, 10); //i==-1: mutating weight of neural connection
     82        if (i == -1) return mutateCreepNoLimit('f', current, 2, true); //i==-1: mutating weight of neural connection
    8383        Param p;
    8484        if (i >= 100) { i -= 100; p = n->getClass()->getProperties(); }
     
    9797        ExtValue ev;
    9898        p.get(i, ev);
    99         ev.setDouble(mutateCreep(p.type(i)[0], ev.getDouble(), mn, mx));
     99        ev.setDouble(mutateCreep(p.type(i)[0], ev.getDouble(), mn, mx, true));
    100100        p.set(i, ev);
    101101        return true;
     
    123123                double mn, mx, df;
    124124                getMinMaxDef(&p, i, mn, mx, df);
    125                 newval = mutateCreep(p.type(i)[0], oldval, mn, mx);
     125                newval = mutateCreep(p.type(i)[0], oldval, mn, mx, true);
    126126                        }
    127127        return true;
    128128}
    129129
    130 double GenoOperators::mutateCreepNoLimit(char type, double current, double mn, double mx)
    131 {
    132         double result = RndGen.Gauss(current, (mx - mn) / 2 / 5); // /halfinterval, 5 times narrower
    133         if (type == 'd') { result = int(result + 0.5); if (result == current) result += randomN(2) * 2 - 1; }
    134         else result = floor(result * 1000 + 0.5) / 1000.0; //round
     130double GenoOperators::mutateCreepNoLimit(char type, double current, double stddev, bool limit_precision_3digits)
     131{
     132        double result = RndGen.Gauss(current, stddev);
     133        if (type == 'd')
     134        {
     135                result = int(result + 0.5);
     136                if (result == current) result += randomN(2) * 2 - 1; //force some change
     137        }
     138        else
     139        {
     140                if (limit_precision_3digits)
     141                        result = floor(result * 1000 + 0.5) / 1000.0; //round
     142        }
    135143        return result;
    136144}
    137145
    138 double GenoOperators::mutateCreep(char type, double current, double mn, double mx)
    139 {
    140         double result = mutateCreepNoLimit(type, current, mn, mx); //TODO consider that when boundary is touched (reflect/absorb below), the default precision (3 digits) may change. Is it good or bad?
     146double GenoOperators::mutateCreep(char type, double current, double mn, double mx, double stddev, bool limit_precision_3digits)
     147{
     148        double result = mutateCreepNoLimit(type, current, stddev, limit_precision_3digits);
     149        //TODO consider that when boundary is touched (reflect+absorb below), the requested precision (3 digits) may change. Is it good or bad?
    141150        //reflect:
    142151        if (result > mx) result = mx - (result - mx); else
     
    146155                if (result < mn) result = mn;
    147156        return result;
     157}
     158
     159double GenoOperators::mutateCreep(char type, double current, double mn, double mx, bool limit_precision_3digits)
     160{
     161        double stddev = (mx - mn) / 2 / 5; // magic arbitrary formula for stddev, which becomes /halfinterval, 5 times narrower
     162        return mutateCreep(type, current, mn, mx, stddev, limit_precision_3digits);
    148163}
    149164
  • cpp/frams/genetics/oper_fx.h

    r749 r751  
    187187        static bool mutateProperty(ParamInterface &p, int propindex); ///<like mutatePropertyNaive(), but uses special probability distributions for some neuron properties.
    188188        static bool getMutatedProperty(ParamInterface &p, int i, double oldval, double &newval); ///<like mutateProperty(), but just returns \e newval, does not get nor set it using \e p.
    189         static double mutateCreepNoLimit(char type, double current, double mn, double mx); ///<returns \e current value creep-mutated with Gaussian distribution within [ \e mn , \e mx ] interval. Forced precision: 3 digits after comma. \e type must be either 'd' (integer) or 'f' (float/double).
    190         static double mutateCreep(char type, double current, double mn, double mx); ///<just as mutateCreepNoLimit(), but forces mutated value into the [mn,mx] range using the 'reflect' approach.
     189        static double mutateCreepNoLimit(char type, double current, double stddev, bool limit_precision_3digits); ///<returns \e current value creep-mutated with Gaussian distribution and \e stddev standard deviation. Precision limited to 3 digits after comma when \e limit_precision_3digits is true. \e type must be either 'd' (integer) or 'f' (float/double).
     190        static double mutateCreep(char type, double current, double mn, double mx, double stddev, bool limit_precision_3digits); ///<just as mutateCreepNoLimit(), but forces mutated value into the [mn,mx] range using the 'reflect' approach.
     191        static double mutateCreep(char type, double current, double mn, double mx, bool limit_precision_3digits); ///<just as mutateCreepNoLimit(), but forces mutated value into the [\e mn,\e mx] range using the 'reflect' approach and assumes standard deviation to be a fraction of the mx-mn interval width.
    191192        static void setIntFromDoubleWithProbabilisticDithering(ParamInterface &p, int index, double value); ///<sets a double value in an integer field; when a value is non-integer, applies random "dithering" so that both lower and higher integer value have some chance to be set.
    192193        static void linearMix(vector<double> &p1, vector<double> &p2, double proportion); ///<mixes two real-valued vectors; inherited proportion should be within [0,1]; 1.0 does not change values (all inherited), 0.5 causes both vectors to become their average, 0.0 swaps values (none inherited).
Note: See TracChangeset for help on using the changeset viewer.