1 10 package org.jgap.impl; 11 12 import java.math.*; 13 import java.util.*; 14 import org.jgap.*; 15 import org.jgap.util.*; 16 17 31 public class WeightedRouletteSelector 32 extends NaturalSelector implements ICloneable { 33 34 private final static String CVS_REVISION = "$Revision: 1.35 $"; 35 36 private static final double DELTA = 0.000001d; 38 39 private static final BigDecimal ZERO_BIG_DECIMAL = new BigDecimal(0.0d); 40 41 46 private HashMap m_wheel = new HashMap(); 47 48 53 private double m_totalNumberOfUsedSlots; 54 55 60 private Pool m_counterPool = new Pool(); 61 62 private WeightedRouletteSelConfig m_config 63 = new WeightedRouletteSelConfig(); 64 65 73 public WeightedRouletteSelector() { 74 this(Genotype.getStaticConfiguration()); 75 } 76 77 83 public WeightedRouletteSelector(Configuration a_config) { 84 super(a_config); 85 m_config.m_doublettesAllowed = false; 86 } 87 88 97 protected synchronized void add(final IChromosome a_chromosomeToAdd) { 98 SlotCounter counter = (SlotCounter) m_wheel.get(a_chromosomeToAdd); 107 if (counter != null) { 108 counter.increment(); 111 } 112 else { 113 a_chromosomeToAdd.setIsSelectedForNextGeneration(false); 121 counter = (SlotCounter) m_counterPool.acquirePooledObject(); 125 if (counter == null) { 126 counter = new SlotCounter(); 127 } 128 counter.reset(a_chromosomeToAdd.getFitnessValue()); 129 m_wheel.put(a_chromosomeToAdd, counter); 130 } 131 } 132 133 150 public synchronized void select(int a_howManyToSelect, 151 final Population a_from_pop, 152 Population a_to_pop) { 153 if (a_from_pop != null) { 154 int size = a_from_pop.size(); 155 for (int i = 0; i < size; i++) { 156 add(a_from_pop.getChromosome(i)); 157 } 158 } 159 160 RandomGenerator generator = getConfiguration().getRandomGenerator(); 161 scaleFitnessValues(); 162 Set entries = m_wheel.entrySet(); 171 int numberOfEntries = entries.size(); 172 double[] fitnessValues = new double[numberOfEntries]; 173 double[] counterValues = new double[numberOfEntries]; 174 IChromosome[] chromosomes = new Chromosome[numberOfEntries]; 175 m_totalNumberOfUsedSlots = 0.0d; 176 Iterator entryIterator = entries.iterator(); 177 for (int i = 0; i < numberOfEntries; i++) { 178 Map.Entry chromosomeEntry = (Map.Entry) entryIterator.next(); 179 IChromosome currentChromosome = 180 (IChromosome) chromosomeEntry.getKey(); 181 SlotCounter currentCounter = 182 (SlotCounter) chromosomeEntry.getValue(); 183 fitnessValues[i] = currentCounter.getFitnessValue(); 184 counterValues[i] = fitnessValues[i] * currentCounter.getCounterValue(); 186 chromosomes[i] = currentChromosome; 187 m_totalNumberOfUsedSlots += counterValues[i]; 191 } 192 if (a_howManyToSelect > numberOfEntries 193 && !getDoubletteChromosomesAllowed()) { 194 a_howManyToSelect = numberOfEntries; 195 } 196 IChromosome selectedChromosome; 200 for (int i = 0; i < a_howManyToSelect; i++) { 201 selectedChromosome = spinWheel(generator, fitnessValues, counterValues, 202 chromosomes); 203 selectedChromosome.setIsSelectedForNextGeneration(true); 204 a_to_pop.addChromosome(selectedChromosome); 205 } 206 } 207 208 227 private IChromosome spinWheel(final RandomGenerator a_generator, 228 final double[] a_fitnessValues, 229 double[] a_counterValues, 230 final IChromosome[] a_chromosomes) { 231 double selectedSlot = 234 a_generator.nextDouble() * m_totalNumberOfUsedSlots; 235 if (selectedSlot > m_totalNumberOfUsedSlots) { 236 selectedSlot = m_totalNumberOfUsedSlots; 237 } 238 double currentSlot = 0.0d; 255 FitnessEvaluator evaluator = getConfiguration().getFitnessEvaluator(); 256 boolean isFitter2_1 = evaluator.isFitter(2, 1); 257 for (int i = 0; i < a_counterValues.length; i++) { 258 currentSlot += a_counterValues[i]; 262 boolean found; 263 if (isFitter2_1) { 264 found = selectedSlot - currentSlot <= DELTA; 266 } 267 else { 268 found = currentSlot - selectedSlot <= DELTA; 270 } 271 if (found) { 272 if ( !getDoubletteChromosomesAllowed() ) { 278 m_totalNumberOfUsedSlots -= a_counterValues[i]; 279 a_counterValues[i] = 0; 280 } 281 else { 282 a_counterValues[i] -= a_fitnessValues[i]; 283 m_totalNumberOfUsedSlots -= a_fitnessValues[i]; 284 } 285 if (Math.abs(m_totalNumberOfUsedSlots) < DELTA) { 287 m_totalNumberOfUsedSlots = 0.0d; 288 } 289 return a_chromosomes[i]; 292 } 293 } 294 return a_chromosomes[a_counterValues.length-1]; 298 } 299 300 306 public synchronized void empty() { 307 m_counterPool.releaseAllObjects(m_wheel.values()); 311 m_wheel.clear(); 314 m_totalNumberOfUsedSlots = 0; 315 } 316 317 private void scaleFitnessValues() { 318 double largestFitnessValue = 0.0; 322 BigDecimal totalFitness = ZERO_BIG_DECIMAL; 323 Iterator counterIterator = m_wheel.values().iterator(); 324 while (counterIterator.hasNext()) { 325 SlotCounter counter = (SlotCounter) counterIterator.next(); 326 if (counter.getFitnessValue() > largestFitnessValue) { 327 largestFitnessValue = counter.getFitnessValue(); 328 } 329 BigDecimal counterFitness = new BigDecimal(counter.getFitnessValue()); 330 totalFitness = totalFitness.add(counterFitness.multiply( 331 new BigDecimal(counter.getCounterValue()))); 332 } 333 if (largestFitnessValue > 0.000000d 337 && totalFitness.floatValue() > 0.0000001d) { 338 double scalingFactor = 339 totalFitness.divide(new BigDecimal(largestFitnessValue), 340 BigDecimal.ROUND_HALF_UP).doubleValue(); 341 counterIterator = m_wheel.values().iterator(); 345 while (counterIterator.hasNext()) { 346 SlotCounter counter = (SlotCounter) counterIterator.next(); 347 counter.scaleFitnessValue(scalingFactor); 348 } 349 } 350 } 351 352 358 public boolean returnsUniqueChromosomes() { 359 return false; 360 } 361 362 371 public void setDoubletteChromosomesAllowed(final boolean a_doublettesAllowed) { 372 m_config.m_doublettesAllowed = a_doublettesAllowed; 373 } 374 375 381 public boolean getDoubletteChromosomesAllowed() { 382 return m_config.m_doublettesAllowed; 383 } 384 385 391 public Object clone() { 392 WeightedRouletteSelector result = new WeightedRouletteSelector(getConfiguration()); 393 result.m_wheel = (HashMap)m_wheel.clone(); 394 result.m_config = new WeightedRouletteSelConfig(); 395 result.m_config.m_doublettesAllowed = m_config.m_doublettesAllowed; 396 return result; 397 } 398 399 class WeightedRouletteSelConfig { 400 403 public boolean m_doublettesAllowed; 404 405 } 406 } 407 408 421 class SlotCounter { 422 429 private double m_fitnessValue; 430 431 434 private int m_count; 435 436 446 public void reset(final double a_initialFitness) { 447 m_fitnessValue = a_initialFitness; 448 m_count = 1; 449 } 450 451 460 public double getFitnessValue() { 461 return m_fitnessValue; 462 } 463 464 471 public void increment() { 472 m_count++; 473 } 474 475 482 public int getCounterValue() { 483 return m_count; 484 } 485 486 495 public void scaleFitnessValue(final double a_scalingFactor) { 496 m_fitnessValue /= a_scalingFactor; 497 } 498 499 } 500 | Popular Tags |