⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 evaluator.java

📁 一个开源的用java开发的遗传算法的封装好的工程
💻 JAVA
字号:
/*
 * This file is part of JGAP.
 *
 * JGAP offers a dual license model containing the LGPL as well as the MPL.
 *
 * For licencing 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 org.jgap.*;
import java.util.*;

/**
 * Gathers statistical data and returns them on request.
 *
 * @author Klaus Meffert
 * @since 2.2
 */
public class Evaluator {
  /**@todo implement: overall score calculation (out of best/avg. fitness value
   * etc.)
   */

  /** String containing the CVS revision. Read out via reflection!*/
  private final static String CVS_REVISION = "$Revision: 1.10 $";

  /**
   * Each data has its own data container
   */
  private Map m_permutationData;

  /**
   * Stores the run-numbers (indexes) for all permutations submitted
   */
  private Map m_permutationRuns;

  /**
   * For processinf without permutation
   */
  private KeyedValues2D m_data;

  private PermutingConfiguration m_permConf;

  /**
   * Genotype data per permutation per run
   */
  private Map m_genotypeData;

  /**
   * Genotype data per permutation (averaged over all runs)
   */
  private List m_genotypeDataAvg;

  public Evaluator(final PermutingConfiguration a_conf) {
    if (a_conf == null) {
      throw new IllegalArgumentException("Configuration must not be null!");
    }
    m_permConf = a_conf;
    m_data = new KeyedValues2D();
    m_permutationData = new Hashtable();
    m_permutationRuns = new Hashtable();
    m_genotypeData = new Hashtable();
    m_genotypeDataAvg = new Vector();
  }

  public boolean hasNext() {
    return m_permConf.hasNext();
  }

  public Configuration next()
      throws InvalidConfigurationException {
    return m_permConf.next();
  }

  public void setValue(double a_value, Comparable a_rowKey,
                       Comparable a_columnKey) {
    m_data.setValue(new Double(a_value), a_rowKey, a_columnKey);
//    fireDatasetChanged();
  }

  public Number getValue(Comparable rowKey, Comparable columnKey) {
    return m_data.getValue(rowKey, columnKey);
  }

  /**
   * Sets a specific value.
   * @param a_permutation int
   * @param a_run int
   * @param a_value double
   * @param a_rowKey Comparable
   * @param a_columnKey Comparable
   *
   * @author Klaus Meffert
   * @since 2.2
   */
  public void setValue(int a_permutation, int a_run, double a_value,
                       Comparable a_rowKey, Comparable a_columnKey) {
    Object key = createKey(a_permutation, a_run);
    KeyedValues2D a_data = (KeyedValues2D) m_permutationData.get(
        key);
    if (a_data == null) {
      a_data = new KeyedValues2D();
      m_permutationData.put(key, a_data);
    }
    // Add run-number (index).
    // -----------------------
    addRunNumber(a_permutation, a_run);
    a_data.setValue(new Double(a_value), a_rowKey, a_columnKey);
  }

  protected void addRunNumber(int a_permutation, int a_run) {
    Map v = (Map) m_permutationRuns.get(new Integer(a_permutation));
    if (v == null) {
      v = new Hashtable();
    }
    v.put(new Integer(a_run), new Integer(a_run));
    m_permutationRuns.put(new Integer(a_permutation), v);
  }

  public Number getValue(int a_permutation, int a_run, Comparable rowKey,
                         Comparable columnKey) {
    KeyedValues2D a_data = (KeyedValues2D) m_permutationData.get(
        createKey(a_permutation, a_run));
    if (a_data == null) {
      return null;
    }
    return a_data.getValue(rowKey, columnKey);
  }

  public KeyedValues2D getData() {
    return m_data;
  }

  protected Object createKey(int a_permutation, int a_run) {
    return a_permutation + "_" + a_run;
  }

  /**
   * Calculates the average fitness value curve for a given permutation.
   * If permutation -1 is given, a composition of all permutations available
   * is created.
   * @param a_permutation -1 to use all permutations
   * @return DefaultKeyedValues2D list of fitness values, one for each
   * individual in the generation
   *
   * @author Klaus Meffert
   * @since 2.2
   */
  public KeyedValues2D calcAvgFitness(int a_permutation) {
    if (a_permutation == -1) {
      Iterator it = m_permutationRuns.keySet().iterator();
      Integer permNumberI;
      int permNumber;
      KeyedValues2D result = new KeyedValues2D();
      while (it.hasNext()) {
        permNumberI = (Integer) it.next();
        permNumber = permNumberI.intValue();
        calcAvgFitnessHelper(permNumber, result);
      }
      return result;
    }
    else {
      KeyedValues2D a_data = new KeyedValues2D();
      calcAvgFitnessHelper(a_permutation, a_data);
      return a_data;
    }
  }

  protected void calcAvgFitnessHelper(int a_permutation,
                                      final KeyedValues2D result) {
    // Determine run-numbers of given permutation.
    // -------------------------------------------
    Map runNumbers = (Map) m_permutationRuns.get(new Integer(a_permutation));
    if (runNumbers == null) {
      return;
    }
    // Loop over all run-numbers.
    // --------------------------
    Iterator it = runNumbers.keySet().iterator();
    int numRuns = runNumbers.keySet().size();
    Integer runI;
    while (it.hasNext()) {
      runI = (Integer) it.next();
      // Determine dataset of given permutation.
      // ---------------------------------------
      KeyedValues2D a_data = (KeyedValues2D) m_permutationData.
          get(createKey(a_permutation, runI.intValue()));
      // Determine values for current run-number and "add" them to gathered
      // data.
      // ------------------------------------------------------------------
      for (int col = 0; col < a_data.getColumnCount(); col++) {
        for (int row = 0; row < a_data.getRowCount(); row++) {
          // Previous value (summation).
          // --------------------------.
          Double d = (Double) result.getValue(a_data.getRowKey(row),
                                              a_data.getColumnKey(col));
          double newValue;
          if (d == null) {
            newValue = 0.0d;
          }
          else {
            newValue = d.doubleValue();
          }
          // Add current value (divided by total number of runs to get an
          // averaged value).
          // ------------------------------------------------------------
          newValue +=
              a_data.getValue(a_data.getRowKey(row), a_data.getColumnKey(col)).
              doubleValue() / numRuns;
          // Set averaged value back to result dataset.
          // ------------------------------------------
          result.setValue(new Double(newValue), a_data.getRowKey(row),
                          a_data.getColumnKey(col));
        }
      }
    }
  }

  /**
   * Returns a list of lists (i.e. a matrix) to use for output as a table
   * @param a_data DefaultKeyedValues2D
   * @return List
   */
  /**@todo implement*/
//  public List getTable(KeyedValues2D a_data) {
//    return null;
//  }

  /**
   * Calculates average fitness value improvement per generation.
   *
   * @param a_permutation int
   * @return DefaultKeyedValues2D
   *
   * @author Klaus Meffert
   * @since 2.2
   */
  public KeyedValues2D calcAvgFitnessImpr(int a_permutation) {
    /**@todo implement*/
    /**@todo is this method used resp. contained in calcPerformance?*/
    Map runNumbers = (Map) m_permutationRuns.get(new Integer(a_permutation));
    if (runNumbers == null) {
      return null;
    }
//    Map fitnessImpr = new Hashtable();
    // Loop over all run-numbers.
    // --------------------------
    Iterator it = runNumbers.keySet().iterator();
//    int numRuns = runNumbers.keySet().size();
    Integer runI;
    while (it.hasNext()) {
      runI = (Integer) it.next();
      // Determine dataset of given permutation.
      // ---------------------------------------
      KeyedValues2D a_data = (KeyedValues2D) m_permutationData.
          get(createKey(a_permutation, runI.intValue()));
      for (int col = 0; col < a_data.getColumnCount(); col++) {
        for (int row = 0; row < a_data.getRowCount(); row++) {
        }
      }
    }
    return null;
  }

  /**
   *
   * @param a_permutation the permutation to determine the number of runs for
   * @return the number of runs for the given permutation
   */
  public int getNumberOfRuns(int a_permutation) {
    Map runNumbers = (Map) m_permutationRuns.get(new Integer(a_permutation));
    if (runNumbers == null) {
      return 0;
    }
    else {
      return runNumbers.keySet().size();
    }
  }

  /**
   * Stores information contained in the given genotype.
   * @param a_permutation int
   * @param a_run index of the run proceeded for the given genotype
   * @param a_genotype the genotype holding the population of chromosomes
   *
   * @author Klaus Meffert
   * @since 2.2
   */
  public void storeGenotype(int a_permutation, int a_run, Genotype a_genotype) {
    /**@todo implement*/
    // average and maximum fitness value
    //
    GenotypeData data = new GenotypeData();
    int generation = a_genotype.getConfiguration().getGenerationNr();
    data.generation = generation;
    Population pop = a_genotype.getPopulation();
    data.hashCode = a_genotype.hashCode();
    int popSize = pop.size();
    data.chromosomeData = new ChromosomeData[popSize];
    data.size = popSize;
    // gather data of Chromosomes
    IChromosome chrom;
    ChromosomeData chromData;
    for (int i = 0; i < popSize; i++) {
      chrom = pop.getChromosome(i);
      chromData = new ChromosomeData();
      chromData.fitnessValue = chrom.getFitnessValue();
      chromData.size = chrom.size();
      chromData.index = i;
      data.chromosomeData[i] = chromData;
    }
    String key = a_permutation + "_" + a_run;
    m_genotypeData.put(key, data);
    addRunNumber(a_permutation, a_run);
  }

  public GenotypeData retrieveGenotype(int a_permutation, int a_run) {
    return (GenotypeData) m_genotypeData.get(a_permutation + "_" + a_run);
  }

  /**
   * Calculates performance metrics for a given permutation and run stored
   * before with storeGenotype, like:
   * average fitness, maximum fitness...
   * @param a_permutation the permutation to compute the performance metrics
   * for
   * @return computed statistical data
   *
   * @author Klaus Meffert
   * @since 2.2
   */
  public GenotypeDataAvg calcPerformance(int a_permutation) {
    int numRuns = getNumberOfRuns(a_permutation);
    GenotypeData data;
    GenotypeDataAvg dataAvg = new GenotypeDataAvg();
    dataAvg.permutation = a_permutation;
    double sizeAvg = 0.0d;
    double fitnessAvg = 0.0d;
    double fitnessBest = -1.0d;
    double fitnessBestOld = -1.0d;
    double fitness;
    int fitnessBestGen = -1;
    double fitnessAvgChroms;
    double fitnessDiversityChromsOld = -1.0d;
    double fitnessBestDeltaAvg = 0.0d;
    double fitnessDiversity;
    double fitnessDiversityAvg = 0.0d;
    int size;
    ChromosomeData chrom;
    for (int i = 0; i < numRuns; i++) {
      data = retrieveGenotype(a_permutation, i);
      // generation the genotype data represents
      if (i == 0) {
        dataAvg.generation = data.generation;
      }
      // average number of chromosomes
      sizeAvg += (double) data.size / numRuns;
      size = data.size;
      fitnessAvgChroms = 0.0d;
      fitnessDiversity = 0.0d;
      double fitnessBestLocal = -1.0d;
      for (int j = 0; j < size; j++) {
        chrom = data.chromosomeData[j];
        fitness = chrom.fitnessValue;
        // diversity of fitness values over all chromosomes
        if (j > 0) {
          fitnessDiversity += Math.abs(fitness - fitnessDiversityChromsOld) /
              (size - 1);
        }
        fitnessDiversityChromsOld = fitness;
        // average fitness value for generation over all Chromosomes
        fitnessAvgChroms += fitness / size;
        // fittest chromosome in generation over all runs
        if (fitnessBest < fitness) {
          fitnessBest = fitness;
          // memorize generation number in which fittest chromosome appeared
          fitnessBestGen = data.generation;
        }
        // fittest chromosome in generation over current runs
        if (fitnessBestLocal < fitness) {
          fitnessBestLocal = fitness;
        }
      }
      // average fitness value for generation over all runs
      fitnessAvg += fitnessAvgChroms / numRuns;
      // average fitness delta value for generation over all runs
      fitnessDiversityAvg += fitnessDiversity / numRuns;
      // absolute delta between two adjacent best fitness values
      if (i > 0) {
        fitnessBestDeltaAvg += Math.abs(fitnessBestLocal - fitnessBestOld) /
            (numRuns - 1);
      }
      fitnessBestOld = fitnessBestLocal;
    }
    dataAvg.sizeAvg = sizeAvg;
    dataAvg.avgFitnessValue = fitnessAvg;
    dataAvg.bestFitnessValue = fitnessBest;
    dataAvg.bestFitnessValueGeneration = fitnessBestGen;
    dataAvg.avgDiversityFitnessValue = fitnessDiversityAvg;
    dataAvg.avgBestDeltaFitnessValue = fitnessBestDeltaAvg;
    //store computed (averaged) data
    m_genotypeDataAvg.add(dataAvg);
    return dataAvg;
  }

  /**
   * Averaged genotype data (computed over all runs of a permutation)
   *
   * @author Klaus Meffert
   * @since 2.2
   */
  public class GenotypeDataAvg {
    public int permutation;

    public int generation;

    public double sizeAvg;

    public double bestFitnessValue;

    public double avgFitnessValue;

    public int bestFitnessValueGeneration;

    public double avgDiversityFitnessValue;

    public double avgBestDeltaFitnessValue;
  }
  /**
   * Genotype data for one single run
   *
   * @author Klaus Meffert
   * @since 2.2
   */
  public class GenotypeData {
    public int generation;

    public int hashCode;

    public int size;

    public ChromosomeData[] chromosomeData;
  }
  public class ChromosomeData {
    public int index;

    public int size;

    public double fitnessValue;
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -