22import java.util.ArrayList;
23import java.util.Arrays;
24import java.util.Collections;
25import java.util.HashMap;
26import java.util.HashSet;
30import java.util.concurrent.ArrayBlockingQueue;
31import java.util.concurrent.Future;
32import java.util.concurrent.RejectedExecutionHandler;
33import java.util.concurrent.ThreadPoolExecutor;
34import java.util.concurrent.TimeUnit;
35import java.util.logging.Level;
36import java.util.logging.Logger;
38import org.apache.bcel.generic.RETURN;
39import org.apache.commons.lang3.time.StopWatch;
40import org.openscience.cdk.io.iterator.IteratingSMILESReader;
42import denoptim.exception.DENOPTIMException;
43import denoptim.exception.ExceptionUtils;
44import denoptim.fitness.FitnessParameters;
45import denoptim.ga.EAUtils.CandidateSource;
46import denoptim.graph.Candidate;
47import denoptim.io.IteratingAtomContainerReader;
48import denoptim.logging.CounterID;
49import denoptim.logging.Monitor;
50import denoptim.programs.RunTimeParameters.ParametersType;
51import denoptim.programs.denovo.GAParameters;
52import denoptim.programs.fragmenter.FragmenterParameters;
53import denoptim.task.FitnessTask;
54import denoptim.task.Task;
55import denoptim.task.TasksBatchManager;
56import denoptim.utils.SizeControlledSet;
132 private Map<FitnessTask,Future<Object>>
futures;
143 private ThreadPoolExecutor
tpe;
154 private Throwable
ex;
166 private final String
NL = System.getProperty(
"line.separator");
185 futures =
new HashMap<FitnessTask,Future<Object>>();
190 TimeUnit.MILLISECONDS,
191 new ArrayBlockingQueue<Runnable>(1));
193 Runtime.getRuntime().addShutdownHook(
new Thread()
202 if (!
tpe.awaitTermination(30, TimeUnit.SECONDS))
206 if (!
tpe.awaitTermination(60, TimeUnit.SECONDS))
211 catch (InterruptedException ie)
217 Thread.currentThread().interrupt();
223 tpe.setRejectedExecutionHandler(
new RejectedExecutionHandler()
226 public void rejectedExecution(Runnable r,
227 ThreadPoolExecutor executor)
232 executor.getQueue().put(r);
234 catch (InterruptedException
ex)
253 StopWatch watch =
new StopWatch();
257 tpe.prestartAllCoreThreads();
268 }
catch (Exception e)
285 String msg =
"Fitness values have negligible standard deviation "
286 +
"(STDDEV=" + String.format(
"%.6f", sdev) +
"). "
287 +
"Abbandoning evolutionary algorithm.";
288 logger.log(Level.SEVERE, msg);
294 int numStag = 0, genId = 1;
297 logger.log(Level.INFO,
"Starting Generation {0}"
300 String txt =
"No change";
310 txt =
"New members introduced";
314 logger.log(Level.SEVERE,
"Exception while running evolutionary"
315 +
"algorithm. Details: " +
NL
320 logger.log(Level.INFO,txt +
" in Generation {0}"
329 "EA stopped while working on generation {0}. " +
NL
330 +
"Reporting data for incomplete generation {0}."
335 "Generation {0}" +
" completed" +
NL
336 +
"----------------------------------------"
337 +
"----------------------------------------"
344 "No change in population over {0} iterations. "
345 +
"Stopping EA." +
NL, numStag);
358 while (!
tpe.awaitTermination(5, TimeUnit.SECONDS))
363 catch (InterruptedException
ex)
371 Collections.sort(population, Collections.reverseOrder());
383 logger.log(Level.INFO,
"Overall time: {0}." +
NL,
388 logger.info(
"DENOPTIM EA run stopped." +
NL);
390 logger.info(
"DENOPTIM EA run completed." +
NL);
407 synchronized (population)
415 Collections.sort(population, Collections.reverseOrder());
441 IteratingSMILESReader.class))
452 }
catch (Exception e1)
463 List<Task> batchOfSyncParallelTasks =
new ArrayList<>();
466 while (iterMolsToFragment.
hasNext())
479 +
"tasks execution.",
ex);
490 batchOfSyncParallelTasks, i,
true,
true);
493 if (batchOfSyncParallelTasks.size()>0)
511 ex.printStackTrace();
521 List<Task> tasks =
new ArrayList<>();
541 synchronized (population)
551 tasks, i,
false,
false);
569 ex.printStackTrace();
584 "Unable to initialize molecules in {0} attempts."+
NL, i);
587 + i +
" attempts (Population size: " + population.size()
588 +
", tasks batch size: " + tasks.size() +
").");
591 synchronized (population)
594 population.trimToSize();
595 Collections.sort(population, Collections.reverseOrder());
619 List<Task> batchOfSyncParallelTasks,
int attemptsToFillBatch,
620 boolean replaceWorstPopMember,
boolean candidatesOverflow)
623 if (candidate ==
null)
624 return attemptsToFillBatch;
626 candidate.setGeneration(0);
636 return attemptsToFillBatch;
638 }
catch (Exception e) {
640 return attemptsToFillBatch;
650 replaceWorstPopMember);
665 batchOfSyncParallelTasks.add(task);
666 boolean submitBatch =
false;
667 if (!candidatesOverflow)
669 submitBatch = batchOfSyncParallelTasks.size() >= Math.abs(
677 submitBatch = batchOfSyncParallelTasks.size()
689 attemptsToFillBatch = 0;
692 return attemptsToFillBatch;
702 batchOfSyncParallelTasks.clear();
722 List<Candidate> eligibleParents =
new ArrayList<Candidate>();
723 int populationVersion = -1;
725 synchronized (population)
729 eligibleParents.add(c);
734 + eligibleParents.size();
739 populationVersion = population.getVersionID();
743 List<Task> syncronisedTasks =
new ArrayList<>();
766 synchronized (population)
774 Candidate c = population.getCandidateNamed(
id);
777 population.remove(c);
778 eligibleParents.remove(c);
786 synchronized (population)
788 if (population.size() >= newPopSize)
792 File srcOfCandidate =
null;
793 List<Candidate> candidatesToEvaluate =
new ArrayList<>();
803 if (candidate ==
null)
806 candidatesToEvaluate.add(candidate);
810 if (candidatesToEvaluate.size()==0)
815 eligibleParents, population, mnt));
818 eligibleParents, population, mnt));
821 if (candidatesToEvaluate.size()==0)
825 for (
int iSibling=0; iSibling<candidatesToEvaluate.size(); iSibling++)
827 Candidate candidate = candidatesToEvaluate.get(iSibling);
833 if (candidatesToEvaluate.size()>1)
834 sibling = candidatesToEvaluate.get(jSibling);
848 }
catch (Exception e) {
874 syncronisedTasks.add(task);
875 if (syncronisedTasks.size()
876 >= Math.abs(population.size() - newPopSize)
901 dex.printStackTrace();
911 ex.printStackTrace();
926 "Reached maximum number of attempts (" + i +
") to "
927 +
"generate new candidates in generation " + genId +
"."
932 synchronized (population)
934 Collections.sort(population, Collections.reverseOrder());
941 eligibleParents =
null;
942 syncronisedTasks.clear();
945 int newPopulationVersion = -1;
946 synchronized (population)
948 newPopulationVersion = population.getVersionID();
951 return populationVersion != newPopulationVersion;
975 @SuppressWarnings(
"incomplete-switch")
981 List<Candidate> candidates =
new ArrayList<Candidate>();
988 eligibleParents, population, mnt,
settings));
997 candidates.add(candidate);
1005 if (candidate!=
null)
1006 candidates.add(candidate);
1036 @SuppressWarnings(
"incomplete-switch")
1046 List<Candidate> candidates =
new ArrayList<Candidate>();
1052 eligibleParents, population, mnt,
settings));
1059 eligibleParents, population, mnt,
settings);
1062 String provenanceMsg = parent.getGraph().getLocalMsg();
1064 Arrays.asList(parent), mnt,
settings);
1065 if (candidate!=
null)
1069 candidates.add(candidate);
1079 if (candidate!=
null)
1080 candidates.add(candidate);
1112 futures.get(tsk).cancel(
true);
1116 tpe.getQueue().clear();
1126 List<FitnessTask> completed =
new ArrayList<FitnessTask>();
1130 if (t.isCompleted())
1146 boolean foundExceptions =
false;
1151 boolean interrupt =
false;
1152 synchronized (tsk.lock)
1154 if (tsk.foundException())
1156 foundExceptions =
true;
1157 logger.log(Level.SEVERE,
"problems in "
1158 + tsk.toString() +
". ErrorMessage: '"
1159 + tsk.getErrorMessage() +
"'. ExceptionInTask: "
1160 + tsk.getException());
1161 ex = tsk.getException().getCause();
1173 return foundExceptions;
1198 for (String pathName : pathNames)
static String getStackTraceAsString(Throwable t)
Prints the stack trace of an exception into a string.
Settings defining the calculation of fitness.
Helper methods for the genetic algorithm.
static void outputFinalResults(Population popln, GAParameters settings)
Saves the final results to disk.
static CandidateSource pickNewCandidateGenerationMode(double xoverWeight, double mutWeight, double newWeight, Randomizer randomizer)
Takes a decision on which CandidateSource method to use for generating a new Candidate.
static Candidate readCandidateFromFile(File srcFile, Monitor mnt, GAParameters settings)
static List< Candidate > buildCandidatesByXOver(List< Candidate > eligibleParents, Population population, Monitor mnt, GAParameters settings)
Generates a pair of new offspring by performing a crossover operation.
static CandidateSource chooseGenerationMethod(GAParameters settings)
Choose one of the methods to make new Candidates.
static Candidate buildCandidateByMutation(List< Candidate > eligibleParents, Monitor mnt, GAParameters settings)
static Candidate buildCandidateByFragmentingMolecule(IAtomContainer mol, Monitor mnt, GAParameters settings, int index)
Generates a candidate by fragmenting a molecule and generating the graph that reconnects all fragment...
static void createFolderForGeneration(int genId, GAParameters settings)
Creates a folder meant to hold all the data generated during a generation.
static void outputPopulationDetails(Population population, String filename, GAParameters settings, boolean printpathNames)
Write out summary for the current GA population.
static String getPathNameToGenerationFolder(int genID, GAParameters settings)
static double getPopulationSD(Population molPopulation)
Check if fitness values have significant standard deviation.
static Candidate buildCandidateFromScratch(Monitor mnt, GAParameters settings)
static String getPathNameToGenerationDetailsFile(int genID, GAParameters settings)
static Population importInitialPopulation(SizeControlledSet uniqueIDsSet, GAParameters settings)
Reads unique identifiers and initial population file according to the GAParameters.
DENOPTIM's evolutionary algorithm.
boolean checkForException()
List< Candidate > makeOffspringA(List< Candidate > eligibleParents, Population population, Monitor mnt)
Generates one offspring according to the method where crossover and mutation are decoupled,...
EvolutionaryAlgorithm(GAParameters settings, ExternalCmdsListener cmdListener)
void cleanupAsync()
Removes all tasks whether they are completed or not.
final ExternalCmdsListener cmdListener
Service watching for external commands.
boolean stopped
Flag signaling this EA was stopped.
int processInitialPopCandidate(Candidate candidate, Population population, Monitor mnt, List< Task > batchOfSyncParallelTasks, int attemptsToFillBatch, boolean replaceWorstPopMember, boolean candidatesOverflow)
List< String > candidatesToAdd
List of IDs of candidates to be evaluated upon request from the user.
boolean evolvePopulation(Population population, int genId)
Generates a given number of new candidate items and adds them to the current population.
void cleanupCompleted()
Removes only tasks that are marked as completed.
void addCandidates(Set< String > pathNames)
Adds candidate IDs to the list of "to-be-included" candidates.
boolean isAsync
Flag determining the use of asynchronous parallelization scheme.
List< FitnessTask > submitted
Temporary storage of fitness evaluation tasks just submitted to asynchronous Parallelization scheme.
TasksBatchManager tbm
Task manager for tasks to be executed as batches.
void submitSyncParallelBatch(List< Task > batchOfSyncParallelTasks)
ThreadPoolExecutor tpe
Execution service used in asynchronous parallelization scheme.
Set< String > candidatesToRemove
List of IDs of candidates to be removed from the population.
SizeControlledSet scs
Storage of unique identifiers encountered by this instance.
Throwable ex
Issue emerging from a thread submitted by asynchronous parallelization scheme.
GAParameters settings
Parameters controlling the execution of this evolutionary algorithm.
void removeCandidates(Set< String > candID)
Adds candidate IDs to the list of "to-be-removed" candidates.
void initializePopulation(Population population)
Fills up the population with candidates build from scratch.
List< Candidate > makeOffspringB(List< Candidate > eligibleParents, Population population, Monitor mnt)
Generates one offspring according to the method where crossover and mutation are coupled,...
Map< FitnessTask, Future< Object > > futures
Temporary storage of future results produced by fitness evaluation tasks submitted to asynchronous pa...
Logger logger
Program-specific logger.
Service that watches the interface folder (i.e., see GAParameters#interfaceDir) for instructions comi...
void setReferenceToRunningEAlgorithm(EvolutionaryAlgorithm ea)
Task that calls the fitness provider for an offspring that can become a member of the current populat...
A collection of candidates.
void trim(int populationSize)
Removes all the elements exceeding the given size.
A candidate is the combination of a denoptim graph with molecular representation and may include also...
void setGeneration(int genId)
void setLocalMsg(String msg)
An iterator that take IAtomContainers from a file, possibly using an available iterating reader,...
Class<?> getIteratorType()
A collection of counters user to count actions taken by the evolutionary algorithm.
void increase(CounterID cid)
void printHeader(String pathName)
boolean containsParameters(ParametersType type)
RunTimeParameters getParameters(ParametersType type)
Logger getLogger()
Get the name of the program specific logger.
Randomizer getRandomizer()
Returns the current program-specific randomizer.
Parameters for genetic algorithm.
double getConstructionWeight()
double getMutationWeight()
int getNumberOfChildren()
boolean dumpMonitor
Flag controlling if we dump monitored data or not.
String getInitMolsToFragmentFile()
int maxUIDMemory
Maximum number of unique identifiers kept in memory.
boolean parentsSurvive
Flag defining if population members can survive multiple generations (when this variable is true) or ...
int getNumberOfConvergenceGenerations()
int getNumberOfGenerations()
String uidMemoryOnDisk
Text file used to store unique identifiers beyond the limits of the memory (see GAParameters#maxUIDMe...
int getReplacementStrategy()
boolean coupleMutationAndCrossover
Flag defining if we want mutation to occur on offspring that result from crossover (i....
int getParallelizationScheme()
double getCrossoverWeight()
Parameters controlling execution of the fragmenter.
void setWorkingIn3D(boolean workingIn3D)
Sets boolean variable workingIn3D.
Task that assesses the fitness of a given graph.
Class that manages the submission of a batch of tasks.
List< Candidate > executeTasks(List< Task > syncronisedTasks, int numOfProcessors)
Execute the list of tasks.
Class meant to collect unique strings without leading to memory overflow.
synchronized boolean addNewUniqueEntry(String entry)
Checks if the given entry is already container in the set of known entries and, if not,...
A chosen method for generation of new Candidates.
FAILEDDUPLICATEPREFITNESSDETECTION
Identifier of the type of parameters.
FRG_PARAMS
Parameters controlling the fragmenter.
FIT_PARAMS
Parameters pertaining the calculation of fitness (i.e., the fitness provider).