// MultithreadedEvaluator.java // // Author: // Antonio J. Nebro <antonio@lcc.uma.es> // // Copyright (c) 2013 Antonio J. Nebro // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. package jmetal.util.parallel; import jmetal.core.Problem; import jmetal.core.Solution; import jmetal.util.Configuration; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Vector; import java.util.concurrent.*; /** * @author Antonio J. Nebro * Class for evaluating solutions in parallel using threads */ public class MultithreadedEvaluator implements IParallelEvaluator { private int numberOfThreads_ ; private Problem problem_ ; private ExecutorService executor_ ; private Collection<Callable<Solution>> taskList_ ; /** * @author Antonio J. Nebro * Private class representing tasks to evaluate solutions. */ private class EvaluationTask implements Callable<Solution> { private Problem problem_ ; private Solution solution_ ; /** * Constructor * @param problem Problem to solve * @param solution Solution to evaluate */ public EvaluationTask(Problem problem, Solution solution) { problem_ = problem ; solution_ = solution ; } public Solution call() throws Exception { long initTime = System.currentTimeMillis(); problem_.evaluate(solution_) ; problem_.evaluateConstraints(solution_) ; //long estimatedTime = System.currentTimeMillis() - initTime; //System.out.println("Time: "+ estimatedTime) ; return solution_ ; } } /** * Constructor * @param threads */ public MultithreadedEvaluator(int threads) { numberOfThreads_ = threads ; if (threads == 0) numberOfThreads_ = Runtime.getRuntime().availableProcessors() ; else if (threads < 0) { Configuration.logger_.severe("MultithreadedEvaluator: the number of threads" + " cannot be negative number " + threads); } else { numberOfThreads_ = threads ; } } /** * Constructor * @param problem problem to solve */ public void startEvaluator(Problem problem) { executor_ = Executors.newFixedThreadPool(numberOfThreads_) ; System.out.println("Cores: "+ numberOfThreads_) ; taskList_ = null ; problem_ = problem ; } /** * Adds a solution to be evaluated to a list of tasks * @param solution Solution to be evaluated */ public void addSolutionForEvaluation(Solution solution) { if (taskList_ == null) taskList_ = new ArrayList<Callable<Solution>>(); taskList_.add(new EvaluationTask(problem_, solution)) ; } /** * Evaluates a list of solutions * @return A list with the evaluated solutions */ public List<Solution> parallelEvaluation() { List<Future<Solution>> future = null ; try { future = executor_.invokeAll(taskList_); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } List<Solution> solutionList = new Vector<Solution>() ; for(Future<Solution> result : future){ Solution solution = null ; try { solution = result.get(); solutionList.add(solution) ; } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } } taskList_ = null ; return solutionList ; } /** * Shutdown the executor */ public void stopEvaluator() { executor_.shutdown() ; } }