/**********************************************************************
# Copyright (c) EWA Systems Inc. 1998 - 2005 All Rights Reserved
#               No part of this program may be photocopied, reproduced,
#               or translated to another programming language without
#               the prior written consent of EWA Systems.
**********************************************************************/

package com.ewasystems.opt.ga.test;

import com.ewasystems.opt.ga.GeneticAlleleSet;
import com.ewasystems.opt.ga.GeneticEngine;
import com.ewasystems.opt.ga.GeneticGene;
import com.ewasystems.opt.ga.GeneticProblem;
import com.ewasystems.opt.ga.GeneticRunTask;

/**
 * <p>Genetic Algorithm Test Case: Multi Variable Optimization</p>
 * <p>Description: Minimize f(x1,x2,x3,x4,x5) = x1*sin(x1) + 1.7*x2*sin(x1)
 *  - 1.5*x3 - 0.1*x4*cos(x4+x5-x1) + (0.2*x5^2-x2) - 1 where X = [-80, 80] by 1</p>
 * <p>Copyright: EWASystems Copyright (c) 1998 - 2005</p>
 * <p>Company: EWASystems</p>
 * @author Lincoln Evans-Beauchamp
 * @version 1.0
 */
public class MultiVarMin extends GeneticProblem
{
  /**
   * Problem Constructor
   */
  public MultiVarMin()
  {
    super("Multivariable Minimize", "Minimize f(x1,x2,x3,x4,x5) = x1*sin(x1) + 1.7*x2*sin(x1) - 1.5*x3 - 0.1*x4*cos(x4+x5-x1) + (0.2*x5^2-x2) - 1 where X = [-80, 80] by 1");
  }

  /**
   * The Objective Function
   * @param gene The Genetic Gene to Test
   * @return double: The Genetic Gene's Fitness
   */
  public double f(GeneticGene gene)
  {
    double x1 = ((Double)gene.getGeneValue(0)).doubleValue();
    double x2 = ((Double)gene.getGeneValue(1)).doubleValue();
    double x3 = ((Double)gene.getGeneValue(2)).doubleValue();
    double x4 = ((Double)gene.getGeneValue(3)).doubleValue();
    double x5 = ((Double)gene.getGeneValue(4)).doubleValue();
    return x1*Math.sin(x1)+1.7d*x2*Math.sin(x1)-1.5d*x3-.1d*x4*Math.cos(x4+x5-x1)+(.2d*x5*x5-x2)-1;
  }

  /**
   * Gets the Allele Set for the Problem
   * @return GeneticAlleleSet: The Allele Set
   */
  public GeneticAlleleSet getAlleleSet()
  {
    GeneticAlleleSet gas = new GeneticAlleleSet();
    Double[] values = new Double[] {new Double(-80d), new Double(1d), new Double(80d)};
    gas.addContinuousAllele("Double [-80, 80] by 1", values, 5);
    return gas;
  }

  /**
   * Gets the Objective Type
   * @return int: The Objective Type
   */
  public int getObjectiveType()
    {return OBJECTIVE_TYPE_MIN;}

  /**
   * Main for Running the Problem
   * @param args Not Used
   */
  public static final void main(String[] args)
  {
    GeneticEngine ge = new GeneticEngine();
    GeneticRunTask grt = ge.createGeneticTask(new MultiVarMin());
    grt.getConfig().setShowGenerationResults(true);
    grt.getConfig().setShowFinalReport(true);
    grt.run();
  }
}
