1 10 package org.jgap.gp.impl; 11 12 import java.io.*; 13 import java.util.*; 14 import org.jgap.*; 15 import org.jgap.gp.*; 16 import org.jgap.gp.terminal.*; 17 import org.jgap.event.*; 18 import org.jgap.util.*; 19 20 26 public class GPGenotype 27 implements Runnable , Serializable, Comparable { 28 29 private final static String CVS_REVISION = "$Revision: 1.22 $"; 30 31 34 private GPPopulation m_population; 35 36 39 private transient GPConfiguration m_configuration; 40 41 private transient static GPConfiguration m_staticConfiguration; 42 43 46 private transient double m_bestFitness; 47 48 51 private transient double m_totalFitness; 52 53 56 private transient IGPProgram m_allTimeBest; 57 58 private transient double m_allTimeBestFitness; 59 60 63 private boolean m_fullModeAllowed[]; 64 65 68 private Class [] m_types; 69 70 73 private Class [][] m_argTypes; 74 75 78 private CommandGene[][] m_nodeSets; 79 80 83 private int[] m_minDepths; 84 85 88 private int[] m_maxDepths; 89 90 94 private int m_maxNodes; 95 96 99 private boolean m_verbose; 100 101 private Map m_variables; 102 103 private IGPProgram m_fittestToAdd; 104 105 private boolean m_cloneWarningGPProgramShown; 106 107 114 public GPGenotype() 115 throws InvalidConfigurationException { 116 } 117 118 141 public GPGenotype(GPConfiguration a_configuration, GPPopulation a_population, 142 Class [] a_types, Class [][] a_argTypes, 143 CommandGene[][] a_nodeSets, int[] a_minDepths, 144 int[] a_maxDepths, int a_maxNodes) 145 throws InvalidConfigurationException { 146 if (a_configuration == null) { 150 throw new IllegalArgumentException ( 151 "The configuration instance may not be null."); 152 } 153 if (a_population == null) { 154 throw new IllegalArgumentException ( 155 "The population may not be null."); 156 } 157 for (int i = 0; i < a_population.size(); i++) { 158 if (a_population.getGPProgram(i) == null) { 159 throw new IllegalArgumentException ( 160 "The GPProgram instance at index " + i + " in population" + 161 " is null, which is forbidden in general."); 162 } 163 } 164 m_types = a_types; 165 m_argTypes = a_argTypes; 166 m_nodeSets = a_nodeSets; 167 m_maxDepths = a_maxDepths; 168 m_minDepths = a_minDepths; 169 m_maxNodes = a_maxNodes; 170 setGPPopulation(a_population); 171 setGPConfiguration(a_configuration); 172 m_variables = new Hashtable(); 173 m_allTimeBestFitness = FitnessFunction.NO_FITNESS_VALUE; 174 getGPConfiguration().lockSettings(); 178 } 179 180 206 public static GPGenotype randomInitialGenotype(final GPConfiguration a_conf, 207 Class [] a_types, Class [][] a_argTypes, CommandGene[][] a_nodeSets, 208 int a_maxNodes, boolean a_verboseOutput) 209 throws InvalidConfigurationException { 210 int[] minDepths = null; 211 int[] maxDepths = null; 212 return randomInitialGenotype(a_conf, a_types, a_argTypes, a_nodeSets, 213 minDepths, maxDepths, a_maxNodes, 214 a_verboseOutput); 215 } 216 217 247 public static GPGenotype randomInitialGenotype(final GPConfiguration a_conf, 248 Class [] a_types, Class [][] a_argTypes, CommandGene[][] a_nodeSets, 249 int[] a_minDepths, int[] a_maxDepths, int a_maxNodes, 250 boolean a_verboseOutput) 251 throws InvalidConfigurationException { 252 boolean[] fullModeAllowed = new boolean[a_types.length]; 253 for (int i = 0; i < a_types.length; i++) { 254 fullModeAllowed[i] = true; 255 } 256 return randomInitialGenotype(a_conf, a_types, a_argTypes, a_nodeSets, 257 a_minDepths, a_maxDepths, a_maxNodes, 258 fullModeAllowed, a_verboseOutput); 259 } 260 261 294 public static GPGenotype randomInitialGenotype(final GPConfiguration a_conf, 295 Class [] a_types, Class [][] a_argTypes, CommandGene[][] a_nodeSets, 296 int[] a_minDepths, int[] a_maxDepths, int a_maxNodes, 297 boolean[] a_fullModeAllowed, boolean a_verboseOutput) 298 throws InvalidConfigurationException { 299 if (a_argTypes.length != a_fullModeAllowed.length 300 || (a_minDepths != null && a_argTypes.length != a_minDepths.length) 301 || (a_maxDepths != null && a_argTypes.length != a_maxDepths.length) 302 || a_argTypes.length != a_types.length) { 303 throw new IllegalArgumentException ("a_argTypes must have same length" 304 + " as a_types, a_minDepths, a_maxDepths and a_fullModeAllowed"); 305 } 306 System.gc(); 307 if (a_verboseOutput) { 308 System.out.println("Creating initial population"); 309 System.out.println("Memory consumed before creating population: " 310 + SystemKit.getTotalMemoryMB() + "MB"); 311 } 312 GPPopulation pop = new GPPopulation(a_conf, a_conf.getPopulationSize()); 313 pop.create(a_types, a_argTypes, a_nodeSets, a_minDepths, a_maxDepths, 316 a_maxNodes, a_fullModeAllowed); 317 System.gc(); 318 if (a_verboseOutput) { 319 System.out.println("Memory used after creating population: " 320 + SystemKit.getTotalMemoryMB() + "MB"); 321 } 322 GPGenotype gp = new GPGenotype(a_conf, pop, a_types, a_argTypes, a_nodeSets, 323 a_minDepths, a_maxDepths, a_maxNodes); 324 gp.m_fullModeAllowed = a_fullModeAllowed; 325 return gp; 326 } 327 328 public GPConfiguration getGPConfiguration() { 329 return m_configuration; 330 } 331 332 338 public static GPConfiguration getStaticGPConfiguration() { 339 return m_staticConfiguration; 340 } 341 342 350 public static void setStaticGPConfiguration(GPConfiguration a_configuration) { 351 m_staticConfiguration = a_configuration; 352 } 353 354 static class GPFitnessComparator 355 implements Comparator { 356 public int compare(Object o1, Object o2) { 357 if (! (o1 instanceof IGPProgram) || 358 ! (o2 instanceof IGPProgram)) 359 throw new ClassCastException ( 360 "FitnessComparator must operate on IGPProgram instances"); 361 double f1 = ( (IGPProgram) o1).getFitnessValue(); 362 double f2 = ( (IGPProgram) o2).getFitnessValue(); 363 if (f1 > f2) { 364 return 1; 365 } 366 else if (Math.abs(f1 - f2) < 0.000001) { 367 return 0; 368 } 369 else { 370 return -1; 371 } 372 } 373 } 374 382 public void evolve(int a_evolutions) { 383 getGPPopulation().sort(new GPFitnessComparator()); 384 for (int i = 0; i < a_evolutions; i++) { 386 calcFitness(); 387 if (m_bestFitness < 0.000001) { 388 return; 391 } 392 if (m_verbose) { 393 if (i % 25 == 0) { 394 System.out.println("Evolving generation " 395 + i 396 + ", memory free: " 397 + SystemKit.getFreeMemoryMB() 398 + " MB"); 399 } 400 } 401 evolve(); 402 } 403 calcFitness(); 404 } 405 406 413 public void calcFitness() { 414 double totalFitness = 0.0d; 415 GPPopulation pop = getGPPopulation(); 416 IGPProgram best = null; 417 IGPFitnessEvaluator evaluator = getGPConfiguration().getGPFitnessEvaluator(); 418 m_bestFitness = FitnessFunction.NO_FITNESS_VALUE; 419 for (int i = 0; i < pop.size() && pop.getGPProgram(i) != null; i++) { 420 IGPProgram program = pop.getGPProgram(i); 421 double fitness = program.getFitnessValue(); 422 if (best == null || evaluator.isFitter(fitness, m_bestFitness)) { 423 best = program; 424 m_bestFitness = fitness; 425 } 426 totalFitness += fitness; 427 } 428 m_totalFitness = totalFitness; 429 432 if (m_allTimeBest == null 433 || evaluator.isFitter(m_bestFitness, m_allTimeBestFitness)) { 434 pop.setChanged(true); 435 try { 436 ICloneHandler cloner = getGPConfiguration().getJGAPFactory(). 437 getCloneHandlerFor(best, null); 438 if (cloner == null) { 439 m_allTimeBest = best; 440 if (!m_cloneWarningGPProgramShown) { 441 System.out.println("Warning: cannot clone instance of " + 442 best.getClass()); 443 m_cloneWarningGPProgramShown = true; 444 } 445 } 446 else { 447 m_allTimeBest = (IGPProgram) cloner.perform(best, null, null); 448 } 449 } catch (Exception ex) { 450 m_allTimeBest = best; 451 ex.printStackTrace(); 452 } 453 m_allTimeBestFitness = m_bestFitness; 454 getGPConfiguration().getEventManager().fireGeneticEvent( 457 new GeneticEvent(GeneticEvent.GPGENOTYPE_NEW_BEST_SOLUTION, this)); 458 if (m_verbose) { 459 outputSolution(m_allTimeBest); 462 } 463 } 464 } 465 466 472 public IGPProgram getAllTimeBest() { 473 return m_allTimeBest; 474 } 475 476 483 public void outputSolution(IGPProgram a_best) { 484 System.out.println(" Best solution fitness: " + a_best.getFitnessValue()); 485 System.out.println(" Best solution: " + a_best.toStringNorm(0)); 486 String depths = ""; 487 int size = a_best.size(); 488 for (int i = 0; i < size; i++) { 489 if (i > 0) { 490 depths += " / "; 491 } 492 depths += a_best.getChromosome(i).getDepth(0); 493 } 494 if (size == 1) { 495 System.out.println(" Depth of chromosome: " + depths); 496 } 497 else { 498 System.out.println(" Depths of chromosomes: " + depths); 499 } 500 System.out.println(" --------"); 501 } 502 503 511 public void evolve() { 512 try { 513 int popSize = getGPConfiguration().getPopulationSize(); 514 GPPopulation oldPop = getGPPopulation(); 515 GPPopulation newPopulation = new GPPopulation(oldPop, false); 516 if (m_fittestToAdd != null) { 517 newPopulation.addFittestProgram(m_fittestToAdd); 518 m_fittestToAdd = null; 519 } 520 float val; 521 RandomGenerator random = getGPConfiguration().getRandomGenerator(); 522 GPConfiguration conf = getGPConfiguration(); 523 int popSize1 = (int) Math.round(popSize * (1 - conf.getNewChromsPercent())); 526 for (int i = 0; i < popSize1; i++) { 527 getGPConfiguration().clearStack(); 530 val = random.nextFloat(); 531 if (i < popSize - 1 && val < conf.getCrossoverProb()) { 535 IGPProgram i1 = conf.getSelectionMethod().select(this); 538 IGPProgram i2 = conf.getSelectionMethod().select(this); 540 int tries = 0; 542 do { 543 try { 544 IGPProgram[] newIndividuals = conf.getCrossMethod().operate(i1, 545 i2); 546 newPopulation.setGPProgram(i, newIndividuals[0]); 547 newPopulation.setGPProgram(i + 1, newIndividuals[1]); 548 i++; 549 break; 550 } catch (IllegalStateException iex) { 551 tries++; 552 if (tries >= getGPConfiguration().getProgramCreationMaxtries()) { 553 if (!getGPConfiguration().isMaxNodeWarningPrinted()) { 554 System.err.println( 555 "Warning: Maximum number of nodes allowed may be too small"); 556 getGPConfiguration().flagMaxNodeWarningPrinted(); 557 IGPProgram program = cloneProgram(getGPConfiguration(). 560 getPrototypeProgram()); 561 if (program != null) { 562 newPopulation.setGPProgram(i++, program); 563 program = cloneProgram(getGPConfiguration(). 564 getPrototypeProgram()); 565 newPopulation.setGPProgram(i, program); 566 break; 567 } 568 else { 569 throw new IllegalStateException (iex.getMessage()); 570 } 571 } 572 } 573 } 574 } while (true); 575 } 576 else if (val < conf.getCrossoverProb() + conf.getReproductionProb()) { 577 newPopulation.setGPProgram(i, conf.getSelectionMethod().select(this)); 580 } 581 } 582 for (int i = popSize1; i < popSize; i++) { 585 int depth = conf.getMinInitDepth() 588 + random.nextInt(conf.getMaxInitDepth() - conf.getMinInitDepth() 589 + 1); 590 int tries = 0; 591 do { 592 try { 593 IGPProgram program = newPopulation.create(m_types, m_argTypes, 594 m_nodeSets, m_minDepths, m_maxDepths, depth, (i % 2) == 0, 595 m_maxNodes, m_fullModeAllowed); 596 newPopulation.setGPProgram(i, program); 597 break; 598 } catch (IllegalStateException iex) { 599 tries++; 600 if (tries > getGPConfiguration().getProgramCreationMaxtries()) { 601 IGPProgram program = cloneProgram(getGPConfiguration(). 604 getPrototypeProgram()); 605 if (program != null) { 606 newPopulation.setGPProgram(i, program); 607 break; 608 } 609 else { 610 throw new IllegalStateException (iex.getMessage()); 611 } 612 } 613 } 614 } while (true); 615 } 616 setGPPopulation(newPopulation); 619 conf.incrementGenerationNr(); 622 conf.getEventManager().fireGeneticEvent( 625 new GeneticEvent(GeneticEvent.GPGENOTYPE_EVOLVED_EVENT, this)); 626 } catch (InvalidConfigurationException iex) { 627 throw new IllegalStateException (iex.getMessage()); 630 } 631 } 632 633 public GPPopulation getGPPopulation() { 634 return m_population; 635 } 636 637 643 public double getTotalFitness() { 644 return m_totalFitness; 645 } 646 647 653 public void run() { 654 try { 655 while (!Thread.currentThread().interrupted()) { 656 evolve(); 657 calcFitness(); 658 Thread.sleep(10); 661 } 662 } catch (Exception ex) { 663 ex.printStackTrace(); 664 System.exit(1); 665 } 666 } 667 668 678 public synchronized IGPProgram getFittestProgram() { 679 double fittest; 680 if (m_allTimeBest != null) { 681 fittest = m_allTimeBest.getFitnessValue(); 682 } 683 else { 684 fittest = FitnessFunction.NO_FITNESS_VALUE; 685 } 686 IGPProgram fittestPop = getGPPopulation().determineFittestProgram(); 687 if (fittestPop == null) { 688 return m_allTimeBest; 689 } 690 if (getGPConfiguration().getGPFitnessEvaluator().isFitter(fittest, 691 fittestPop.getFitnessValue())) { 692 return m_allTimeBest; 693 } 694 else { 695 return fittestPop; 697 } 698 } 699 710 public synchronized IGPProgram getFittestProgramComputed() { 711 return getGPPopulation().determineFittestProgramComputed(); 712 } 713 714 protected void setGPPopulation(GPPopulation a_pop) { 715 m_population = a_pop; 716 } 717 718 725 public void setGPConfiguration(GPConfiguration a_configuration) { 726 m_configuration = a_configuration; 727 } 728 729 738 public boolean equals(Object a_other) { 739 try { 740 return compareTo(a_other) == 0; 741 } catch (ClassCastException cex) { 742 return false; 743 } 744 } 745 746 762 public int compareTo(Object a_other) { 763 try { 764 if (a_other == null) { 767 return 1; 768 } 769 GPGenotype otherGenotype = (GPGenotype) a_other; 770 int size1 = getGPPopulation().size(); 774 int size2 = otherGenotype.getGPPopulation().size(); 775 if (size1 != size2) { 776 if (size1 > size2) { 777 return 1; 778 } 779 else { 780 return -1; 781 } 782 } 783 Arrays.sort(getGPPopulation().getGPPrograms()); 791 Arrays.sort(otherGenotype.getGPPopulation().getGPPrograms()); 792 for (int i = 0; i < getGPPopulation().size(); i++) { 793 int result = (getGPPopulation().getGPProgram(i).compareTo( 794 otherGenotype.getGPPopulation().getGPProgram(i))); 795 if (result != 0) { 796 return result; 797 } 798 } 799 return 0; 800 } catch (ClassCastException e) { 801 return -1; 802 } 803 } 804 805 823 public int hashCode() { 824 int i, size = getGPPopulation().size(); 825 IGPProgram prog; 826 int twopower = 1; 827 int localHashCode = -573; 831 for (i = 0; i < size; i++, twopower = 2 * twopower) { 832 prog = getGPPopulation().getGPProgram(i); 833 localHashCode = 31 * localHashCode + prog.hashCode(); 834 } 835 return localHashCode; 836 } 837 838 844 public void setVerboseOutput(boolean a_verbose) { 845 m_verbose = a_verbose; 846 } 847 848 private IGPProgram cloneProgram(IGPProgram a_original) { 849 IGPProgram validProgram = getGPConfiguration(). 850 getPrototypeProgram(); 851 ICloneHandler cloner = getGPConfiguration().getJGAPFactory(). 852 getCloneHandlerFor(validProgram, null); 853 if (cloner != null) { 854 try { 855 IGPProgram program = (IGPProgram) cloner.perform( 856 validProgram, null, null); 857 return program; 858 } catch (Exception ex) { 859 return null; 860 } 861 } 862 return null; 863 } 864 865 872 public void putVariable(Variable a_var) { 873 m_variables.put(a_var.getName(), a_var); 874 } 875 876 883 public Variable getVariable(String a_varName) { 884 return (Variable) m_variables.get(a_varName); 885 } 886 887 896 public void addFittestProgram(final IGPProgram a_toAdd) { 897 if (a_toAdd != null) { 898 m_fittestToAdd = a_toAdd; 899 } 900 } 901 } 902 | Popular Tags |