$darkmode
DENOPTIM
GeneOpsRunner.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2019 Marco Foscato <marco.foscato@uib.no>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19package denoptim.programs.genetweeker;
20
21import java.io.File;
22import java.util.ArrayList;
23import java.util.HashSet;
24import java.util.List;
25import java.util.Set;
26import java.util.logging.Level;
27import java.util.logging.Logger;
28
29import org.openscience.cdk.interfaces.IAtomContainer;
30
31import denoptim.constants.DENOPTIMConstants;
32import denoptim.exception.DENOPTIMException;
33import denoptim.fragspace.FragmentSpace;
34import denoptim.fragspace.FragmentSpaceParameters;
35import denoptim.ga.EAUtils;
36import denoptim.ga.GraphOperations;
37import denoptim.ga.XoverSite;
38import denoptim.graph.DGraph;
39import denoptim.graph.Template;
40import denoptim.graph.Vertex;
41import denoptim.graph.rings.RingClosureParameters;
42import denoptim.io.DenoptimIO;
43import denoptim.logging.CounterID;
44import denoptim.logging.Monitor;
45import denoptim.molecularmodeling.ThreeDimTreeBuilder;
46import denoptim.programs.RunTimeParameters.ParametersType;
47import denoptim.programs.denovo.GAParameters;
48import denoptim.task.ProgramTask;
49import denoptim.utils.CrossoverType;
50import denoptim.utils.MutationType;
51
59public class GeneOpsRunner extends ProgramTask
60{
61
66
71
76
80 private Logger logger = null;
81
82//------------------------------------------------------------------------------
83
89 public GeneOpsRunner(File configFile, File workDir)
90 {
91 super(configFile,workDir);
92 }
93
94//------------------------------------------------------------------------------
95
96 @Override
97 public void runProgram() throws Throwable
98 {
100 goParams.readParameterFile(configFilePathName.getAbsolutePath());
101 goParams.checkParameters();
102 goParams.processParameters();
103 goParams.startProgramSpecificLogger(loggerIdentifier, false); //to STDOUT
104 goParams.printParameters();
105
106 this.logger = goParams.getLogger();
107 this.settings = goParams;
110 {
113 }
114 this.fragSpace = fsParams.getFragmentSpace();
116 {
117 this.gaParams = (GAParameters) settings.getParameters(
119 } else {
120 this.gaParams = new GAParameters();
121 }
122
123 switch (goParams.operatorToTest)
124 {
125 case CROSSOVER:
126 runXOver();
127 break;
128 case XOVER:
129 runXOver();
130 break;
131 case MUTATION:
132 runMutation();
133 break;
134 }
135 }
136
137//------------------------------------------------------------------------------
138
139 private void runMutation() throws DENOPTIMException
140 {
141 DGraph graph = null;
142 try
143 {
145 new File(settings.inpFileM)).get(0);
146 } catch (Exception e)
147 {
148 e.printStackTrace();
149 }
150
151 logger.log(Level.INFO, "Initial graphs: " + NL + graph.toString() + NL);
153
154 //Just in case we used some keyword to set something that affects
155 //mutation operations
158 {
161 }
163 {
166 }
168 {
171 }
172
173 boolean done = false;
174 if (mt != null)
175 {
177 graph, "mutation " + mt);
178
179 if (v == null)
180 {
181 List<Vertex> mutable = graph.getSelectedMutableSites(mt);
182 if (mutable.size()==0)
183 {
184 logger.log(Level.INFO, "Graph has no mutable site of type '"
185 + mt + "'. Mutation aborted.");
186 return;
187 }
189 logger.log(Level.INFO, "Randomly choosed vertex as target "
190 + "for mutation '" + mt + "': " + v);
191 }
192
193 int apID = settings.idNewAP;
194 if (mt==MutationType.ADDLINK)
195 {
196 apID = settings.idTargetAP;
197 if (apID<0)
198 throw new DENOPTIMException("ID of target AP is negative. "
199 + "For mutation " + mt + " you should specify also "
200 + "the index of the AP on the mutation target as "
201 + "TESTGENOPS-APIDONTARGETVERTEX.");
202 }
203
205
206 // NB: last boolean asks to ignore the growth probability
207 done = GraphOperations.performMutation(v, mt, true,
208 settings.idNewVrt, apID, new Monitor(), gaParams);
209 } else {
210 logger.log(Level.INFO, "Attempting mutation a random mutation on a "
211 + "random vertex");
212 done = GraphOperations.performMutation(graph, new Monitor(), gaParams);
213 }
214
215 if (done)
216 {
217 logger.log(Level.INFO, "Result of mutation:" + NL + graph.toString()+NL);
218 }
222 IAtomContainer iac = t3d.convertGraphTo3DAtomContainer(graph, true);
224 }
225
226//------------------------------------------------------------------------------
227
228 private void runXOver() throws DENOPTIMException
229 {
230 DGraph male = null;
231 DGraph female = null;
232 try
233 {
235 new File(settings.inpFileM)).get(0);
237 new File(settings.inpFileF)).get(0);
238 } catch (Exception e)
239 {
240 e.printStackTrace();
241 return;
242 }
243
244 logger.log(Level.INFO, "Initial graphs: "+NL
245 +"MALE: "+male+NL
246 +"FEMALE: "+female);
247
248 // Identify the crossover operation to perform
249 XoverSite xos = null;
250 if (settings.xoverSrcMale!=null && settings.xoverSrcFemale!=null)
251 {
253 male, "crossover");
255 female, "crossover");
256
258 if (settings.xoverSubGraphEndMale.size()!=0)
259 xoverType = CrossoverType.SUBGRAPH;
260
261 List<Vertex> subGraphA = new ArrayList<Vertex>();
262 subGraphA.add(vm);
263 male.getChildTreeLimited(vm, subGraphA, getSubGraphEnds(male,
264 settings.xoverSubGraphEndMale, "crossover"));
265 List<Vertex> subGraphB = new ArrayList<Vertex>();
266 subGraphB.add(vf);
267 female.getChildTreeLimited(vf, subGraphB, getSubGraphEnds(female,
268 settings.xoverSubGraphEndFemale, "crossover"));
269
270 xos = new XoverSite(subGraphA, subGraphB, xoverType);
271
272 // Ensure uniqueness on vertexID
274 female.renumberGraphVertices();
275
276 logger.log(Level.INFO,NL+"Initial graphs now with unique vertexID: "
277 +NL+ "v: "+ vm.getVertexId() + " of MALE: " + male
278 +NL+ "v:" + vf.getVertexId() + " of FEMALE: " + female);
279 } else {
280 logger.log(Level.INFO, "Attempting crossover on a site detected "
281 + "on-the-fly");
282 List<XoverSite> sites = GraphOperations.locateCompatibleXOverPoints(
284 if (sites.isEmpty())
285 {
286 logger.log(Level.WARNING, "No crossover site detected.");
287 return;
288 } else {
289 logger.log(Level.INFO, "Randombly choosing among "
290 + sites.size() + " xover sites.");
291 }
293 }
294
296
297 logger.log(Level.INFO, NL + "Result of crossover:"
298 + NL + "MALE: " + male
299 + NL + "FEMALE: " + female);
300
304 IAtomContainer iacM = t3d.convertGraphTo3DAtomContainer(male, true);
305 IAtomContainer iacF = t3d.convertGraphTo3DAtomContainer(female, true);
308 }
309
310//------------------------------------------------------------------------------
311
312 private Set<Vertex> getSubGraphEnds(DGraph graph,
313 List<int[]> embeddingPaths, String operation)
314 {
315 Set<Vertex> result = new HashSet<Vertex>();
316 for (int[] embeddingPath : embeddingPaths)
317 {
318 result.add(getEmbeddedVertex(embeddingPath, graph, operation));
319 }
320 return result;
321 }
322
323//------------------------------------------------------------------------------
324
325 private Vertex getEmbeddedVertex(int[] embeddingPath,
326 DGraph graph, String operation)
327 {
328 String str = "";
329 if (embeddingPath != null && embeddingPath.length>1)
330 {
331 for (int i=(embeddingPath.length-1); i>-1; i--)
332 {
333 if (i==embeddingPath.length-1)
334 {
335 str = "[" + embeddingPath[i] + "]";
336 } else {
337 str = "[" + str + " " + embeddingPath[i] + "] ";
338 }
339 }
340 logger.log(Level.INFO, "Attempting '" + operation + "' on deep "
341 + "vertex " + str);
342 Vertex outerVertex = null;
343 DGraph innerGraph = graph;
344 for (int i=0; i<embeddingPath.length; i++)
345 {
346 if (outerVertex != null && outerVertex instanceof Template)
347 {
348 innerGraph = ((Template) outerVertex).getInnerGraph();
349 }
350 outerVertex = innerGraph.getVertexWithId(embeddingPath[i]);
351 if (outerVertex == null)
352 {
353 logger.log(Level.INFO, "VertexID '" + embeddingPath[i] +
354 "' not found in graph " + innerGraph);
355 return null;
356 }
357 }
358 return outerVertex;
359 } else {
360 if (embeddingPath==null)
361 {
362 logger.log(Level.INFO, "No mutation site specified.");
363 return null;
364 }
365 int vid = embeddingPath[0];
366 logger.log(Level.INFO, "Attempting '" + operation + "' on vertex "
367 + embeddingPath[0]);
368 Vertex v = graph.getVertexWithId(vid);
369 if (v == null)
370 {
371 logger.log(Level.INFO, "VertexID '" + vid + "' not found in "
372 + "graph " + graph);
373 return null;
374 }
375 return v;
376 }
377 }
378
379//------------------------------------------------------------------------------
380
381}
General set of constants used in DENOPTIM.
static final Object STOREDVID
Key of the property remembering vertex IDs.
Class defining a space of building blocks.
Parameters defining the fragment space.
Collection of operators meant to alter graphs and associated utilities.
static List< XoverSite > locateCompatibleXOverPoints(DGraph graphA, DGraph graphB, FragmentSpace fragSpace, int maxSizeXoverSubGraph)
Identify crossover sites, i.e., subgraphs that can be swapped between two graphs (i....
static boolean performMutation(DGraph graph, Monitor mnt, GAParameters settings)
Tries to do mutate the given graph.
static boolean performCrossover(XoverSite site, FragmentSpace fragSpace)
Performs the crossover that swaps the two subgraphs defining the given XoverSite.
This class collects the data identifying the subgraphs that would be swapped by a crossover event.
Definition: XoverSite.java:36
Container for the list of vertices and the edges that connect them.
Definition: DGraph.java:102
Vertex getVertexWithId(long vid)
Searches for a vertex with the given identifier.
Definition: DGraph.java:2811
void renumberGraphVertices()
Reassign vertex IDs to all vertices of this graph.
Definition: DGraph.java:5512
void getChildTreeLimited(Vertex vertex, List< Vertex > children, boolean stopBeforeRCVs)
Gets all the children of the current vertex recursively.
Definition: DGraph.java:3257
List< Vertex > getSelectedMutableSites(MutationType requestedType)
A list of mutation sites from within this graph.
Definition: DGraph.java:6905
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
Definition: Vertex.java:62
void setProperty(Object key, Object property)
Definition: Vertex.java:1236
Parameters and setting related to handling ring closures.
Utility methods for input/output.
static void writeSDFFile(String fileName, IAtomContainer mol)
Writes IAtomContainer to SDF file.
static ArrayList< DGraph > readDENOPTIMGraphsFromFile(File inFile)
Reads a list of DGraphs from file.
A collection of counters user to count actions taken by the evolutionary algorithm.
Definition: Monitor.java:37
Tool to build build three-dimensional (3D) tree-like molecular structures from DGraph.
IAtomContainer convertGraphTo3DAtomContainer(DGraph graph)
Created a three-dimensional molecular representation from a given DGraph.
Logger startProgramSpecificLogger(String loggerIdentifier)
Starts a logger with the given name.
boolean containsParameters(ParametersType type)
void setParameters(RunTimeParameters otherParams)
RunTimeParameters getParameters(ParametersType type)
void readParameterFile(String infile)
Read the parameter TXT file line by line and interpret its content.
Logger getLogger()
Get the name of the program specific logger.
void printParameters()
Print all parameters.
Randomizer getRandomizer()
Returns the current program-specific randomizer.
Parameters for genetic algorithm.
int maxXOverableSubGraphSize
Limit to the size of subgraphs that are exchanged during crossover.
Tool to run genetic operations in a stand-alone fashion, i.e., outside of a genetic algorithm run.
Set< Vertex > getSubGraphEnds(DGraph graph, List< int[]> embeddingPaths, String operation)
GeneOpsRunnerParameters settings
Settings from input parameters.
Vertex getEmbeddedVertex(int[] embeddingPath, DGraph graph, String operation)
FragmentSpace fragSpace
Fragment space in use.
GeneOpsRunner(File configFile, File workDir)
Creates and configures the program task.
GAParameters gaParams
Parameters for genetic algorithm.
Logger logger
Program-specific logger.
Parameters controlling execution of TestOperator.
List< int[]> xoverSubGraphEndFemale
Female VertedID (not index) that represent the end of the subgraph that is swapped by crossover.
List< int[]> xoverSubGraphEndMale
Male VertedID (not index) that represent the end of the subgraph that is swapped by crossover.
int[] xoverSrcFemale
Female VertexID (not index) on which perform xover.
int idTargetAP
Target attachment point ID for mutation (AP belonging already to the graph).
void checkParameters()
Evaluate consistency of input parameters.
void processParameters()
Processes all parameters and initialize related objects.
MutationType mutationType
Type of mutation to perform.
int[] xoverSrcMale
Male VertedID (not index) on which perform xover.
Task structure for any of the main programs in the denoptim project, such as genetic algorithm and co...
String loggerIdentifier
Identifier of this program's logger.
File configFilePathName
File containing configuration parameters for the program task.
File workDir
The file system location where we want to be placed when doing the work.
Definition: Task.java:78
final String NL
System-dependent line separator (newline)
Definition: Task.java:93
public< T > T randomlyChooseOne(Collection< T > c)
Chooses one member among the given collection.
FS_PARAMS
Parameters pertaining the definition of the fragment space.
GA_PARAMS
Parameters pertaining the genetic algorithm.
RC_PARAMS
Parameters pertaining to ring closures in graphs.
Types of crossover defined.
SUBGRAPH
Swaps a portion of a branch trying to retain cyclicity.
BRANCH
Swaps the entire branch starting from a given vertex.
Types of mutation defined in relation to what happens to the target vertex (i.e., the actual mutation...
ADDLINK
Adds a vertex between two previously connected vertexes.