gpgenotype.java

来自「jgap3.2 遗传算法工具包,嘿嘿,笨鸟先飞哦」· Java 代码 · 共 902 行 · 第 1/3 页

JAVA
902
字号
        || a_argTypes.length != a_types.length) {
      throw new IllegalArgumentException("a_argTypes must have same length"
          + " as a_types, a_minDepths, a_maxDepths and a_fullModeAllowed");
    }
    System.gc();
    if (a_verboseOutput) {
      System.out.println("Creating initial population");
      System.out.println("Memory consumed before creating population: "
                         + SystemKit.getTotalMemoryMB() + "MB");
    }
    GPPopulation pop = new GPPopulation(a_conf, a_conf.getPopulationSize());
    // Create initial population.
    // --------------------------
    pop.create(a_types, a_argTypes, a_nodeSets, a_minDepths, a_maxDepths,
               a_maxNodes, a_fullModeAllowed);
    System.gc();
    if (a_verboseOutput) {
      System.out.println("Memory used after creating population: "
                         + SystemKit.getTotalMemoryMB() + "MB");
    }
    GPGenotype gp = new GPGenotype(a_conf, pop, a_types, a_argTypes, a_nodeSets,
                                   a_minDepths, a_maxDepths, a_maxNodes);
    gp.m_fullModeAllowed = a_fullModeAllowed;
    return gp;
  }

  public GPConfiguration getGPConfiguration() {
    return m_configuration;
  }

  /**
   * @return the static configuration to use with the Genetic Programming
   *
   * @author Klaus Meffert
   * @since 3.2
   */
  public static GPConfiguration getStaticGPConfiguration() {
    return m_staticConfiguration;
  }

  /**
   * Sets the static configuration to use with the Genetic Programming.
   *
   * @param a_configuration the static configuration to use
   *
   * @author Klaus Meffert
   * @since 3.2
   */
  public static void setStaticGPConfiguration(GPConfiguration a_configuration) {
    m_staticConfiguration = a_configuration;
  }

  static class GPFitnessComparator
      implements Comparator {
    public int compare(Object o1, Object o2) {
      if (! (o1 instanceof IGPProgram) ||
          ! (o2 instanceof IGPProgram))
        throw new ClassCastException(
            "FitnessComparator must operate on IGPProgram instances");
      double f1 = ( (IGPProgram) o1).getFitnessValue();
      double f2 = ( (IGPProgram) o2).getFitnessValue();
      if (f1 > f2) {
        return 1;
      }
      else if (Math.abs(f1 - f2) < 0.000001) {
        return 0;
      }
      else {
        return -1;
      }
    }
  }
  /**
   * Evolves the population n times.
   *
   * @param a_evolutions number of evolution
   *
   * @author Klaus Meffert
   * @since 3.0
   */
  public void evolve(int a_evolutions) {
    getGPPopulation().sort(new GPFitnessComparator());
    // Here, we could do threading.
    for (int i = 0; i < a_evolutions; i++) {
      calcFitness();
      if (m_bestFitness < 0.000001) {
        // Optimal solution found, quit.
        // -----------------------------
        return;
      }
      if (m_verbose) {
        if (i % 25 == 0) {
          System.out.println("Evolving generation "
                             + i
                             + ", memory free: "
                             + SystemKit.getFreeMemoryMB()
                             + " MB");
        }
      }
      evolve();
    }
    calcFitness();
  }

  /**
   * Calculates the fitness value of all programs, of the best solution as
   * well as the total fitness (sum of all fitness values).
   *
   * @author Klaus Meffert
   * @since 3.0
   */
  public void calcFitness() {
    double totalFitness = 0.0d;
    GPPopulation pop = getGPPopulation();
    IGPProgram best = null;
    IGPFitnessEvaluator evaluator = getGPConfiguration().getGPFitnessEvaluator();
    m_bestFitness = FitnessFunction.NO_FITNESS_VALUE;
    for (int i = 0; i < pop.size() && pop.getGPProgram(i) != null; i++) {
      IGPProgram program = pop.getGPProgram(i);
      double fitness = program.getFitnessValue();
      if (best == null || evaluator.isFitter(fitness, m_bestFitness)) {
        best = program;
        m_bestFitness = fitness;
      }
      totalFitness += fitness;
    }
    m_totalFitness = totalFitness;
//    best = pop.determineFittestProgram();
//    m_bestFitness = best.getFitnessValue();
    /**@todo do something similar here as with Genotype.preserveFittestChromosome*/
    if (m_allTimeBest == null
        || evaluator.isFitter(m_bestFitness, m_allTimeBestFitness)) {
      pop.setChanged(true);
      try {
        ICloneHandler cloner = getGPConfiguration().getJGAPFactory().
            getCloneHandlerFor(best, null);
        if (cloner == null) {
          m_allTimeBest = best;
          if (!m_cloneWarningGPProgramShown) {
            System.out.println("Warning: cannot clone instance of " +
                               best.getClass());
            m_cloneWarningGPProgramShown = true;
          }
        }
        else {
          m_allTimeBest = (IGPProgram) cloner.perform(best, null, null);
        }
      } catch (Exception ex) {
        m_allTimeBest = best;
        ex.printStackTrace();
      }
      m_allTimeBestFitness = m_bestFitness;
      // Fire an event to indicate a new best solution.
      // ----------------------------------------------
      getGPConfiguration().getEventManager().fireGeneticEvent(
          new GeneticEvent(GeneticEvent.GPGENOTYPE_NEW_BEST_SOLUTION, this));
      if (m_verbose) {
        // Output the new best solution found.
        // -----------------------------------
        outputSolution(m_allTimeBest);
      }
    }
  }

  /**
   * @return the all-time best solution found
   *
   * @author Klaus Meffert
   * @since 3.0
   */
  public IGPProgram getAllTimeBest() {
    return m_allTimeBest;
  }

  /**
   * Outputs the best solution currently found.
   * @param a_best the fittest ProgramChromosome
   *
   * @author Klaus Meffert
   * @since 3.0
   */
  public void outputSolution(IGPProgram a_best) {
    System.out.println(" Best solution fitness: " + a_best.getFitnessValue());
    System.out.println(" Best solution: " + a_best.toStringNorm(0));
    String depths = "";
    int size = a_best.size();
    for (int i = 0; i < size; i++) {
      if (i > 0) {
        depths += " / ";
      }
      depths += a_best.getChromosome(i).getDepth(0);
    }
    if (size == 1) {
      System.out.println(" Depth of chromosome: " + depths);
    }
    else {
      System.out.println(" Depths of chromosomes: " + depths);
    }
    System.out.println(" --------");
  }

  /**
   * Evolve the population by one generation. Probabilistically reproduces
   * and crosses individuals into a new population which then overwrites the
   * original population.
   *
   * @author Klaus Meffert
   * @since 3.0
   */
  public void evolve() {
    try {
      int popSize = getGPConfiguration().getPopulationSize();
      GPPopulation oldPop = getGPPopulation();
      GPPopulation newPopulation = new GPPopulation(oldPop, false);
      if (m_fittestToAdd != null) {
        newPopulation.addFittestProgram(m_fittestToAdd);
        m_fittestToAdd = null;
      }
      float val;
      RandomGenerator random = getGPConfiguration().getRandomGenerator();
      GPConfiguration conf = getGPConfiguration();
      // Determine how many new individuals will be added to the new generation.
      // -----------------------------------------------------------------------
      int popSize1 = (int) Math.round(popSize * (1 - conf.getNewChromsPercent()));
      for (int i = 0; i < popSize1; i++) {
        // Clear the stack for each GP program (=ProgramChromosome).
        // ---------------------------------------------------------
        getGPConfiguration().clearStack();
        val = random.nextFloat();
        // Note that if we only have one slot left to fill, we don't do
        // crossover, but fall through to reproduction.
        // ------------------------------------------------------------
        if (i < popSize - 1 && val < conf.getCrossoverProb()) {
          // Do crossover.
          // -------------
          IGPProgram i1 = conf.getSelectionMethod().select(this);
//          newPopulation.checkIfFittest(i1);
          IGPProgram i2 = conf.getSelectionMethod().select(this);
//          newPopulation.checkIfFittest(i2);
          int tries = 0;
          do {
            try {
              IGPProgram[] newIndividuals = conf.getCrossMethod().operate(i1,
                  i2);
              newPopulation.setGPProgram(i, newIndividuals[0]);
              newPopulation.setGPProgram(i + 1, newIndividuals[1]);
              i++;
              break;
            } catch (IllegalStateException iex) {
              tries++;
              if (tries >= getGPConfiguration().getProgramCreationMaxtries()) {
                if (!getGPConfiguration().isMaxNodeWarningPrinted()) {
                  System.err.println(
                      "Warning: Maximum number of nodes allowed may be too small");
                  getGPConfiguration().flagMaxNodeWarningPrinted();
                  // Try cloning a previously generated valid program.
                  // -------------------------------------------------
                  IGPProgram program = cloneProgram(getGPConfiguration().
                      getPrototypeProgram());
                  if (program != null) {
                    newPopulation.setGPProgram(i++, program);
                    program = cloneProgram(getGPConfiguration().
                        getPrototypeProgram());
                    newPopulation.setGPProgram(i, program);
                    break;
                  }
                  else {
                    throw new IllegalStateException(iex.getMessage());
                  }
                }
              }
            }
          } while (true);
        }
        else if (val < conf.getCrossoverProb() + conf.getReproductionProb()) {
          // Reproduction only.
          // ------------------
          newPopulation.setGPProgram(i, conf.getSelectionMethod().select(this));
        }
      }
      // Add new chromosomes randomly.
      // -----------------------------
      for (int i = popSize1; i < popSize; i++) {
        // Determine depth randomly and between minInitDepth and maxInitDepth.
        // -------------------------------------------------------------------
        int depth = conf.getMinInitDepth()
            + random.nextInt(conf.getMaxInitDepth() - conf.getMinInitDepth()
                             + 1);
        int tries = 0;
        do {
          try {
            IGPProgram program = newPopulation.create(m_types, m_argTypes,
                m_nodeSets, m_minDepths, m_maxDepths, depth, (i % 2) == 0,
                m_maxNodes, m_fullModeAllowed);
            newPopulation.setGPProgram(i, program);
            break;
          } catch (IllegalStateException iex) {
            tries++;
            if (tries > getGPConfiguration().getProgramCreationMaxtries()) {
              // Try cloning a previously generated valid program.
              // -------------------------------------------------

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?