/**
  * Operate on the given chromosome with the given mutation rate.
  *
  * @param a_chrom chromosome to operate
  * @param a_rate mutation rate
  * @param a_generator random generator to use (must not be null)
  * @return mutated chromosome of null if no mutation has occured.
  * @author Audrius Meskauskas
  * @author Florian Hafner
  * @since 3.3.2
  */
 protected IChromosome operate(
     final IChromosome a_chrom, final int a_rate, final RandomGenerator a_generator) {
   IChromosome chromosome = null;
   // ----------------------------------------
   for (int j = m_startOffset; j < a_chrom.size(); j++) {
     // Ensure probability of 1/currentRate for applying mutation.
     // ----------------------------------------------------------
     if (a_generator.nextInt(a_rate) == 0) {
       if (chromosome == null) {
         chromosome = (IChromosome) a_chrom.clone();
         // In case monitoring is active, support it.
         // -----------------------------------------
         if (m_monitorActive) {
           chromosome.setUniqueIDTemplate(a_chrom.getUniqueID(), 1);
         }
       }
       Gene[] genes = chromosome.getGenes();
       if (m_range == 0) {
         m_range = genes.length;
       }
       Gene[] mutated = operate(a_generator, j, genes);
       // setGenes is not required for this operator, but it may
       // be needed for the derived operators.
       // ------------------------------------------------------
       try {
         chromosome.setGenes(mutated);
       } catch (InvalidConfigurationException cex) {
         throw new Error("Gene type not allowed by constraint checker", cex);
       }
     }
   }
   return chromosome;
 }
  public Individual[] reproduce(Individual[] parents, GAParameterSet params) {
    if (parents.length != getRequiredNumberOfParents())
      throw new IllegalArgumentException(
          "Need "
              + getRequiredNumberOfParents()
              + " parents for reproduction (not "
              + parents.length
              + ")");

    // Check correct type for parents, get length:
    int bitLen = checkParentsTypeAndLength(parents);

    // Chance (1 - xover probability) that parents wont be changed:
    final RandomGenerator rnd = params.getRandomGenerator();

    if (rnd.nextDouble() >= getXOverProbability()) return makeCopyOfParents(parents, params);

    // Get parents bitsrings:
    BitString p1 = ((BinaryEncodedIndividual) parents[0]).getBitStringRepresentation();
    BitString p2 = ((BinaryEncodedIndividual) parents[1]).getBitStringRepresentation();

    // x-over:
    final int maxAttempts = params.getMaxBadReproductionAttempts();

    int attempts = 0;
    boolean kidsAreValid = false;
    do {
      kidsAreValid = false;
      int xPoint = rnd.nextInt(1, bitLen);

      // offspring bit strings:
      BitString c1 = new BitString(bitLen);
      BitString c2 = new BitString(bitLen);

      // copy before xover-point:
      for (int i = 0; i < xPoint; i++) {
        c1.set(i, p1.get(i));
        c2.set(i, p2.get(i));
      }

      // copy after xover-point:
      for (int i = xPoint; i < bitLen; i++) {
        c1.set(i, p2.get(i));
        c2.set(i, p1.get(i));
      }

      // create children and check if children are valid:
      ClassifierIndividual[] kids = createKidsFromEncoding(params, c1, c2);
      kidsAreValid = kidsSatisfyConstraints(kids, params);

      // return valid kids or have another attempts:
      if (kidsAreValid) return kids;
      else attempts++;

    } while (!kidsAreValid && attempts < maxAttempts);

    // all attempts failed:
    return makeCopyOfParents(parents, params);
  }
  /**
   * Operate on the given array of genes. This method is only called when it is already clear that
   * the mutation must occur under the given mutation rate.
   *
   * @param a_generator a random number generator that may be needed to perform a mutation
   * @param a_target_gene an index of gene in the chromosome that will mutate
   * @param a_genes the array of all genes in the chromosome
   * @return the mutated gene array
   * @author Florian Hafner
   * @since 3.3.2
   */
  protected Gene[] operate(
      final RandomGenerator a_generator, final int a_target_gene, final Gene[] a_genes) {
    // Other needs to be an integer that is within the range of the subject
    // target gene.

    int rand = a_generator.nextInt(2 * m_range);
    int other = (a_target_gene - m_range) + rand;
    if (other < 0) {
      other = 0;
    }
    if (other >= a_genes.length) {
      other = a_genes.length - 1; // Index is -1 of length
    }
    Gene t = a_genes[a_target_gene];
    a_genes[a_target_gene] = a_genes[other];
    a_genes[other] = t;
    if (m_monitorActive) {
      a_genes[a_target_gene].setUniqueIDTemplate(a_genes[other].getUniqueID(), 1);
      a_genes[other].setUniqueIDTemplate(a_genes[a_target_gene].getUniqueID(), 1);
    }
    return a_genes;
  }
Exemplo n.º 4
0
 /** {@inheritDoc} */
 public long nextSecureLong(final long lower, final long upper) throws NumberIsTooLargeException {
   if (lower >= upper) {
     throw new NumberIsTooLargeException(
         LocalizedFormats.LOWER_BOUND_NOT_BELOW_UPPER_BOUND, lower, upper, false);
   }
   final RandomGenerator rng = getSecRan();
   final long max = (upper - lower) + 1;
   if (max <= 0) {
     // the range is too wide to fit in a positive long (larger than 2^63); as it covers
     // more than half the long range, we use directly a simple rejection method
     while (true) {
       final long r = rng.nextLong();
       if (r >= lower && r <= upper) {
         return r;
       }
     }
   } else if (max < Integer.MAX_VALUE) {
     // we can shift the range and generate directly a positive int
     return lower + rng.nextInt((int) max);
   } else {
     // we can shift the range and generate directly a positive long
     return lower + nextLong(rng, max);
   }
 }
  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);
    }
  }
  protected void doCrossover(
      IChromosome firstMate,
      IChromosome secondMate,
      List a_candidateChromosomes,
      RandomGenerator generator) {
    Gene[] firstGenes = firstMate.getGenes();
    Gene[] secondGenes = secondMate.getGenes();
    int locus = generator.nextInt(firstGenes.length);
    // Swap the genes.
    // ---------------
    Gene gene1, gene11;
    Gene gene2, gene22;
    Integer firstAllele, firstAllele1;
    Integer secondAllele, secondAllele1;

    for (int j = locus; j < firstGenes.length; j++) {
      gene1 = firstGenes[j];
      gene2 = secondGenes[j];

      firstAllele = (Integer) gene1.getAllele();
      secondAllele = (Integer) gene2.getAllele();

      if (payload[firstAllele] != null && payload[secondAllele] != null) {
        if (!checkAlleles(firstMate, j, secondAllele)) gene1.setAllele(secondAllele);
        if (!checkAlleles(secondMate, j, firstAllele)) gene2.setAllele(firstAllele);
      }

      if (payload[firstAllele] == null && payload[secondAllele] == null) {

        if (payload[64 + firstAllele].getPair() != payload[64 + secondAllele].getPair()) continue;

        if (payload[64 + firstAllele].getPair() == 1) {
          if (!checkAlleles(firstMate, j, secondAllele)
              && !checkAlleles(secondMate, j, firstAllele)) {
            if (chkonepair(j) || chktwopair(j + 1)) {
              System.out.println("Crossover.. something wrong");
            }

            gene11 = firstGenes[j + 1];
            firstAllele1 = (Integer) gene11.getAllele();

            gene22 = secondGenes[j + 1];
            secondAllele1 = (Integer) gene22.getAllele();

            if (!checkAlleles(firstMate, j + 1, secondAllele1)) {
              gene1.setAllele(secondAllele);
              gene11.setAllele(secondAllele1);
            }

            if (!checkAlleles(secondMate, j + 1, firstAllele1)) {
              gene2.setAllele(firstAllele);
              gene22.setAllele(firstAllele1);
            }
          }
        } else if (payload[64 + firstAllele].getPair() == 2) {

          if (!checkAlleles(firstMate, j, secondAllele)
              && !checkAlleles(secondMate, j, firstAllele)) {

            gene11 = firstGenes[j - 1];
            firstAllele1 = (Integer) gene11.getAllele();

            gene22 = secondGenes[j - 1];
            secondAllele1 = (Integer) gene22.getAllele();

            if (!checkAlleles(firstMate, j - 1, secondAllele1)) {
              gene1.setAllele(secondAllele);
              gene11.setAllele(secondAllele1);
            }

            if (!checkAlleles(secondMate, j - 1, firstAllele1)) {
              gene2.setAllele(firstAllele);
              gene22.setAllele(firstAllele1);
            }
          }
        } else {
          System.out.println("...Invalid Configuration Exception...");
        }
      }
    }
    // Add the modified chromosomes to the candidate pool so that
    // they'll be considered for natural selection during the next
    // phase of evolution.
    // -----------------------------------------------------------
    a_candidateChromosomes.add(firstMate);
    a_candidateChromosomes.add(secondMate);
  }