/**
  * Convenience method that returns a new Chromosome instance with its genes values (alleles)
  * randomized. Note that, if possible, this method will acquire a Chromosome instance from the
  * active ChromosomePool (if any) and then randomize its gene values before returning it. If a
  * Chromosome cannot be acquired from the pool, then a new instance will be constructed and its
  * gene values randomized before returning it.
  *
  * @param a_configuration the configuration to use
  * @return randomly initialized Chromosome
  * @throws InvalidConfigurationException if the given Configuration instance is invalid
  * @throws IllegalArgumentException if the given Configuration instance is null
  * @author Neil Rotstan
  * @author Klaus Meffert
  * @since 1.0
  */
 public static IChromosome randomInitialChromosome(Configuration a_configuration)
     throws InvalidConfigurationException {
   // Sanity check: make sure the given configuration isn't null.
   // -----------------------------------------------------------
   if (a_configuration == null) {
     throw new IllegalArgumentException("Configuration instance must not be null");
   }
   // Lock the configuration settings so that they can't be changed
   // from now on.
   // -------------------------------------------------------------
   a_configuration.lockSettings();
   // First see if we can get a Chromosome instance from the pool.
   // If we can, we'll randomize its gene values (alleles) and then
   // return it.
   // -------------------------------------------------------------
   IChromosomePool pool = a_configuration.getChromosomePool();
   if (pool != null) {
     IChromosome randomChromosome = pool.acquireChromosome();
     if (randomChromosome != null) {
       Gene[] genes = randomChromosome.getGenes();
       RandomGenerator generator = a_configuration.getRandomGenerator();
       for (int i = 0; i < genes.length; i++) {
         genes[i].setToRandomValue(generator);
         /** @todo what about Gene's energy? */
       }
       randomChromosome.setFitnessValueDirectly(FitnessFunction.NO_FITNESS_VALUE);
       return randomChromosome;
     }
   }
   // We weren't able to get a Chromosome from the pool, so we have to
   // construct a new instance and build it from scratch.
   // ------------------------------------------------------------------
   IChromosome sampleChromosome = a_configuration.getSampleChromosome();
   sampleChromosome.setFitnessValue(FitnessFunction.NO_FITNESS_VALUE);
   Gene[] sampleGenes = sampleChromosome.getGenes();
   Gene[] newGenes = new Gene[sampleGenes.length];
   RandomGenerator generator = a_configuration.getRandomGenerator();
   for (int i = 0; i < newGenes.length; i++) {
     // We use the newGene() method on each of the genes in the
     // sample Chromosome to generate our new Gene instances for
     // the Chromosome we're returning. This guarantees that the
     // new Genes are setup with all of the correct internal state
     // for the respective gene position they're going to inhabit.
     // -----------------------------------------------------------
     newGenes[i] = sampleGenes[i].newGene();
     // Set the gene's value (allele) to a random value.
     // ------------------------------------------------
     newGenes[i].setToRandomValue(generator);
     /** @todo what about Gene's energy? */
   }
   // Finally, construct the new chromosome with the new random
   // genes values and return it.
   // ---------------------------------------------------------
   return new Chromosome(a_configuration, newGenes);
 }