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.commons.lang3.time.StopWatch;
39import org.openscience.cdk.io.iterator.IteratingSMILESReader;
41import denoptim.exception.DENOPTIMException;
42import denoptim.exception.ExceptionUtils;
43import denoptim.fitness.FitnessParameters;
44import denoptim.ga.EAUtils.CandidateSource;
45import denoptim.graph.Candidate;
46import denoptim.io.IteratingAtomContainerReader;
47import denoptim.logging.CounterID;
48import denoptim.logging.Monitor;
49import denoptim.programs.RunTimeParameters.ParametersType;
50import denoptim.programs.denovo.GAParameters;
51import denoptim.programs.fragmenter.FragmenterParameters;
52import denoptim.task.FitnessTask;
53import denoptim.task.Task;
54import denoptim.task.TasksBatchManager;
55import denoptim.utils.SizeControlledSet;
131 private Map<FitnessTask,Future<Object>>
futures;
142 private ThreadPoolExecutor
tpe;
153 private Throwable
ex;
165 private final String
NL = System.getProperty(
"line.separator");
184 futures =
new HashMap<FitnessTask,Future<Object>>();
189 TimeUnit.MILLISECONDS,
190 new ArrayBlockingQueue<Runnable>(1));
192 Runtime.getRuntime().addShutdownHook(
new Thread()
201 if (!
tpe.awaitTermination(30, TimeUnit.SECONDS))
205 if (!
tpe.awaitTermination(60, TimeUnit.SECONDS))
210 catch (InterruptedException ie)
216 Thread.currentThread().interrupt();
222 tpe.setRejectedExecutionHandler(
new RejectedExecutionHandler()
225 public void rejectedExecution(Runnable r,
226 ThreadPoolExecutor executor)
231 executor.getQueue().put(r);
233 catch (InterruptedException
ex)
252 StopWatch watch =
new StopWatch();
256 tpe.prestartAllCoreThreads();
267 }
catch (Exception e)
284 String msg =
"Fitness values have negligible standard deviation "
285 +
"(STDDEV=" + String.format(
"%.6f", sdev) +
"). "
286 +
"Abbandoning evolutionary algorithm.";
287 logger.log(Level.SEVERE, msg);
293 int numStag = 0, genId = 1;
296 logger.log(Level.INFO,
"Starting Generation {0}"
299 String txt =
"No change";
309 txt =
"New members introduced";
313 logger.log(Level.SEVERE,
"Exception while running evolutionary"
314 +
"algorithm. Details: " +
NL
319 logger.log(Level.INFO,txt +
" in Generation {0}"
328 "EA stopped while working on generation {0}. " +
NL
329 +
"Reporting data for incomplete generation {0}."
334 "Generation {0}" +
" completed" +
NL
335 +
"----------------------------------------"
336 +
"----------------------------------------"
343 "No change in population over {0} iterations. "
344 +
"Stopping EA." +
NL, numStag);
357 while (!
tpe.awaitTermination(5, TimeUnit.SECONDS))
362 catch (InterruptedException
ex)
370 Collections.sort(population, Collections.reverseOrder());
382 logger.log(Level.INFO,
"Overall time: {0}." +
NL,
387 logger.info(
"DENOPTIM EA run stopped." +
NL);
389 logger.info(
"DENOPTIM EA run completed." +
NL);
406 synchronized (population)
414 Collections.sort(population, Collections.reverseOrder());
440 IteratingSMILESReader.class))
451 }
catch (Exception e1)
462 List<Task> batchOfSyncParallelTasks =
new ArrayList<>();
465 while (iterMolsToFragment.
hasNext())
478 +
"tasks execution.",
ex);
489 batchOfSyncParallelTasks, i,
true,
true);
492 if (batchOfSyncParallelTasks.size()>0)
510 ex.printStackTrace();
520 List<Task> tasks =
new ArrayList<>();
540 synchronized (population)
550 tasks, i,
false,
false);
568 ex.printStackTrace();
583 "Unable to initialize population in {0} attempts."+
NL, i);
586 + i +
" attempts (Population size: " + population.size()
587 +
", tasks batch size: " + tasks.size() +
").");
590 synchronized (population)
593 population.trimToSize();
594 Collections.sort(population, Collections.reverseOrder());
618 List<Task> batchOfSyncParallelTasks,
int attemptsToFillBatch,
619 boolean replaceWorstPopMember,
boolean candidatesOverflow)
622 if (candidate ==
null)
623 return attemptsToFillBatch;
625 candidate.setGeneration(0);
635 return attemptsToFillBatch;
637 }
catch (Exception e) {
639 return attemptsToFillBatch;
649 replaceWorstPopMember);
664 batchOfSyncParallelTasks.add(task);
665 boolean submitBatch =
false;
666 if (!candidatesOverflow)
668 submitBatch = batchOfSyncParallelTasks.size() >= Math.abs(
676 submitBatch = batchOfSyncParallelTasks.size()
688 attemptsToFillBatch = 0;
691 return attemptsToFillBatch;
701 batchOfSyncParallelTasks.clear();
721 List<Candidate> eligibleParents =
new ArrayList<Candidate>();
722 int populationVersion = -1;
724 synchronized (population)
728 eligibleParents.add(c);
733 + eligibleParents.size();
738 populationVersion = population.getVersionID();
742 List<Task> syncronisedTasks =
new ArrayList<>();
765 synchronized (population)
773 Candidate c = population.getCandidateNamed(
id);
776 population.remove(c);
777 eligibleParents.remove(c);
785 synchronized (population)
787 if (population.size() >= newPopSize)
791 File srcOfCandidate =
null;
792 List<Candidate> candidatesToEvaluate =
new ArrayList<>();
802 if (candidate ==
null)
805 candidatesToEvaluate.add(candidate);
809 if (candidatesToEvaluate.size()==0)
814 eligibleParents, population, mnt));
817 eligibleParents, population, mnt));
820 if (candidatesToEvaluate.size()==0)
824 for (
int iSibling=0; iSibling<candidatesToEvaluate.size(); iSibling++)
826 Candidate candidate = candidatesToEvaluate.get(iSibling);
832 if (candidatesToEvaluate.size()>1)
833 sibling = candidatesToEvaluate.get(jSibling);
847 }
catch (Exception e) {
873 syncronisedTasks.add(task);
874 if (syncronisedTasks.size()
875 >= Math.abs(population.size() - newPopSize)
900 dex.printStackTrace();
910 ex.printStackTrace();
925 "Reached maximum number of attempts (" + i +
") to "
926 +
"generate new candidates in generation " + genId +
"."
931 synchronized (population)
933 Collections.sort(population, Collections.reverseOrder());
940 eligibleParents =
null;
941 syncronisedTasks.clear();
944 int newPopulationVersion = -1;
945 synchronized (population)
947 newPopulationVersion = population.getVersionID();
950 return populationVersion != newPopulationVersion;
974 @SuppressWarnings(
"incomplete-switch")
980 List<Candidate> candidates =
new ArrayList<Candidate>();
987 eligibleParents, population, mnt,
settings));
996 candidates.add(candidate);
1004 if (candidate!=
null)
1005 candidates.add(candidate);
1035 @SuppressWarnings(
"incomplete-switch")
1045 List<Candidate> candidates =
new ArrayList<Candidate>();
1051 eligibleParents, population, mnt,
settings));
1058 eligibleParents, population, mnt,
settings);
1061 String provenanceMsg = parent.getGraph().getLocalMsg();
1063 Arrays.asList(parent), mnt,
settings);
1064 if (candidate!=
null)
1068 candidates.add(candidate);
1078 if (candidate!=
null)
1079 candidates.add(candidate);
1111 futures.get(tsk).cancel(
true);
1115 tpe.getQueue().clear();
1125 List<FitnessTask> completed =
new ArrayList<FitnessTask>();
1129 if (t.isCompleted())
1145 boolean foundExceptions =
false;
1150 boolean interrupt =
false;
1151 synchronized (tsk.lock)
1153 if (tsk.foundException())
1155 foundExceptions =
true;
1156 logger.log(Level.SEVERE,
"problems in "
1157 + tsk.toString() +
". ErrorMessage: '"
1158 + tsk.getErrorMessage() +
"'. ExceptionInTask: "
1159 + tsk.getException());
1160 ex = tsk.getException().getCause();
1172 return foundExceptions;
1197 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).