1 | /* |
---|
2 | Copyright 2006 by Sean Luke and George Mason University |
---|
3 | Licensed under the Academic Free License version 3.0 |
---|
4 | See the file "LICENSE" for more information |
---|
5 | */ |
---|
6 | |
---|
7 | package ec.spatial; |
---|
8 | |
---|
9 | import ec.*; |
---|
10 | import ec.util.*; |
---|
11 | import ec.select.TournamentSelection; |
---|
12 | |
---|
13 | /* |
---|
14 | * SpatialTournamentSelection.java |
---|
15 | * |
---|
16 | * By: Liviu Panait |
---|
17 | */ |
---|
18 | |
---|
19 | /** |
---|
20 | * A slight modification of the tournament selection procedure for use with spatially-embedded EAs. |
---|
21 | * |
---|
22 | * When selecting an individual, the SpatialTournamentSelection is told a specific individual. |
---|
23 | * It then picks N individuals at random which are within a certain distance (the <i>neighborhood size</i>) of that individual. These |
---|
24 | * individuals then enter a tournament a-la standard Tournament Selection. |
---|
25 | * |
---|
26 | * <p>The method of picking individuals is either <tt>uniform</tt> (picking individuals using the Space interface's |
---|
27 | * getRandomIndividual(...)) or <tt>random-walk</tt> (wandering <i>distance</i> steps at random). You can also |
---|
28 | * stipulate whether the original individual must be in the tournament. |
---|
29 | * |
---|
30 | <p><b>Parameters</b><br> |
---|
31 | <table> |
---|
32 | <tr><td valign=top><i>base.</i><tt>neighborhood-size</tt><br> |
---|
33 | <font size=-1>int >= 1</font></td> |
---|
34 | <td valign=top>(the neighborhood size)</td></tr> |
---|
35 | |
---|
36 | <tr><td valign=top><i>base.</i><tt>ind-competes</tt><br> |
---|
37 | <font size=-1> bool = <tt>true</tt> or <tt>false</tt> (default)</font></td> |
---|
38 | <td valign=top>(Do we include the base individual in the tournament?)</td></tr> |
---|
39 | |
---|
40 | <tr><td valign=top><i>base.</i><tt>type</tt><br> |
---|
41 | <font size=-1>String: uniform (default) or random-walk</font></td> |
---|
42 | <td valign=top>Method for selecting individuals in neighborhood</td></tr> |
---|
43 | |
---|
44 | </table> |
---|
45 | |
---|
46 | Further parameters may be found in ec.select.TournamentSelection. |
---|
47 | |
---|
48 | <p><b>Default Base</b><br> |
---|
49 | spatial.tournament |
---|
50 | * |
---|
51 | * @author Liviu Panait and Sean Luke |
---|
52 | * @version 2.0 |
---|
53 | */ |
---|
54 | public class SpatialTournamentSelection extends TournamentSelection |
---|
55 | { |
---|
56 | /** |
---|
57 | The size of the neighborhood from where parents are selected. Small neighborhood sizes |
---|
58 | enforce a local selection pressure, while larger values for this parameters allow further-away |
---|
59 | individuals to compete for breeding as well. |
---|
60 | */ |
---|
61 | public static final String P_N_SIZE = "neighborhood-size"; |
---|
62 | int neighborhoodSize; |
---|
63 | |
---|
64 | /** |
---|
65 | Some models assume an individual is always selected to compete for breeding a child that would |
---|
66 | take its location in space. Other models don't make this assumption. This parameter allows one |
---|
67 | to specify whether an individual will be selected to compete with others for breeding a child that |
---|
68 | will take its location in space. If the parameter value is not specified, it is assumed to be false |
---|
69 | by default. |
---|
70 | */ |
---|
71 | public static final String P_IND_COMPETES = "ind-competes"; |
---|
72 | boolean indCompetes; |
---|
73 | |
---|
74 | |
---|
75 | /** |
---|
76 | Selection procedure. |
---|
77 | */ |
---|
78 | public static final String P_TYPE = "type"; |
---|
79 | public static final String V_UNIFORM = "uniform"; |
---|
80 | public static final String V_RANDOM_WALK = "random-walk"; |
---|
81 | public static final int TYPE_UNIFORM = 0; |
---|
82 | public static final int TYPE_RANDOM_WALK = 1; |
---|
83 | int type; |
---|
84 | |
---|
85 | public void setup(final EvolutionState state, final Parameter base) |
---|
86 | { |
---|
87 | super.setup(state,base); |
---|
88 | |
---|
89 | Parameter defaultBase = defaultBase(); |
---|
90 | |
---|
91 | neighborhoodSize = state.parameters.getInt( base.push(P_N_SIZE), defaultBase.push(P_N_SIZE), 1 ); |
---|
92 | if( neighborhoodSize < 1 ) |
---|
93 | state.output.fatal( "Parameter not found, or its value is < 1.", base.push(P_N_SIZE), defaultBase.push(P_N_SIZE)); |
---|
94 | |
---|
95 | if (!state.parameters.exists(base.push(P_TYPE), defaultBase.push(P_TYPE)) || |
---|
96 | state.parameters.getString( base.push(P_TYPE), defaultBase.push(P_TYPE)).equals(V_UNIFORM)) |
---|
97 | type = TYPE_UNIFORM; |
---|
98 | else if (state.parameters.getString( base.push(P_TYPE), defaultBase.push(P_TYPE)).equals(V_RANDOM_WALK)) |
---|
99 | type = TYPE_RANDOM_WALK; |
---|
100 | else state.output.fatal("Invalid parameter, must be either " + V_RANDOM_WALK + " or " + V_UNIFORM + ".", |
---|
101 | base.push(P_TYPE), defaultBase.push(P_TYPE)); |
---|
102 | |
---|
103 | indCompetes = state.parameters.getBoolean(base.push(P_IND_COMPETES), defaultBase.push(P_IND_COMPETES), false); |
---|
104 | } |
---|
105 | |
---|
106 | |
---|
107 | public Parameter defaultBase() |
---|
108 | { |
---|
109 | return SpatialDefaults.base().push(P_TOURNAMENT); |
---|
110 | } |
---|
111 | |
---|
112 | public int getRandomIndividual(int number, int subpopulation, EvolutionState state, int thread) |
---|
113 | { |
---|
114 | Subpopulation subpop = state.population.subpops[subpopulation]; |
---|
115 | if (!(subpop instanceof Space)) |
---|
116 | state.output.fatal( "Subpopulation "+subpopulation+" is not a spatially-embedded subpopulation.\n"); |
---|
117 | Space space = (Space)(state.population.subpops[subpopulation]); |
---|
118 | int index = space.getIndex(thread); |
---|
119 | |
---|
120 | if (number==0 && indCompetes) // Should we just return the individual? |
---|
121 | return index; |
---|
122 | else if (type == TYPE_UNIFORM) // Should we pick randomly in the space up to the given distance? |
---|
123 | return space.getIndexRandomNeighbor(state,thread,neighborhoodSize); |
---|
124 | else // if (type == TYPE_RANDOM_WALK) // Should we do a random walk? |
---|
125 | { |
---|
126 | int oldIndex = index; |
---|
127 | for(int x=0; x < neighborhoodSize; x++) |
---|
128 | space.setIndex(thread, space.getIndexRandomNeighbor(state, thread, 1)); |
---|
129 | int val = space.getIndex(thread); |
---|
130 | space.setIndex(thread,oldIndex); // just in case we weren't supposed to mess around with that |
---|
131 | return val; |
---|
132 | } |
---|
133 | } |
---|
134 | } |
---|