/**
   * Determine the fitness of the given Chromosome instance. The higher the return value, the more
   * fit the instance. This method should always return the same fitness value for two equivalent
   * Chromosome instances.
   *
   * @param a_subject the Chromosome instance to evaluate
   * @return positive double reflecting the fitness rating of the given Chromosome
   * @since 2.0 (until 1.1: return type int)
   * @author Neil Rotstan, Klaus Meffert, John Serri
   */
  public double evaluate(IChromosome a_subject) {
    // Take care of the fitness evaluator. It could either be weighting higher
    // fitness values higher (e.g.DefaultFitnessEvaluator). Or it could weight
    // lower fitness values higher, because the fitness value is seen as a
    // defect rate (e.g. DeltaFitnessEvaluator)
    boolean defaultComparation = a_subject.getConfiguration().getFitnessEvaluator().isFitter(2, 1);

    // The fitness value measures both how close the value is to the
    // target amount supplied by the user and the total number of coins
    // represented by the solution. We do this in two steps: first,
    // we consider only the represented amount of change vs. the target
    // amount of change and return higher fitness values for amounts
    // closer to the target, and lower fitness values for amounts further
    // away from the target. Then we go to step 2, which returns a higher
    // fitness value for solutions representing fewer total coins, and
    // lower fitness values for solutions representing more total coins.
    // ------------------------------------------------------------------
    int changeAmount = amountOfChange(a_subject);
    int totalCoins = getTotalNumberOfCoins(a_subject);
    int changeDifference = Math.abs(m_targetAmount - changeAmount);
    double fitness;
    if (defaultComparation) {
      fitness = 0.0d;
    } else {
      fitness = MAX_BOUND / 2;
    }
    // Step 1: Determine distance of amount represented by solution from
    // the target amount. If the change difference is greater than zero we
    // will divide one by the difference in change between the
    // solution amount and the target amount. That will give the desired
    // effect of returning higher values for amounts closer to the target
    // amount and lower values for amounts further away from the target
    // amount.
    // In the case where the change difference is zero it means that we have
    // the correct amount and we assign a higher fitness value.
    // ---------------------------------------------------------------------
    if (defaultComparation) {
      fitness += changeDifferenceBonus(MAX_BOUND / 2, changeDifference);
    } else {
      fitness -= changeDifferenceBonus(MAX_BOUND / 2, changeDifference);
    }
    // Step 2: We divide the fitness value by a penalty based on the number of
    // coins. The higher the number of coins the higher the penalty and the
    // smaller the fitness value.
    // And inversely the smaller number of coins in the solution the higher
    // the resulting fitness value.
    // -----------------------------------------------------------------------
    if (defaultComparation) {
      fitness -= computeCoinNumberPenalty(MAX_BOUND / 2, totalCoins);
    } else {
      fitness += computeCoinNumberPenalty(MAX_BOUND / 2, totalCoins);
    }
    // Make sure fitness value is always positive.
    // -------------------------------------------
    return Math.max(1.0d, fitness);
  }
예제 #2
0
 private double computeFitness(IGPProgram a_program, Variable vx) {
   double error = 0.0f;
   Object[] noargs = new Object[0];
   // Initialize local stores.
   // ------------------------
   a_program.getGPConfiguration().clearStack();
   a_program.getGPConfiguration().clearMemory();
   // Compute fitness for each program.
   // ---------------------------------
   for (int i = 2; i < 15; i++) {
     for (int j = 0; j < a_program.size(); j++) {
       vx.set(new Integer(i));
       try {
         try {
           // Only evaluate after whole GP program was run.
           // ---------------------------------------------
           if (j == a_program.size() - 1) {
             double result = a_program.execute_int(j, noargs);
             error += Math.abs(result - fib_iter(i));
           } else {
             a_program.execute_void(j, noargs);
           }
         } catch (IllegalStateException iex) {
           error = Double.MAX_VALUE / 2;
           break;
         }
       } catch (ArithmeticException ex) {
         System.out.println("Arithmetic Exception with x = " + i);
         System.out.println(a_program.getChromosome(j));
         throw ex;
       }
     }
   }
   return error;
 }
예제 #3
0
 protected void setRandomValue(double a_value) {
   RandomGenerator randomGen = getGPConfiguration().getRandomGenerator();
   m_value_double = randomGen.nextDouble() * (m_upperBounds - m_lowerBounds) + m_lowerBounds;
   if (m_wholeNumbers) {
     m_value_double = Math.round(m_value_double);
   }
 }
예제 #4
0
 public void setValue(float a_value) {
   if (m_wholeNumbers) {
     m_value_float = Math.round(a_value);
   } else {
     m_value_float = a_value;
   }
 }
예제 #5
0
 public void setValue(double a_value) {
   if (m_wholeNumbers) {
     m_value_double = Math.round(a_value);
   } else {
     m_value_double = a_value;
   }
 }
  /**
   * Determine the fitness of the given Chromosome instance. The higher the return value, the more
   * fit the instance. This method should always return the same fitness value for two equivalent
   * Chromosome instances.
   *
   * @param a_subject the Chromosome instance to evaluate
   * @return positive double reflecting the fitness rating of the given Chromosome
   * @since 2.0 (until 1.1: return type int)
   * @author Neil Rotstan, Klaus Meffert, John Serri
   */
  public double evaluate(IChromosome a_subject) {
    int i = 0, j, k;

    for (j = 0; j < EvolvingSubsumptionForRobocode.numberOfEvents; j++) {
      eventPriority[j] = ((Integer) a_subject.getGene(i++).getAllele()).intValue();
    }
    for (j = 0; j < EvolvingSubsumptionForRobocode.numberOfBehaviours; j++) {
      behaviourOverwrite[j] = ((Integer) a_subject.getGene(i++).getAllele()).intValue() > 50;
    }
    for (j = 0; j < EvolvingSubsumptionForRobocode.numberOfBehaviours; j++) {
      for (k = 0; k < EvolvingSubsumptionForRobocode.behaviourSize; k++) {
        behaviourActions[j][k] = ((Integer) a_subject.getGene(i++).getAllele()).intValue();
      }
    }

    double tempFitness;
    double fitness = 0;
    for (j = 0; j < otherRobots.length; j++) {
      RobotSpecification[] tempRobots = new RobotSpecification[2];
      tempRobots[0] = evolvable;
      tempRobots[1] = otherRobots[j];
      battleSpecs = new BattleSpecification(1, new BattlefieldSpecification(800, 600), tempRobots);
      tempFitness = 0;
      System.out.println("Testing against " + otherRobots[j].getName() + "...");
      for (i = 0; i < EvolvingSubsumptionForRobocode.numberOfBattles; i++) {
        engine.runBattle(battleSpecs, true);
        tempFitness += battleObserver.getScoreRobot() / 500;
      }
      tempFitness /= EvolvingSubsumptionForRobocode.numberOfBattles;
      fitness += tempFitness;
    }
    fitness /= otherRobots.length;

    return Math.min(1.0d, fitness);
  }
예제 #7
0
 protected void setRandomValue(float a_value) {
   RandomGenerator randomGen = getGPConfiguration().getRandomGenerator();
   m_value_float =
       (float) (randomGen.nextFloat() * (m_upperBounds - m_lowerBounds) + m_lowerBounds);
   if (m_wholeNumbers) {
     m_value_float = Math.round(m_value_float);
   }
 }
 /**
  * Calculates the penalty to apply to the fitness value based on the ammount of coins in the
  * solution
  *
  * @param a_maxFitness maximum fitness value allowed
  * @param a_coins number of coins in the solution
  * @return penalty for the fitness value base on the number of coins
  * @author John Serri
  * @since 2.2
  */
 protected double computeCoinNumberPenalty(double a_maxFitness, int a_coins) {
   if (a_coins == 1) {
     // we know the solution cannot have less than one coin
     return 0;
   } else {
     // The more coins the more penalty, but not more than the maximum fitness
     // value possible. Let's avoid linear behavior and use
     // exponential penalty calculation instead
     return (Math.min(a_maxFitness, a_coins * a_coins));
   }
 }
예제 #9
0
 /**
  * Find and print the solution, return the solution error.
  *
  * @param a_conf the configuration to use
  * @return absolute difference between the required and computed change
  */
 protected int solve(
     Configuration a_conf,
     int a_targetChangeAmount,
     SupergeneChangeFitnessFunction a_fitnessFunction,
     Gene[] a_sampleGenes)
     throws InvalidConfigurationException {
   IChromosome sampleChromosome = new Chromosome(a_conf, a_sampleGenes);
   a_conf.setSampleChromosome(sampleChromosome);
   // Finally, we need to tell the Configuration object how many
   // Chromosomes we want in our population. The more Chromosomes,
   // the larger number of potential solutions (which is good for
   // finding the answer), but the longer it will take to evolve
   // the population (which could be seen as bad). We'll just set
   // the population size to 500 here.
   // ------------------------------------------------------------
   a_conf.setPopulationSize(POPULATION_SIZE);
   // Create random initial population of Chromosomes.
   // ------------------------------------------------
   Genotype population = Genotype.randomInitialGenotype(a_conf);
   int s;
   Evolution:
   // Evolve the population, break if the the change solution is found.
   // -----------------------------------------------------------------
   for (int i = 0; i < MAX_ALLOWED_EVOLUTIONS; i++) {
     population.evolve();
     s =
         Math.abs(
             a_fitnessFunction.amountOfChange(population.getFittestChromosome())
                 - a_targetChangeAmount);
     if (s == 0) {
       break Evolution;
     }
   }
   // Display the best solution we found.
   // -----------------------------------
   IChromosome bestSolutionSoFar = report(a_fitnessFunction, population);
   return Math.abs(a_fitnessFunction.amountOfChange(bestSolutionSoFar) - a_targetChangeAmount);
 }
예제 #10
0
  /**
   * Evolves the population of chromosomes within a genotype. This will execute all of the genetic
   * operators added to the present active configuration and then invoke the natural selector to
   * choose which chromosomes will be included in the next generation population.
   *
   * @param a_pop the population to evolve
   * @param a_conf the configuration to use for evolution
   * @return evolved population
   * @author Klaus Meffert
   * @since 3.2
   */
  public Population evolve(Population a_pop, Configuration a_conf) {
    Population pop = a_pop;
    int originalPopSize = a_conf.getPopulationSize();
    boolean monitorActive = a_conf.getMonitor() != null;
    IChromosome fittest = null;
    // If first generation: Set age to one to allow genetic operations,
    // see CrossoverOperator for an illustration.
    // ----------------------------------------------------------------
    if (a_conf.getGenerationNr() == 0) {
      int size = pop.size();
      for (int i = 0; i < size; i++) {
        IChromosome chrom = pop.getChromosome(i);
        chrom.increaseAge();
      }
    } else {
      // Select fittest chromosome in case it should be preserved and we are
      // not in the very first generation.
      // -------------------------------------------------------------------
      if (a_conf.isPreserveFittestIndividual()) {
        /** @todo utilize jobs. In pop do also utilize jobs, especially for fitness computation */
        fittest = pop.determineFittestChromosome(0, pop.size() - 1);
      }
    }
    if (a_conf.getGenerationNr() > 0) {
      // Adjust population size to configured size (if wanted).
      // Theoretically, this should be done at the end of this method.
      // But for optimization issues it is not. If it is the last call to
      // evolve() then the resulting population possibly contains more
      // chromosomes than the wanted number. But this is no bad thing as
      // more alternatives mean better chances having a fit candidate.
      // If it is not the last call to evolve() then the next call will
      // ensure the correct population size by calling keepPopSizeConstant.
      // ------------------------------------------------------------------
      keepPopSizeConstant(pop, a_conf);
    }
    // Ensure fitness value of all chromosomes is udpated.
    // ---------------------------------------------------
    if (monitorActive) {
      // Monitor that fitness value of chromosomes is being updated.
      // -----------------------------------------------------------
      a_conf
          .getMonitor()
          .event(
              IEvolutionMonitor.MONITOR_EVENT_BEFORE_UPDATE_CHROMOSOMES1,
              a_conf.getGenerationNr(),
              new Object[] {pop});
    }
    updateChromosomes(pop, a_conf);
    if (monitorActive) {
      // Monitor that fitness value of chromosomes is being updated.
      // -----------------------------------------------------------
      a_conf
          .getMonitor()
          .event(
              IEvolutionMonitor.MONITOR_EVENT_AFTER_UPDATE_CHROMOSOMES1,
              a_conf.getGenerationNr(),
              new Object[] {pop});
    }
    // Apply certain NaturalSelectors before GeneticOperators will be executed.
    // ------------------------------------------------------------------------
    pop = applyNaturalSelectors(a_conf, pop, true);
    // Execute all of the Genetic Operators.
    // -------------------------------------
    applyGeneticOperators(a_conf, pop);
    // Reset fitness value of genetically operated chromosomes.
    // Normally, this should not be necessary as the Chromosome class
    // initializes each newly created chromosome with
    // FitnessFunction.NO_FITNESS_VALUE. But who knows which Chromosome
    // implementation is used...
    // ----------------------------------------------------------------
    int currentPopSize = pop.size();
    for (int i = originalPopSize; i < currentPopSize; i++) {
      IChromosome chrom = pop.getChromosome(i);
      chrom.setFitnessValueDirectly(FitnessFunction.NO_FITNESS_VALUE);
      // Mark chromosome as new-born.
      // ----------------------------
      chrom.resetAge();
      // Mark chromosome as being operated on.
      // -------------------------------------
      chrom.increaseOperatedOn();
    }
    // Increase age of all chromosomes which are not modified by genetic
    // operations.
    // -----------------------------------------------------------------
    int size = Math.min(originalPopSize, currentPopSize);
    for (int i = 0; i < size; i++) {
      IChromosome chrom = pop.getChromosome(i);
      chrom.increaseAge();
      // Mark chromosome as not being operated on.
      // -----------------------------------------
      chrom.resetOperatedOn();
    }
    // If a bulk fitness function has been provided, call it.
    // ------------------------------------------------------
    BulkFitnessFunction bulkFunction = a_conf.getBulkFitnessFunction();
    if (bulkFunction != null) {
      if (monitorActive) {
        // Monitor that bulk fitness will be called for evaluation.
        // --------------------------------------------------------
        a_conf
            .getMonitor()
            .event(
                IEvolutionMonitor.MONITOR_EVENT_BEFORE_BULK_EVAL,
                a_conf.getGenerationNr(),
                new Object[] {bulkFunction, pop});
      }
      /** @todo utilize jobs: bulk fitness function is not so important for a prototype! */
      bulkFunction.evaluate(pop);
      if (monitorActive) {
        // Monitor that bulk fitness has been called for evaluation.
        // ---------------------------------------------------------
        a_conf
            .getMonitor()
            .event(
                IEvolutionMonitor.MONITOR_EVENT_AFTER_BULK_EVAL,
                a_conf.getGenerationNr(),
                new Object[] {bulkFunction, pop});
      }
    }
    // Ensure fitness value of all chromosomes is udpated.
    // ---------------------------------------------------
    if (monitorActive) {
      // Monitor that fitness value of chromosomes is being updated.
      // -----------------------------------------------------------
      a_conf
          .getMonitor()
          .event(
              IEvolutionMonitor.MONITOR_EVENT_BEFORE_UPDATE_CHROMOSOMES2,
              a_conf.getGenerationNr(),
              new Object[] {pop});
    }
    updateChromosomes(pop, a_conf);
    if (monitorActive) {
      // Monitor that fitness value of chromosomes is being updated.
      // -----------------------------------------------------------
      a_conf
          .getMonitor()
          .event(
              IEvolutionMonitor.MONITOR_EVENT_AFTER_UPDATE_CHROMOSOMES2,
              a_conf.getGenerationNr(),
              new Object[] {pop});
    }
    // Apply certain NaturalSelectors after GeneticOperators have been applied.
    // ------------------------------------------------------------------------
    pop = applyNaturalSelectors(a_conf, pop, false);
    // Fill up population randomly if size dropped below specified percentage
    // of original size.
    // ----------------------------------------------------------------------
    if (a_conf.getMinimumPopSizePercent() > 0) {
      int sizeWanted = a_conf.getPopulationSize();
      int popSize;
      int minSize = (int) Math.round(sizeWanted * (double) a_conf.getMinimumPopSizePercent() / 100);
      popSize = pop.size();
      if (popSize < minSize) {
        IChromosome newChrom;
        IChromosome sampleChrom = a_conf.getSampleChromosome();
        Class sampleChromClass = sampleChrom.getClass();
        IInitializer chromIniter =
            a_conf.getJGAPFactory().getInitializerFor(sampleChrom, sampleChromClass);
        while (pop.size() < minSize) {
          try {
            /**
             * @todo utilize jobs as initialization may be time-consuming as invalid combinations
             *     may have to be filtered out
             */
            newChrom = (IChromosome) chromIniter.perform(sampleChrom, sampleChromClass, null);
            if (monitorActive) {
              // Monitor that fitness value of chromosomes is being updated.
              // -----------------------------------------------------------
              a_conf
                  .getMonitor()
                  .event(
                      IEvolutionMonitor.MONITOR_EVENT_BEFORE_ADD_CHROMOSOME,
                      a_conf.getGenerationNr(),
                      new Object[] {pop, newChrom});
            }
            pop.addChromosome(newChrom);
          } catch (Exception ex) {
            throw new RuntimeException(ex);
          }
        }
      }
    }
    IChromosome newFittest = reAddFittest(pop, fittest);
    if (monitorActive && newFittest != null) {
      // Monitor that fitness value of chromosomes is being updated.
      // -----------------------------------------------------------
      a_conf
          .getMonitor()
          .event(
              IEvolutionMonitor.MONITOR_EVENT_READD_FITTEST,
              a_conf.getGenerationNr(),
              new Object[] {pop, fittest});
    }

    // Increase number of generations.
    // -------------------------------
    a_conf.incrementGenerationNr();
    // Fire an event to indicate we've performed an evolution.
    // -------------------------------------------------------
    m_lastPop = pop;
    m_lastConf = a_conf;
    a_conf
        .getEventManager()
        .fireGeneticEvent(new GeneticEvent(GeneticEvent.GENOTYPE_EVOLVED_EVENT, this));
    return pop;
  }
  public void operate(final Population a_population, final List a_candidateChromosomes) {
    // Work out the number of crossovers that should be performed.
    // -----------------------------------------------------------
    int m_crossoverRate = getCrossOverRate();
    double m_crossoverRatePercent = getCrossOverRatePercent();
    int size = Math.min(getConfiguration().getPopulationSize(), a_population.size());
    int numCrossovers = 0;

    if (m_crossoverRate >= 0) {
      numCrossovers = size / m_crossoverRate;
    } else if (m_crossoverRateCalc != null) {
      numCrossovers = size / 6;
    } else {
      numCrossovers = (int) (size * m_crossoverRatePercent);
    }
    RandomGenerator generator = getConfiguration().getRandomGenerator();
    IGeneticOperatorConstraint constraint =
        getConfiguration().getJGAPFactory().getGeneticOperatorConstraint();
    // For each crossover, grab two random chromosomes, pick a random
    // locus (gene location), and then swap that gene and all genes
    // to the "right" (those with greater loci) of that gene between
    // the two chromosomes.
    // --------------------------------------------------------------
    int index1, index2;

    crossoverValues = new int[size];

    for (int i = 0; i < size; i++) {
      crossoverValues[i] = 0;
    }

    List<Integer> chromeSel = new ArrayList<Integer>();
    for (int i = 0; i < size; i++) {
      if (m_crossoverRateCalc != null) {
        CrossoverRateCalculator ccalc = (CrossoverRateCalculator) m_crossoverRateCalc;
        ccalc.setCurrentFitness(a_population.getChromosome(i).getFitnessValue());

        int numbers = ccalc.calculateCurrentRate();
        crossoverValues[i] = numbers;
        while (numbers > 0) {
          chromeSel.add(i);
          numbers--;
        }
      }
    }
    int justtocheck = chromeSel.size();

    if (m_crossoverRateCalc != null) {
      if (justtocheck == 0) {
        System.out.println("Exception Caught.. Crossover.. chromesel array is null!!");
        for (int fix = 0; fix <= size - 2; fix++) {
          chromeSel.add(fix);
        }
      }
    }

    //
    for (int i = 0; i < numCrossovers; i++) {
      IChromosome chrom1;
      IChromosome chrom2;

      if (m_crossoverRateCalc != null) {
        index1 = generator.nextInt(chromeSel.size());
        index2 = generator.nextInt(chromeSel.size());
        chrom1 = a_population.getChromosome(chromeSel.get(index1));
        chrom2 = a_population.getChromosome(chromeSel.get(index2));
      } else {
        index1 = generator.nextInt(size);
        index2 = generator.nextInt(size);
        chrom1 = a_population.getChromosome(index1);
        chrom2 = a_population.getChromosome(index2);
      }
      // Verify that crossover is allowed.
      // ---------------------------------
      if (!isXoverNewAge() && chrom1.getAge() < 1 && chrom2.getAge() < 1) {
        // Crossing over two newly created chromosomes is not seen as helpful
        // here.
        // ------------------------------------------------------------------
        continue;
      }
      if (constraint != null) {
        List v = new Vector();
        v.add(chrom1);
        v.add(chrom2);
        if (!constraint.isValid(a_population, v, this)) {
          // Constraint forbids crossing over.
          // ---------------------------------
          continue;
        }
      }
      // Clone the chromosomes.
      // ----------------------
      IChromosome firstMate = (IChromosome) ((ICloneable) chrom1).clone();
      IChromosome secondMate = (IChromosome) ((ICloneable) chrom2).clone();

      // Cross over the chromosomes.
      // ---------------------------
      doCrossover(firstMate, secondMate, a_candidateChromosomes, generator);
    }
  }
 /**
  * Calculate Cumulative Cauchy distribution function.
  *
  * @return the probability that a stochastic variable x is less than X
  * @author Klaus Meffert
  * @since 1.1
  */
 public double nextCauchy() {
   return 0.5 + Math.atan((m_rn.nextDouble() - m_location) / m_scale) / Math.PI;
 }
 public int nextInt(final int a_ceiling) {
   return Math.min(a_ceiling - 1, (int) Math.round(nextCauchy() * a_ceiling));
 }
 public int nextInt() {
   return Math.min(Integer.MAX_VALUE - 1, (int) Math.round(nextCauchy() * Integer.MAX_VALUE));
 }
예제 #15
0
 public CommandGene applyMutation(int index, double a_percentage)
     throws InvalidConfigurationException {
   // If percentage is very high: do mutation not relying on
   // current value but on a random value.
   // ------------------------------------------------------
   if (a_percentage > 0.85d) {
     setRandomValue();
   } else {
     Class retType = getReturnType();
     if (retType == CommandGene.FloatClass) {
       float newValuef;
       float rangef = ((float) m_upperBounds - (float) m_lowerBounds) * (float) a_percentage;
       if (m_value_float >= (m_upperBounds - m_lowerBounds) / 2) {
         newValuef =
             m_value_float - getGPConfiguration().getRandomGenerator().nextFloat() * rangef;
       } else {
         newValuef =
             m_value_float + getGPConfiguration().getRandomGenerator().nextFloat() * rangef;
       }
       // Ensure value is within bounds.
       // ------------------------------
       if (m_lowerBounds - newValuef > DELTA || newValuef - m_upperBounds > DELTA) {
         setRandomValue(m_value_float);
       } else {
         setValue(newValuef);
       }
     } else if (retType == CommandGene.DoubleClass) {
       double newValueD;
       double rangeD = (m_upperBounds - m_lowerBounds) * a_percentage;
       if (m_value_double >= (m_upperBounds - m_lowerBounds) / 2) {
         newValueD =
             m_value_double - getGPConfiguration().getRandomGenerator().nextFloat() * rangeD;
       } else {
         newValueD =
             m_value_double + getGPConfiguration().getRandomGenerator().nextFloat() * rangeD;
       }
       // Ensure value is within bounds.
       // ------------------------------
       if (m_lowerBounds - newValueD > DELTA || newValueD - m_upperBounds > DELTA) {
         setRandomValue(m_value_float);
       } else {
         setValue(newValueD);
       }
     } else if (retType == CommandGene.IntegerClass) {
       int newValueI;
       double range = (m_upperBounds - m_lowerBounds) * a_percentage;
       if (m_value_int >= (m_upperBounds - m_lowerBounds) / 2) {
         newValueI =
             m_value_int
                 - (int) Math.round(getGPConfiguration().getRandomGenerator().nextInt() * range);
       } else {
         newValueI =
             m_value_int
                 + (int) Math.round(getGPConfiguration().getRandomGenerator().nextFloat() * range);
       }
       // Ensure value is within bounds.
       // ------------------------------
       if (newValueI < m_lowerBounds || newValueI > m_upperBounds) {
         setRandomValue(m_value_int);
       } else {
         setValue(newValueI);
       }
     } else if (retType == CommandGene.LongClass) {
       long newValueL;
       double range = (m_upperBounds - m_lowerBounds) * a_percentage;
       if (m_value_long >= (m_upperBounds - m_lowerBounds) / 2) {
         newValueL =
             m_value_long
                 - Math.round(getGPConfiguration().getRandomGenerator().nextInt() * range);
       } else {
         newValueL =
             m_value_long
                 + Math.round(getGPConfiguration().getRandomGenerator().nextFloat() * range);
       }
       // Ensure value is within bounds.
       // ------------------------------
       if (newValueL < m_lowerBounds || newValueL > m_upperBounds) {
         setRandomValue(m_value_long);
       } else {
         setValue(newValueL);
       }
     }
   }
   return this;
 }
 public long nextLong() {
   return Math.min(Long.MAX_VALUE - 1, Math.round(nextCauchy() * Long.MAX_VALUE));
 }
 public float nextFloat() {
   return Math.min(Float.MAX_VALUE - 1, (float) (nextCauchy() * Float.MAX_VALUE));
 }
  /**
   * Executes the genetic algorithm to determine the minimum number of items necessary to make up
   * the given target volume. The solution will then be written to the console.
   *
   * @param a_knapsackVolume the target volume for which this method is attempting to produce the
   *     optimal list of items
   * @throws Exception
   * @author Klaus Meffert
   * @since 2.3
   */
  public static void findItemsForVolume(double a_knapsackVolume) throws Exception {
    // Start with a DefaultConfiguration, which comes setup with the
    // most common settings.
    // -------------------------------------------------------------
    Configuration conf = new DefaultConfiguration();
    conf.setPreservFittestIndividual(true);
    // Set the fitness function we want to use. We construct it with
    // the target volume passed in to this method.
    // ---------------------------------------------------------
    FitnessFunction myFunc = new KnapsackFitnessFunction(a_knapsackVolume);
    conf.setFitnessFunction(myFunc);
    // Now we need to tell the Configuration object how we want our
    // Chromosomes to be setup. We do that by actually creating a
    // sample Chromosome and then setting it on the Configuration
    // object. As mentioned earlier, we want our Chromosomes to each
    // have as many genes as there are different items available. We want the
    // values (alleles) of those genes to be integers, which represent
    // how many items of that type we have. We therefore use the
    // IntegerGene class to represent each of the genes. That class
    // also lets us specify a lower and upper bound, which we set
    // to senseful values (i.e. maximum possible) for each item type.
    // --------------------------------------------------------------
    Gene[] sampleGenes = new Gene[itemVolumes.length];
    for (int i = 0; i < itemVolumes.length; i++) {
      sampleGenes[i] = new IntegerGene(conf, 0, (int) Math.ceil(a_knapsackVolume / itemVolumes[i]));
    }
    IChromosome sampleChromosome = new Chromosome(conf, sampleGenes);
    conf.setSampleChromosome(sampleChromosome);
    // Finally, we need to tell the Configuration object how many
    // Chromosomes we want in our population. The more Chromosomes,
    // the larger number of potential solutions (which is good for
    // finding the answer), but the longer it will take to evolve
    // the population (which could be seen as bad).
    // ------------------------------------------------------------
    conf.setPopulationSize(50);
    // Create random initial population of Chromosomes.
    // Here we try to read in a previous run via XMLManager.readFile(..)
    // for demonstration purpose!
    // -----------------------------------------------------------------
    Genotype population;
    try {
      Document doc = XMLManager.readFile(new File("knapsackJGAP.xml"));
      population = XMLManager.getGenotypeFromDocument(conf, doc);
    } catch (FileNotFoundException fex) {
      population = Genotype.randomInitialGenotype(conf);
    }
    population = Genotype.randomInitialGenotype(conf);
    // Evolve the population. Since we don't know what the best answer
    // is going to be, we just evolve the max number of times.
    // ---------------------------------------------------------------
    for (int i = 0; i < MAX_ALLOWED_EVOLUTIONS; i++) {
      population.evolve();
    }
    // Save progress to file. A new run of this example will then be able to
    // resume where it stopped before!
    // ---------------------------------------------------------------------

    // represent Genotype as tree with elements Chromomes and Genes
    // ------------------------------------------------------------
    DataTreeBuilder builder = DataTreeBuilder.getInstance();
    IDataCreators doc2 = builder.representGenotypeAsDocument(population);
    // create XML document from generated tree
    // ---------------------------------------
    XMLDocumentBuilder docbuilder = new XMLDocumentBuilder();
    Document xmlDoc = (Document) docbuilder.buildDocument(doc2);
    XMLManager.writeFile(xmlDoc, new File("knapsackJGAP.xml"));
    // Display the best solution we found.
    // -----------------------------------
    IChromosome bestSolutionSoFar = population.getFittestChromosome();
    System.out.println(
        "The best solution has a fitness value of " + bestSolutionSoFar.getFitnessValue());
    System.out.println("It contained the following: ");
    int count;
    double totalVolume = 0.0d;
    for (int i = 0; i < bestSolutionSoFar.size(); i++) {
      count = ((Integer) bestSolutionSoFar.getGene(i).getAllele()).intValue();
      if (count > 0) {
        System.out.println("\t " + count + " x " + itemNames[i]);
        totalVolume += itemVolumes[i] * count;
      }
    }
    System.out.println("\nFor a total volume of " + totalVolume + " ccm");
    System.out.println("Expected volume was " + a_knapsackVolume + " ccm");
    System.out.println("Volume difference is " + Math.abs(totalVolume - a_knapsackVolume) + " ccm");
  }
예제 #19
0
 protected void setRandomValue(long a_value) {
   RandomGenerator randomGen = getGPConfiguration().getRandomGenerator();
   m_value_long =
       Math.round(randomGen.nextDouble() * (m_upperBounds - m_lowerBounds) + m_lowerBounds);
 }