IntegerGene.applyMutation correct/meaningful?

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

IntegerGene.applyMutation correct/meaningful?

Daniel Schreiber-3
Hi everyone,

I just played around with this framework and found that the
IntegerGene.applyMutation method is not really meaningfull - or do I
just not understand it?
Would not something like the following make more sense?

greets, Daniel

        /**
         * Scales value uniformly, i.e. a_percentage of 1 sets the value to
         * the upper bound and all positive percentages scale linearly between
         * the current value and the upper bound.
         * Analogously for negative percentages.
         * @param a_index ignored (because there is only 1 atomic element)
         * @param a_percentage percentage of mutation (greater than -1 and smaller
         * than 1)
         *
         * @author Daniel Schreiber
         * @since 1.1
         */
        public void applyMutation(final int a_index, final double a_percentage) {
                int add;
                if(a_percentage >= 0) {
                        add = (int) Math.round(((long) getUpperBounds() - (long)
intValue()) * a_percentage);
                } else {
                        add = (int) Math.round(((long) intValue() - (long)
getLowerBounds()) * a_percentage); //negative!
                }
                setAllele(new Integer(intValue()+add));
        }

------------------------------------------------------------------------------
Sell apps to millions through the Intel(R) Atom(Tm) Developer Program
Be part of this innovative community and reach millions of netbook users
worldwide. Take advantage of special opportunities to increase revenue and
speed time-to-market. Join now, and jumpstart your future.
http://p.sf.net/sfu/intel-atom-d2d
_______________________________________________
jgap-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/jgap-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: IntegerGene.applyMutation correct/meaningful?

Christoph Langguth-3
Daniel Schreiber schrieb:
> Hi everyone,
>
> I just played around with this framework and found that the
> IntegerGene.applyMutation method is not really meaningfull - or do I
> just not understand it?
> Would not something like the following make more sense?
>
> greets, Daniel
>
Hi Daniel,

it all depends on the interpretation :-)

The existing code interprets the mutation percentage as relative to the
entire domain (upperBound - lowerBound); it may try to assign
out-of-range values, but fixes that on the fly via the
mapValueToWithinBounds().

You're interpreting it as the percentage of variation between the
current value and the respective bound of where the mutation is
"pointing to".

I had some theoretical thoughts about how this actually influences the
probability of "visiting" a point. Turns out they weren't exactly right
(so I won't tell them here), but not exactly wrong either: your method
produces a rather different behavior.

Since it actually is quite an interesting question, which can be
empirically answered by some quick (and dirty) code, I decided to just
try it out. The code is attached.*

If you're only interested in the results:
http://img831.imageshack.us/img831/9161/keys.png


HTH & cheers,
Chris

PS (*): in case attachment doesn't get through, it's also available
here: http://www.megaupload.com/?d=V06M6INA , though I don't know for
how long :-)

------------------------------------------------------------------------------
Sell apps to millions through the Intel(R) Atom(Tm) Developer Program
Be part of this innovative community and reach millions of netbook users
worldwide. Take advantage of special opportunities to increase revenue and
speed time-to-market. Join now, and jumpstart your future.
http://p.sf.net/sfu/intel-atom-d2d
_______________________________________________
jgap-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/jgap-users

jgapstuff.zip (75K) Download Attachment
smime.p7s (8K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: IntegerGene.applyMutation correct/meaningful?

Daniel Schreiber-3
Hi Chris,
thank you very much for that detailed answer!
At first I couldn't believe your statistics cause I expected them to
be just the other way round - but after reading a bit of your and jgap
code it looks like setAllele() respectively mapValueToWithinBounds()
doesn't work how (I) expected.
I thought that out of bound values would be mapped to the
corresponding boundary but instead a random value between the bounds
is generated. Is this intended? (I don't know enough about GA to
understand this)
with changed mapValueToWithinBounds() the behavior of the standart
mutation is even worse than the alternative - see attached file..

greets, Daniel

2010/8/25 Christoph Langguth <[hidden email]>:

> Daniel Schreiber schrieb:
>>
>> Hi everyone,
>>
>> I just played around with this framework and found that the
>> IntegerGene.applyMutation method is not really meaningfull - or do I
>> just not understand it?
>> Would not something like the following make more sense?
>>
>> greets, Daniel
>>
> Hi Daniel,
>
> it all depends on the interpretation :-)
>
> The existing code interprets the mutation percentage as relative to the
> entire domain (upperBound - lowerBound); it may try to assign out-of-range
> values, but fixes that on the fly via the mapValueToWithinBounds().
>
> You're interpreting it as the percentage of variation between the current
> value and the respective bound of where the mutation is "pointing to".
>
> I had some theoretical thoughts about how this actually influences the
> probability of "visiting" a point. Turns out they weren't exactly right (so
> I won't tell them here), but not exactly wrong either: your method produces
> a rather different behavior.
>
> Since it actually is quite an interesting question, which can be empirically
> answered by some quick (and dirty) code, I decided to just try it out. The
> code is attached.*
>
> If you're only interested in the results:
> http://img831.imageshack.us/img831/9161/keys.png
>
>
> HTH & cheers,
> Chris
>
> PS (*): in case attachment doesn't get through, it's also available
> here: http://www.megaupload.com/?d=V06M6INA , though I don't know for how
> long :-)
>

------------------------------------------------------------------------------
Sell apps to millions through the Intel(R) Atom(Tm) Developer Program
Be part of this innovative community and reach millions of netbook users
worldwide. Take advantage of special opportunities to increase revenue and
speed time-to-market. Join now, and jumpstart your future.
http://p.sf.net/sfu/intel-atom-d2d
_______________________________________________
jgap-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/jgap-users

jgapstuff2.zip (58K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: IntegerGene.applyMutation correct/meaningful?

Christoph Langguth-3
Am 25.08.2010 16:00, schrieb Daniel Schreiber:

> Hi Chris,
> thank you very much for that detailed answer!
> At first I couldn't believe your statistics cause I expected them to
> be just the other way round - but after reading a bit of your and jgap
> code it looks like setAllele() respectively mapValueToWithinBounds()
> doesn't work how (I) expected.
> I thought that out of bound values would be mapped to the
> corresponding boundary but instead a random value between the bounds
> is generated. Is this intended? (I don't know enough about GA to
> understand this)
> with changed mapValueToWithinBounds() the behavior of the standart
> mutation is even worse than the alternative - see attached file..
>
Hi Daniel,

well, again, "better" or "worse" is always subjective (and may also
depend on the optimization goal). What this change did is essentially
halve the probability of every number except the boundaries, which then
got all the rest, i.e., an extraordinary amount of "hits".

I think we agree that a reasonably uniform distribution is usually what
you want to have, so the current implementation seems to do fairly well.
However, after looking more carefully at the code, I agree that the
second random number generation in mapValueToWithinBounds() is not
needed. IMO, what makes most sense (and should be slightly more
performant) is to simply have it "rolling" uniformly over the
boundaries, i.e. something like:

if (value > upperBound) value -= (upperBound-lowerBound+1)
else if (value < lowerBound) value += (upperBound-lowerBound+1)

Maybe this could be considered by the devs?

As a side note, I've been heavily "modding" the framework for my own
uses (some might say "raping" it at times), including my own genes
written from scratch and strategies for mapping other things than plain
numbers to and from [0,1] intervals and trying to find sensible "plans"
for mutations. One strategy that works out quite well for me is
(translated to the IntegerGene):

@Override
public void applyMutation(int aIndex, double aPercentage) {
     double range = ((long) getUpperBounds() - (long) getLowerBounds())
* aPercentage;
     if (getAllele() == null) {
         setAllele(new Integer((int) range + getLowerBounds()));
     } else {
         int current = intValue();
         int upper = getUpperBounds();
         int lower = getLowerBounds();
         int newValue = (int) Math.round(current + range);
         if (newValue > upper) {
             if (current != upper) {
                 newValue -= (upper - lower + 1);
             } else {
                 newValue = upper;
             }
         } else if (newValue < lower) {
             if (current != lower) {
                 newValue += (upper - lower + 1);
             } else {
                 newValue = lower;
             }
         }
         setAllele(Integer.valueOf(newValue));
     }
}

This does the abovementioned "rolling" over the boundaries to stay
within range efficiently, with one additional twist: it stops once at
the boundaries before rolling over. In other words, it's a combination
of your proposal and my abovementioned one. This results in the
boundaries getting about twice as many other hits as other numbers (but
not linearly more, as mere capping does).
I have found this to be quite useful because it usually (at least in
what I'm doing) is quite promising to try the extrema, so it effectively
raises the chances to find them quicker.

Let's not forget that the fitness function in the SimpleExample assigns
every possible value the same fitness (for the purpose of finding out
the distribution *without* preferring anyone). In a real-world
algorithm, you of course want to converge to a good solution as fast as
possible, while still trying out others. Try changing the fitness
function to
         conf.setFitnessFunction(new FitnessFunction() {
             protected double evaluate(IChromosome aSubject) {
                 return (Integer) aSubject.getGene(0).getAllele();
             }
         });
and see how that (correctly) affects the distributions ;-)


Cheers,
Chris

------------------------------------------------------------------------------
Sell apps to millions through the Intel(R) Atom(Tm) Developer Program
Be part of this innovative community and reach millions of netbook users
worldwide. Take advantage of special opportunities to increase revenue and
speed time-to-market. Join now, and jumpstart your future.
http://p.sf.net/sfu/intel-atom-d2d
_______________________________________________
jgap-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/jgap-users
Loading...