1 | /*
|
---|
2 | Copyright 2006 by Sean Luke
|
---|
3 | Licensed under the Academic Free License version 3.0
|
---|
4 | See the file "LICENSE" for more information
|
---|
5 | */
|
---|
6 |
|
---|
7 |
|
---|
8 | package ec.app.tutorial3;
|
---|
9 | import ec.*;
|
---|
10 | import ec.util.*;
|
---|
11 |
|
---|
12 | public class OurSelection extends SelectionMethod
|
---|
13 | {
|
---|
14 | // We have to specify a default base
|
---|
15 | public static final String P_OURSELECTION = "our-selection";
|
---|
16 | public Parameter defaultBase() { return new Parameter(P_OURSELECTION); }
|
---|
17 |
|
---|
18 | public static final String P_MIDDLEPROBABILITY = "middle-probability"; // our parameter name
|
---|
19 |
|
---|
20 | public double middleProbability;
|
---|
21 |
|
---|
22 | public void setup(final EvolutionState state, final Parameter base)
|
---|
23 | {
|
---|
24 | super.setup(state,base); // always call super.setup(...) first if it exists!
|
---|
25 |
|
---|
26 | Parameter def = defaultBase();
|
---|
27 |
|
---|
28 | // gets a double between min (0.0) and max (1.0), from the parameter
|
---|
29 | // database, returning a value of min-1 (-1.0) if the parameter doesn't exist or was
|
---|
30 | // outside this range.
|
---|
31 | middleProbability = state.parameters.getDoubleWithMax(base.push(P_MIDDLEPROBABILITY),
|
---|
32 | def.push(P_MIDDLEPROBABILITY),0.0,1.0);
|
---|
33 | if (middleProbability < 0.0)
|
---|
34 | state.output.fatal("Middle-Probability must be between 0.0 and 1.0",
|
---|
35 | base.push(P_MIDDLEPROBABILITY),def.push(P_MIDDLEPROBABILITY));
|
---|
36 | }
|
---|
37 |
|
---|
38 | public int produce(final int subpopulation, final EvolutionState state, final int thread)
|
---|
39 | {
|
---|
40 | //toss a coin
|
---|
41 | if (state.random[thread].nextBoolean(middleProbability))
|
---|
42 | {
|
---|
43 | //pick three individuals, return the middle one
|
---|
44 | Individual[] inds = state.population.subpops[subpopulation].individuals;
|
---|
45 | int one = state.random[thread].nextInt(inds.length);
|
---|
46 | int two = state.random[thread].nextInt(inds.length);
|
---|
47 | int three = state.random[thread].nextInt(inds.length);
|
---|
48 | // generally the betterThan(...) method imposes an ordering,
|
---|
49 | // so you shouldn't see any cycles here except in very unusual domains...
|
---|
50 | if (inds[two].fitness.betterThan(inds[one].fitness))
|
---|
51 | {
|
---|
52 | if (inds[three].fitness.betterThan(inds[two].fitness)) // 1 < 2 < 3
|
---|
53 | return two;
|
---|
54 | else if (inds[three].fitness.betterThan(inds[one].fitness)) // 1 < 3 < 2
|
---|
55 | return three;
|
---|
56 | else // 3 < 1 < 2
|
---|
57 | return one;
|
---|
58 | }
|
---|
59 | else if (inds[three].fitness.betterThan(inds[one].fitness)) // 2 < 1 < 3
|
---|
60 | return one;
|
---|
61 | else if (inds[three].fitness.betterThan(inds[two].fitness)) // 2 < 3 < 1
|
---|
62 | return three;
|
---|
63 | else // 3 < 2 < 1
|
---|
64 | return two;
|
---|
65 | }
|
---|
66 | else //select a random individual's index
|
---|
67 | {
|
---|
68 | return state.random[thread].nextInt(
|
---|
69 | state.population.subpops[subpopulation].individuals.length);
|
---|
70 | }
|
---|
71 | }
|
---|
72 | } // close the class
|
---|