/*
 * This file is part of JGAP.
 *
 * JGAP offers a dual license model containing the LGPL as well as the MPL.
 *
 * For licensing information please see the file license.txt included with JGAP
 * or have a look at the top of class org.jgap.Chromosome which representatively
 * includes the JGAP license policy applicable for any file delivered with JGAP.
 */
package org.jgap.audit;

import java.util.*;

import org.jgap.*;
import org.jgap.eval.*;

//import examples.*;

/**
 * Evaluates evolution progress thas has previously been tracked by
 * EvolutionMonitor (or a similar instance).
 * This class regards a complete evolution, not just a single round. This is an
 * optional way, another would be to just gather data per round and then display
 * or evaluate the round-specific data.
 * This class considers global (complete evolution) data because computations
 * are executed on this data, like tracking chromosomes, evaluating the progress
 * of selectors or genetic operators, etc.
 *
 * @author Klaus Meffert
 * @since 3.5
 */
public class EvolutionEvaluator {
  /** String containing the CVS revision. Read out via reflection!*/
  private final static String CVS_REVISION = "$Revision: 1.3 $";

  private PopulationHistoryIndexed m_monitorData;

  private List evolutionIndexes;

  public EvolutionEvaluator(PopulationHistoryIndexed a_monitorData) {
    if (a_monitorData == null) {
      throw new IllegalArgumentException("Data must not be null!");
    }
    m_monitorData = a_monitorData;
    evolutionIndexes = new Vector();
  }

  public void evaluate() {
    Map data = m_monitorData.getPopulationsHistory();
    Iterator evolutions = data.keySet().iterator();
    Population pop1, pop2;
    // Gather all evolution indexes.
    // -----------------------------
    int evNo;
    while (evolutions.hasNext()) {
      evNo = evolutions.next();
      evolutionIndexes.add(evNo);
    }
    // Gather a list of unique IDs for all chromosomes within all populations
    // of all recorded states in all generations.
    // ----------------------------------------------------------------------
    Map>> chromIDs =
        gatherChromosomesIDs(data);
    // Track all chromosomes.
    // ----------------------
    Map>> chromTrack =
        trackChromosomes(data);
    /**@todo use chromIDs and chromTrack*/
    int size = evolutionIndexes.size();
    for (int i = 0; i < size; i++) {
      evNo = evolutionIndexes.get(i);
      Map
          eventsPops = m_monitorData.getPopulations(evNo);
      // Care about all executed Selectors per generation.
      // -------------------------------------------------
      int index = 0;
      do {
        PopulationContext ctx1 = eventsPops.get(EvolutionMonitor.
            CONTEXT_OFFSET_NATURAL_SELECTOR1 + index * 2 + 0);
        if (ctx1 == null) {
          break;
        }
        pop1 = ctx1.getPopulation();
        NaturalSelector selector = ctx1.getSelector();
        PopulationContext ctx2 = eventsPops.get(EvolutionMonitor.
            CONTEXT_OFFSET_NATURAL_SELECTOR1 + index * 2 + 1);
        pop2 = ctx2.getPopulation();
        // Evaluate average fitness of selection

        // Track which individuals contributed to the top n solutions

        /**@todo */
      } while (true);
      // Executed Operators per generation.

      // Fitness progress intra-generation.

      // Fitness progress over generations.
    }
  }

  /**
   * Tracks the originator chain of each chromosome in the final population.
   * The originator chain potentially begins with the first generation.
   * A chromosome could virtually have as many originators as there are
   * evolutions (minus one), or it could have zero originators. The latter case
   * means the chromosome was just created in the final population.
   *
   * @param a_data population (evolution) data
   * @return the result of the investigation
   *
   * @author Klaus Meffert
   * @since 3.5
   */
  private Map>>
      trackChromosomes(Map a_data) {
    int size = evolutionIndexes.size() - 1;
    Map contextMap = a_data.get(size);
    PopulationContext context = contextMap.get(EvolutionMonitor.
        CONTEXT_END_OF_CYCLE);
    Population finalPop = context.getPopulation();
    return trackChromosomes(a_data, finalPop);
  }

  /**
   *
   * @param a_data Map
   * @param a_pop Population
   * @return the result of the investigation
   *
   * @author Klaus Meffert
   * @since 3.5
   */
  private Map>>
      trackChromosomes(Map a_data, Population a_pop) {
    // A track is a list of chromosomes, with each of them having a list
    // of originators:
    // A Chromosome has originators, possibly from several different evolutions.
    // -------------------------------------------------------------------------
    Map>> chromosomesTrack
        = new Hashtable();
    int evNo;
    int currentIndex = evolutionIndexes.size();
    if (currentIndex < 1) {
      return chromosomesTrack;
    }
    // Retrieve predecessing population.
    // ---------------------------------
    evNo = evolutionIndexes.get(currentIndex - 1);
    Map contextMap = a_data.get(evNo);
    PopulationContext context = contextMap.get(EvolutionMonitor.
        CONTEXT_END_OF_CYCLE);
    Population previousPop = context.getPopulation();
    Map> evoMap = new Hashtable();
    // Find originators for all chromosomes in given population.
    // ---------------------------------------------------------
    for (int i = 0; i < a_pop.size(); i++) {
      IChromosome chrom = a_pop.getChromosome(i);
      int uindex = 1;
      List uids = new Vector();
      // Gather originators for current chromosome in population.
      // --------------------------------------------------------
      do {
        String uid = chrom.getUniqueIDTemplate(uindex++);
        IChromosome chrom0 = null;
        if (uid != null || uindex == 2) {
          // Find chromosome instance for unique ID.
          // ---------------------------------------
          for (int k = 0; k < previousPop.size(); k++) {
            chrom0 = previousPop.getChromosome(k);
            if (chrom0.getUniqueID().equals(uid)) {
              break;
            }
          }
          uids.add(chrom0);
          evoMap.put(evNo, uids);
          chromosomesTrack.put(chrom, evoMap);
        }
        if (uid == null) {
          break;
        }
      } while (true);
    }
    return chromosomesTrack;
  }

  /**
   * For all chromosomes: Gather their IDs and the list of indexes of the
   * evolution rounds they appeared in. Normally, a chromosome with a specific
   * unique ID just appears within one single generation. The reason is, that,
   * normally, in selection and genetic operator, the chromosomes' IDs change,
   * because the chromosomes are cloned.
   *
   * @param a_data monitoring data
   * @return result of investigation
   */
  private Map>> gatherChromosomesIDs(
      Map a_data) {
    int size = evolutionIndexes.size() - 1;
    Map contextMap;
    // Gather all chromosomes' unique IDs
    // String = ID, IChromosome = Chromosome for ID, List = Index of Generation
    //   the chromosome appears in
    Map>> chromIDs = new Hashtable();
    // For each generator/evolution round...
    // -------------------------------------
    for (int i = 0; i <= size; i++) {
      int evNo = evolutionIndexes.get(i);
      contextMap = a_data.get(evNo);
      Iterator values = contextMap.values().iterator();
      // For each recorded Population state within a generation.
      // -------------------------------------------------------
      while (values.hasNext()) {
        PopulationContext ctx = values.next();
        Population pop = ctx.getPopulation();
        // For each chromosome...
        // ----------------------
        for (int j = 0; j < pop.size(); j++) {
          IChromosome chrom = pop.getChromosome(j);
          Map> entry = chromIDs.get(chrom.getUniqueID());
          List valueList;
          if(entry == null) {
            // Add a new list with the first found evolution number.
            // -----------------------------------------------------
            valueList = new Vector();
            valueList.add(evNo);
            Map valueMap = new Hashtable();
            valueMap.put(chrom, valueList);
            chromIDs.put(chrom.getUniqueID(), valueMap);
          }
          else {
            // Already found in another evolution, just add the new number.
            // ------------------------------------------------------------
            valueList = entry.values().iterator().next();
            if(!valueList.contains(evNo)) {
              valueList.add(evNo);
            }
          }
        }
      }
    }
    return chromIDs;
  }

  /**
   * Sample usage of monitoring, together with an existing JGAP example.
   *
   * @param args String[]
   * @throws Exception
   *
   * @author Klaus Meffert
   * @since 3.5
   */
//  public static void main(String[] args)
//      throws Exception {
//    args = new String[2];
//    args[0] = "93";
//    args[1] = "MONITOR";
//    MinimizingMakeChange.main(args);
//    IEvolutionMonitor monitor = MinimizingMakeChange.m_monitor;
//    EvolutionEvaluator evaluator = new EvolutionEvaluator(
//        monitor.getPopulations());
//    evaluator.evaluate();
//  }
}

 

Ads help maintain this website.