org.um.feri.ears.problems.Task.java Source code

Java tutorial

Introduction

Here is the source code for org.um.feri.ears.problems.Task.java

Source

package org.um.feri.ears.problems;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.ArrayUtils;
import org.um.feri.ears.experiment.ee.so.PSOoriginalLogging;
import org.um.feri.ears.graphing.recording.GraphDataRecorder;

/**
* Task is main class, for communication between algorithm and problem  
* <p>
* 
* @author Matej Crepinsek
* @version 1
* 
*          <h3>License</h3>
* 
*          Copyright (c) 2011 by Matej Crepinsek. <br>
*          All rights reserved. <br>
* 
*          <p>
*          Redistribution and use in source and binary forms, with or without
*          modification, are permitted provided that the following conditions
*          are met:
*          <ul>
*          <li>Redistributions of source code must retain the above copyright
*          notice, this list of conditions and the following disclaimer.
*          <li>Redistributions in binary form must reproduce the above
*          copyright notice, this list of conditions and the following
*          disclaimer in the documentation and/or other materials provided with
*          the distribution.
*          <li>Neither the name of the copyright owners, their employers, nor
*          the names of its contributors may be used to endorse or promote
*          products derived from this software without specific prior written
*          permission.
*          </ul>
*          <p>
*          THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*          "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*          LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*          FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*          COPYRIGHT OWNERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*          INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*          BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*          LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*          CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*          LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
*          ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*          POSSIBILITY OF SUCH DAMAGE.
* 
*/
public class Task extends TaskBase<Problem> {

    /**
     * @param stop the stopping criteria
     * @param eval the maximum number of evaluations allowed
     * @param allowedTime the maximum CPU time allowed in milliseconds
     * @param epsilon the epsilon value for global optimum
     * @param p the problem
     */

    public Task(EnumStopCriteria stop, int eval, long allowedTime, int maxIterations, double epsilon, Problem p) {
        this(stop, eval, allowedTime, maxIterations, epsilon, p, (int) Math.log10((1. / epsilon) + 1));
    }

    public Task(EnumStopCriteria stop, int eval, long allowedTime, int maxIterations, double epsilon, Problem p,
            int precisonOfRealNumbers) {
        precisionOfRealNumbersInDecimalPlaces = precisonOfRealNumbers;
        stopCriteria = stop;
        maxEvaluations = eval;
        numberOfEvaluations = 0;
        this.epsilon = epsilon;
        this.maxIterations = maxIterations;
        isStop = false;
        isGlobal = false;
        this.p = p;
        this.allowedCPUTime = TimeUnit.MILLISECONDS.toNanos(allowedTime);

        // set initial best eval
        bestEval = p.isMinimum() ? Double.MAX_VALUE : Double.MIN_VALUE;
    }

    public double[] getInterval() {
        double interval[] = new double[p.upperLimit.size()];
        for (int i = 0; i < interval.length; i++) {
            interval[i] = p.upperLimit.get(i) - p.lowerLimit.get(i);
        }
        return interval;
    }

    public DoubleSolution getRandomSolution() throws StopCriteriaException {

        if (stopCriteria == EnumStopCriteria.EVALUATIONS) {
            incEvaluate();
            long start = System.nanoTime();
            DoubleSolution tmpSolution = p.getRandomSolution();
            evaluationTime += System.nanoTime() - start;
            checkIfGlobalReached(tmpSolution.getEval());
            GraphDataRecorder.AddRecord(tmpSolution, this.getProblemName());
            if (isAncestorLogginEnabled) {
                tmpSolution.timeStamp = System.currentTimeMillis();
                tmpSolution.generationNumber = this.getNumberOfIterations();
                tmpSolution.evaluationNumner = this.getNumberOfEvaluations();
                ancestors.add(tmpSolution);
                /*ancestorSB.append(tmpSolution.getID()+";"+tmpSolution.getEval()+";"+Arrays.toString(tmpSolution.getDoubleVariables())+";");
                ancestorSB.append("\n");*/
            }

            return tmpSolution;
        } else if (stopCriteria == EnumStopCriteria.GLOBAL_OPTIMUM_OR_EVALUATIONS) {
            if (isGlobal)
                throw new StopCriteriaException("Global optimum already found");
            incEvaluate();
            long start = System.nanoTime();
            DoubleSolution tmpSolution = p.getRandomSolution();
            evaluationTime += System.nanoTime() - start;
            checkIfGlobalReached(tmpSolution.getEval());
            GraphDataRecorder.AddRecord(tmpSolution, this.getProblemName());
            if (isAncestorLogginEnabled) {
                ancestors.add(tmpSolution);
                /*ancestorSB.append(tmpSolution.getID()+";"+tmpSolution.getEval()+";"+Arrays.toString(tmpSolution.getDoubleVariables())+";");
                ancestorSB.append("\n");*/
            }
            return tmpSolution;
        } else if (stopCriteria == EnumStopCriteria.ITERATIONS) {
            if (isStop)
                throw new StopCriteriaException("Max iterations");

            incEvaluate();
            long start = System.nanoTime();
            DoubleSolution tmpSolution = p.getRandomSolution();
            evaluationTime += System.nanoTime() - start;
            checkIfGlobalReached(tmpSolution.getEval());
            GraphDataRecorder.AddRecord(tmpSolution, this.getProblemName());
            if (isAncestorLogginEnabled) {
                ancestors.add(tmpSolution);
                /*ancestorSB.append(tmpSolution.getID()+";"+tmpSolution.getEval()+";"+Arrays.toString(tmpSolution.getDoubleVariables())+";");
                ancestorSB.append("\n");*/
            }

            return tmpSolution;
        } else if (stopCriteria == EnumStopCriteria.CPU_TIME) {
            // check if the CPU time is not exceeded yet
            if (!isStop) {
                hasTheCPUTimeBeenExceeded(); // if CPU time is exceed allow last eval
                incEvaluate();
                long start = System.nanoTime();
                DoubleSolution tmpSolution = p.getRandomSolution();
                evaluationTime += System.nanoTime() - start;
                checkIfGlobalReached(tmpSolution.getEval());
                GraphDataRecorder.AddRecord(tmpSolution, this.getProblemName());
                if (isAncestorLogginEnabled) {
                    ancestors.add(tmpSolution);
                    /*ancestorSB.append(tmpSolution.getID()+";"+tmpSolution.getEval()+";"+Arrays.toString(tmpSolution.getDoubleVariables())+";");
                    ancestorSB.append("\n");*/
                }

                return tmpSolution;
            } else {
                throw new StopCriteriaException("CPU Time");
            }
        } else if (stopCriteria == EnumStopCriteria.STAGNATION) {
            if (isStop)
                throw new StopCriteriaException("Solution stagnation");

            incEvaluate();
            long start = System.nanoTime();
            DoubleSolution tmpSolution = p.getRandomSolution();
            evaluationTime += System.nanoTime() - start;
            checkIfGlobalReached(tmpSolution.getEval());
            checkImprovment(tmpSolution.getEval());
            GraphDataRecorder.AddRecord(tmpSolution, this.getProblemName());
            if (isAncestorLogginEnabled) {
                ancestors.add(tmpSolution);
                /*ancestorSB.append(tmpSolution.getID()+";"+tmpSolution.getEval()+";"+Arrays.toString(tmpSolution.getDoubleVariables())+";");
                ancestorSB.append("\n");*/
            }

            return tmpSolution;
        }

        return null;
    }

    public boolean isFirstBetter(DoubleSolution x, DoubleSolution y) {
        return p.isFirstBetter(x.getVariables(), x.getEval(), y.getVariables(), y.getEval());
    }

    /**
     * This function is not ok, because you do not get informations about
     * constrains, etc.. Just value
     *  
     * @see org.um.feri.ears.problems.Task#eval(double[])
     * @deprecated
     * @param ds
     * @return
     * @throws StopCriteriaException
     */
    /*public double justEval(double[] ds) throws StopCriteriaException {
    if (stopCriteria == EnumStopCriteria.EVALUATIONS) {
        incEvaluate();
        return p.eval(ds);
    }
    if (stopCriteria == EnumStopCriteria.GLOBAL_OPTIMUM_OR_EVALUATIONS) {
        if (isGlobal)
            throw new StopCriteriaException("Global optimum already found");
        incEvaluate();
        double d = p.eval(ds);
        if (Math.abs(d - p.getOptimumEval()) <= epsilon) {
            isGlobal = true;
        }
        return d;
    }
    assert false; // Execution should never reach this point!
    return Double.MAX_VALUE; //error
     }*/

    /**
     * with no evaluations just checks
     * if algorithm result is in interval.
     * This is not checking constrains, just basic intervals!  
     * Delegated from Problem!
     * 
     * @param ds vector of possible solution
     * @return
     */
    public boolean areDimensionsInFeasableInterval(Double[] ds) {
        return p.areDimensionsInFeasableInterval(ds);
    }

    /**
     * Better use method eval returns Individual with calculated fitness and constrains
     * @deprecated
     * 
     * @param ds real vector to be evaluated (just calc constraints)
     * @return
     */
    public double[] calcConstrains(Double[] ds) {
        return p.calc_constrains(ds);
    }

    /**
     * Works only for basic interval setting!
     * Sets interval!
     * for example -40<x_i<40 <p>
     * if x_i <-40 -> -40 same for 40!
     * 
     * @param d value
     * @param i index of dimension
     * @return
     */
    public double setFeasible(double d, int i) {
        return p.setFeasible(d, i);
    }

    public double[] setFeasible(double[] d) {
        return p.setFeasible(d);
    }

    public void setFeasible(DoubleSolution sol) {
        sol.variable = p.setFeasible(sol.variable);
    }

    public boolean isFeasible(double x, int d) {

        return p.isFeasble(x, d);
    }

    /**
     * @deprecated
     * @param d
     * @param bestEvalCond
     * @return
     */
    public boolean isFirstBetter(double a, double b) {
        return p.isFirstBetter(a, b);
    }

    public double[] getLowerLimit() {

        double[] target = new double[p.lowerLimit.size()];
        for (int i = 0; i < target.length; i++) {
            target[i] = p.lowerLimit.get(i);
        }
        return target;
    }

    public double[] getUpperLimit() {
        double[] target = new double[p.upperLimit.size()];
        for (int i = 0; i < target.length; i++) {
            target[i] = p.upperLimit.get(i);
        }
        return target;
    }

    public DoubleSolution eval(double[] x) throws StopCriteriaException {

        Double[] ds = ArrayUtils.toObject(x);
        //List<Double> ds = Arrays.asList(inputBoxed);

        if (stopCriteria == EnumStopCriteria.EVALUATIONS) {
            incEvaluate();
            long start = System.nanoTime();
            DoubleSolution tmpSolution = new DoubleSolution(ds, p.eval(ds), p.calc_constrains(ds), p.upperLimit,
                    p.lowerLimit);
            checkIfGlobalReached(tmpSolution.getEval());
            GraphDataRecorder.AddRecord(tmpSolution, this.getProblemName());
            return tmpSolution;
        } else if (stopCriteria == EnumStopCriteria.ITERATIONS) {
            if (isStop)
                throw new StopCriteriaException("Max iterations");
            incEvaluate();
            long start = System.nanoTime();
            DoubleSolution tmpSolution = new DoubleSolution(ds, p.eval(ds), p.calc_constrains(ds), p.upperLimit,
                    p.lowerLimit);
            evaluationTime += System.nanoTime() - start;
            checkIfGlobalReached(tmpSolution.getEval());
            GraphDataRecorder.AddRecord(tmpSolution, this.getProblemName());
            return tmpSolution;
        } else if (stopCriteria == EnumStopCriteria.GLOBAL_OPTIMUM_OR_EVALUATIONS) {
            if (isGlobal)
                throw new StopCriteriaException("Global optimum already found");
            incEvaluate();
            long start = System.nanoTime();
            double d = p.eval(ds);
            evaluationTime += System.nanoTime() - start;
            checkIfGlobalReached(d);
            DoubleSolution tmpSolution = new DoubleSolution(ds, d, p.calc_constrains(ds), p.upperLimit,
                    p.lowerLimit);
            GraphDataRecorder.AddRecord(tmpSolution, this.getProblemName());
            return tmpSolution;
        } else if (stopCriteria == EnumStopCriteria.CPU_TIME) {
            if (!isStop) {
                hasTheCPUTimeBeenExceeded(); // if CPU time is exceed allow last eval
                incEvaluate();
                long start = System.nanoTime();
                DoubleSolution tmpSolution = new DoubleSolution(ds, p.eval(ds), p.calc_constrains(ds), p.upperLimit,
                        p.lowerLimit);
                evaluationTime += System.nanoTime() - start;
                checkIfGlobalReached(tmpSolution.getEval());
                GraphDataRecorder.AddRecord(tmpSolution, this.getProblemName());
                return tmpSolution;
            } else {
                throw new StopCriteriaException("CPU Time");
            }
        } else if (stopCriteria == EnumStopCriteria.STAGNATION) {
            if (isStop)
                throw new StopCriteriaException("Solution stagnation");

            incEvaluate();
            long start = System.nanoTime();
            DoubleSolution tmpSolution = new DoubleSolution(ds, p.eval(ds), p.calc_constrains(ds), p.upperLimit,
                    p.lowerLimit);
            evaluationTime += System.nanoTime() - start;
            checkIfGlobalReached(tmpSolution.getEval());
            checkImprovment(tmpSolution.getEval());
            GraphDataRecorder.AddRecord(tmpSolution, this.getProblemName());
            if (isAncestorLogginEnabled) {
                tmpSolution.timeStamp = System.currentTimeMillis();
                tmpSolution.generationNumber = this.getNumberOfIterations();
                tmpSolution.evaluationNumner = this.getNumberOfEvaluations();
                ancestors.add(tmpSolution);
                /*ancestorSB.append(tmpSolution.getID()+";"+tmpSolution.getEval()+";"+Arrays.toString(tmpSolution.getDoubleVariables())+";");
                ancestorSB.append("\n");*/
            }

            return tmpSolution;
        }

        assert false; // Execution should never reach this point!
        return null; //error
    }

    private void checkIfGlobalReached(double d) {

        if (Math.abs(d - p.getOptimumEval()) <= epsilon) {
            isGlobal = true;
        }

    }

    public DoubleSolution eval(double[] x, List<DoubleSolution> parents) throws StopCriteriaException {

        DoubleSolution tmpSolution = eval(x);

        if (isAncestorLogginEnabled) {
            tmpSolution.parents = parents;
            tmpSolution.timeStamp = System.currentTimeMillis();
            tmpSolution.generationNumber = this.getNumberOfIterations();
            tmpSolution.evaluationNumner = this.getNumberOfEvaluations();
            /*   ancestorSB.append(tmpSolution.getID()+";"+tmpSolution.getEval()+";"+Arrays.toString(tmpSolution.getDoubleVariables())+";[");
               for(int i = 0; i < parents.size(); i++)
               {
                  ancestorSB.append(parents.get(i).getID());
                  if(i+1 < parents.size())
                     ancestorSB.append(",");
               }
                
               ancestorSB.append("]\n");*/
            ancestors.add(tmpSolution);
        }

        return tmpSolution;
    }

    protected void checkImprovment(double eval) {
        if (p.isMinimum()) {
            if (eval < bestEval) {
                bestEval = eval;
                stagnationTrials = 0;
            } else {
                stagnationTrials++;
            }
        } else {
            if (eval > bestEval) {
                bestEval = eval;
                stagnationTrials = 0;
            } else {
                stagnationTrials++;
            }
        }

        if (stagnationTrials >= maxEvaluationsBeforStagnation) {
            isStop = true;
        }
    }

    public static void resetLoggingID() {
        ancestors.clear();
        SolutionBase.resetLoggingID();
    }

    public DoubleSolution eval(DoubleSolution newSolution) throws StopCriteriaException {
        return newSolution = eval(newSolution.getDoubleVariables());
    }

}