public double getDoubleValue(int valueIndex) {
   BitString clear = getClearBitCode(valueIndex);
   double f = 1.0;
   double val = 0.0;
   for (int i = getPrecision() - 1; i >= 1; i--, f *= 2.0) val += (clear.get(i) ? 1.0 : 0.0) * f;
   if (clear.get(0)) val = -val;
   val /= decimalScale;
   return val;
 }
 public void setDoubleValue(int valueIndex, double value) {
   double setVal = Math.rint(value * decimalScale);
   if (setVal >= Long.MAX_VALUE || setVal <= Long.MIN_VALUE)
     throw new IllegalArgumentException("Absolute decimal value too big");
   BitString clear = new BitString(getPrecision());
   clear.set(0, setVal < 0);
   setVal = Math.abs(setVal);
   double f = 1.0;
   for (int i = getPrecision() - 1; i >= 1; i--, f *= 2.0) clear.set(i, (setVal % (2.0 * f) >= f));
   setClearBitCode(valueIndex, clear);
 }
  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);
  }