[6152] | 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 | } |
---|