Newer
Older
abgabensammlungSS15 / ea / project / ExampleProblem.java
@MaxXximus92 MaxXximus92 on 6 Jul 2015 4 KB mr rename
package eva2.problems.simple;

import eva2.util.annotation.Description;
import eva2.util.annotation.Parameter;

/**
 * This is a simple example for adding problems to EvA2. The EvA2.jar is
 * required for this class! The jar file is available from
 * http://www.ra.cs.uni-tuebingen.de/software/EvA2/downloads/2.2.0-rc1/EvA2.jar<br>
 * <br>
 * To be found by EvA2, this class must remain in the package
 * eva2.problems.simple!<br>
 * <br>
 * Depending on your representation of a solution, you must extend either the
 * class SimpleProblemDouble or SimpleProblemBinary!<br>
 * <br>
 * To optimize this problem, start EvA2 (use the eva2.gui.Main class) and select
 * as Problem: SimpleProblemWrapper. Next select as Simple Problem:
 * eva2.problems.simple.ExampleProblem and customize any parameters. You can now
 * try different optimization algorithms!<br>
 * <br>
 * To launch EvA2 from the command line with this custom problem:<br>
 * 1. extract the EvA2.jar (NOT EvA2Base.jar!)<br>
 * 2. place this class file in the directory eva2/problems/simple/<br>
 * 3. compile this class with: javac eva2/problems/simple/ExampleProblem.java<br>
 * 4. start EvA2 with: java eva2.gui.Main<br>
 * <br>
 * Some tips: - Look at the function setAbs, setDimension, and
 * setEvaluateFunction to see how EvA2 recognizes changeable inputs! Note that
 * getX() and setX() must be present to correctly provide the input!
 * 
 * @author mroemer
 *
 */
@Description("An example problem for including new problems in EvA2.")
public class ExampleProblem extends SimpleProblemDouble {

  /**
   * 
   */
  private static final long serialVersionUID = 2796213693976730841L;

  /**
   * Possible functions to evaluate the fitness
   */
  public enum EvaluateFunction {
    SUM, MIN, MAX, MEAN
  }

  /**
   * Problem dimension
   */
  private int dimension = 10;
  /**
   * Fitness evaluation function
   */
  private EvaluateFunction evalFun = EvaluateFunction.SUM;
  /**
   * Use absolute values for evaluation?
   */
  private boolean useAbs = true;

  public ExampleProblem() {
    // Here you can read files you need (i.e., input data) or set default values
    // for parameters
  }

  /**
   * Evaluate a double vector representing a possible problem solution as part
   * of an individual in the EvA framework. This makes up the target function to
   * be evaluated.
   *
   * @param x
   *          a double vector to be evaluated
   * @return the fitness vector assigned to x as to the target function (the
   *         return value is actually a array with only one entry!)
   */
  @Override
  public double[] evaluate(double[] individual) {
    double fitness = 0;
    switch (evalFun) {
    case SUM:
      fitness = 0;
      for (int i = 0; i < individual.length; i++) {
        fitness += evalAt(individual, i);
      }
      break;
    case MIN:
      fitness = Double.POSITIVE_INFINITY;
      for (int i = 0; i < individual.length; i++) {
        fitness = Math.min(fitness, evalAt(individual, i));
      }
      break;
    case MAX:
      fitness = Double.NEGATIVE_INFINITY;
      for (int i = 0; i < individual.length; i++) {
        fitness = Math.max(fitness, evalAt(individual, i));
      }
      break;
    case MEAN:
      fitness = 0;
      for (int i = 0; i < individual.length; i++) {
        fitness += evalAt(individual, i);
      }
      fitness = fitness / dimension;
      break;
    default:
      break;
    }
    return new double[] { fitness };
  }

  // Evaluates an individual at a single point
  // This is a abstraction to simplify incorporation of useAbs...
  private double evalAt(double[] individual, int i) {
    return useAbs ? Math.abs(individual[i]) : individual[i];
  }

  /*
   * Below are parameters that can be set at runtime! See the class comment for
   * more information...
   */

  /**
   * Return the problem dimension.
   *
   * @return the problem dimension
   */
  @Override
  public int getProblemDimension() {
    return dimension;
  }

  /**
   * This method allows you to toggle the usage of absolute values.
   *
   * @param show
   *          Whether to use absolute values or not
   */
  @Parameter(description = "Use absolute values for evaluation?")
  public void setAbs(boolean useAbs) {
    this.useAbs = useAbs;
  }

  public boolean getAbs() {
    return this.useAbs;
  }

  /**
   * Set the problem dimension.
   *
   * @param d
   *          The dimension.
   */
  @Parameter(description = "Set 1 <= Dimension <= 1000.")
  public void setDimension(int d) {
    if (d < 1) {
      d = 1;
    }
    if (d > 1000) {
      d = 1000;
    }
    this.dimension = d;
  }

  public int getDimension() {
    return this.dimension;
  }

  /**
   * Set the evaluation function.
   *
   * @param f
   *          The evaluation function.
   */
  @Parameter(description = "Choose the timeinterval type.")
  public void setEvaluateFunction(EvaluateFunction f) {
    this.evalFun = f;
  }

  public EvaluateFunction getEvaluateFunction() {
    return this.evalFun;
  }

}