21import static org.junit.jupiter.api.Assertions.assertEquals;
22import static org.junit.jupiter.api.Assertions.assertTrue;
25import java.util.ArrayList;
26import java.util.Arrays;
27import java.util.Collection;
28import java.util.Comparator;
29import java.util.HashMap;
30import java.util.HashSet;
32import java.util.Random;
34import java.util.function.BiFunction;
35import java.util.logging.Logger;
36import java.util.stream.Collectors;
37import java.util.stream.IntStream;
38import java.util.stream.Stream;
40import javax.vecmath.Point3d;
42import org.jgrapht.alg.util.Pair;
43import org.junit.jupiter.api.BeforeAll;
44import org.junit.jupiter.api.Test;
45import org.openscience.cdk.Atom;
46import org.openscience.cdk.DefaultChemObjectBuilder;
47import org.openscience.cdk.PseudoAtom;
48import org.openscience.cdk.interfaces.IAtom;
49import org.openscience.cdk.interfaces.IAtomContainer;
50import org.openscience.cdk.interfaces.IChemObjectBuilder;
51import org.openscience.cdk.silent.Bond;
52import org.openscience.cdk.silent.SilentChemObjectBuilder;
54import denoptim.exception.DENOPTIMException;
55import denoptim.fragspace.FragmentSpace;
56import denoptim.fragspace.FragmentSpaceParameters;
57import denoptim.graph.APClass;
58import denoptim.graph.AttachmentPoint;
59import denoptim.graph.DGraph;
60import denoptim.graph.EmptyVertex;
61import denoptim.graph.Fragment;
62import denoptim.graph.GraphPattern;
63import denoptim.graph.Ring;
64import denoptim.graph.SymmetricVertexes;
65import denoptim.graph.Template;
66import denoptim.graph.Template.ContractLevel;
67import denoptim.graph.Vertex;
68import denoptim.graph.Vertex.BBType;
69import denoptim.graph.rings.RingClosingAttractor;
70import denoptim.graph.rings.RingClosureParameters;
71import denoptim.io.DenoptimIO;
72import denoptim.logging.Monitor;
73import denoptim.molecularmodeling.ThreeDimTreeBuilder;
74import denoptim.programs.denovo.GAParameters;
75import denoptim.utils.GraphUtils;
76import denoptim.utils.Randomizer;
88 IChemObjectBuilder
chemBuilder = DefaultChemObjectBuilder.getInstance();
89 private final Random
rng =
new Random();
112 assertEquals(1, subgraphs.size());
113 DGraph actual = subgraphs.get(0);
134 assertEquals(0, subgraphs.size());
174 BiFunction<String, Boolean, Vertex> vertexSupplier =
195 List<Vertex> vertices = Stream.of(
196 new Pair<>(
"O",
true),
new Pair<>(
"C",
false),
197 new Pair<>(
"Cl",
false),
new Pair<>(
"N",
false),
198 new Pair<>(
"C",
true),
new Pair<>(
"N",
true),
199 new Pair<>(
"C",
true),
new Pair<>(
"O",
false),
200 new Pair<>(
"C",
false),
new Pair<>(
"O",
true),
201 new Pair<>(
"C",
true),
new Pair<>(
"C",
false),
202 new Pair<>(
"N",
true)
203 ).map(p -> vertexSupplier.apply(p.getFirst(), p.getSecond()))
204 .collect(Collectors.toList());
208 List<List<Integer>> edges = Arrays.asList(
210 Arrays.asList(2, 3, 4),
217 Arrays.asList(9, 10),
241 List<List<Integer>> edges)
245 for (
int i = 0; i < edges.size(); i++) {
246 Vertex srcVertex = vertices.get(i);
247 for (Integer adj : edges.get(i)) {
248 Vertex trgVertex = vertices.get(adj);
253 .filter(ap -> ap.getEdgeUser() ==
null)
259 .filter(ap -> ap.getEdgeUser() ==
null)
277 List<List<Vertex>> ringVertices = Stream.of(
278 Arrays.asList(0, 1, 3, 5),
279 Arrays.asList(4, 1, 3, 6),
280 Arrays.asList(6, 3, 5),
281 Arrays.asList(9, 8, 10),
282 Arrays.asList(10, 11, 12))
283 .map(indices -> indices
286 .collect(Collectors.toList())
288 .collect(Collectors.toList());
290 for (List<Vertex> vs : ringVertices) {
302 List<Set<Integer>> keepVertices = Stream.of(
303 Stream.of(0, 1, 3, 4, 5, 6),
304 Stream.of(8, 9, 10, 11, 12))
305 .map(indices -> indices.collect(Collectors.toSet()))
306 .collect(Collectors.toList());
308 List<DGraph> expectedSubgraphs =
new ArrayList<>(2);
309 for (Set<Integer> keepVertex : keepVertices) {
312 Set<Vertex> removeVertices = IntStream
313 .range(0, vertices.size())
314 .filter(i -> !keepVertex.contains(i))
315 .mapToObj(vertices::get)
316 .collect(Collectors.toSet());
318 for (
Vertex removeVertex : removeVertices) {
321 expectedSubgraphs.add(expSubgraph);
324 return new HashSet<>(expectedSubgraphs);
334 IAtomContainer atomContainer =
chemBuilder.newAtomContainer();
336 oxygen.setSymbol(elementSymbol);
337 atomContainer.addAtom(oxygen);
342 for (
int i = 0; i < apCount; i++)
347 }
catch (Throwable t)
357 double precision = 10*10*10*10;
359 (
double) (Math.round(
rng.nextDouble() * precision)) / precision,
360 (
double) (Math.round(
rng.nextDouble() * precision)) / precision,
361 (
double) (Math.round(
rng.nextDouble() * precision)) / precision
377 new ArrayList<>(),
true);
379 new ArrayList<>(),
true);
381 List<EmptyVertex> vertices = Arrays.asList(v1, rcv1, rcv2);
395 Arrays.asList(rcv1, v1, rcv2)));
410 gA.sameAs(gB,
new StringBuilder()) ? 0 : -1;
431 unmatchedGraphs = unmatchedGraphs
434 .collect(Collectors.toSet());
441 return unmatchedGraphs.size() == 0;
460 String k =
"Uniquefier";
468 List<ContractLevel> contracts =
new ArrayList<ContractLevel>();
473 List<Integer> expectedNumberOfSites =
new ArrayList<Integer>();
474 expectedNumberOfSites.add(17);
475 expectedNumberOfSites.add(12);
476 expectedNumberOfSites.add(10);
478 List<Set<String>> expectedInvariants =
new ArrayList<Set<String>>();
480 Set<String> invariantFREEContract =
new HashSet<String>();
481 invariantFREEContract.add(
""+
GraphUtils.
getLabel(graphA,1)+
"_"+
GraphUtils.
getLabel(graphA,4)+
"_"+
GraphUtils.
getLabel(graphA,2)+
"_"+
GraphUtils.
getLabel(graphA,3)+
"_"+
GraphUtils.
getLabel(graphA,5)+
"_"+
"@@@_"+
GraphUtils.
getLabel(graphB,1)+
"_"+
GraphUtils.
getLabel(graphB,5)+
"_"+
GraphUtils.
getLabel(graphB,2)+
"_"+
GraphUtils.
getLabel(graphB,3)+
"_"+
GraphUtils.
getLabel(graphB,4)+
"_");
498 expectedInvariants.add(invariantFREEContract);
499 Set<String> invariantFIXED_STRUCTContract =
new HashSet<String>();
500 invariantFIXED_STRUCTContract.add(
""+
GraphUtils.
getLabel(graphA,1)+
"_"+
GraphUtils.
getLabel(graphA,4)+
"_"+
GraphUtils.
getLabel(graphA,2)+
"_"+
GraphUtils.
getLabel(graphA,3)+
"_"+
GraphUtils.
getLabel(graphA,5)+
"_"+
"@@@_"+
GraphUtils.
getLabel(graphB,1)+
"_"+
GraphUtils.
getLabel(graphB,5)+
"_"+
GraphUtils.
getLabel(graphB,2)+
"_"+
GraphUtils.
getLabel(graphB,3)+
"_"+
GraphUtils.
getLabel(graphB,4)+
"_");
512 expectedInvariants.add(invariantFIXED_STRUCTContract);
513 Set<String> invariantFIXEDContract =
new HashSet<String>();
514 invariantFIXEDContract.add(
""+
GraphUtils.
getLabel(graphA,1)+
"_"+
GraphUtils.
getLabel(graphA,4)+
"_"+
GraphUtils.
getLabel(graphA,2)+
"_"+
GraphUtils.
getLabel(graphA,3)+
"_"+
GraphUtils.
getLabel(graphA,5)+
"_"+
"@@@_"+
GraphUtils.
getLabel(graphB,1)+
"_"+
GraphUtils.
getLabel(graphB,5)+
"_"+
GraphUtils.
getLabel(graphB,2)+
"_"+
GraphUtils.
getLabel(graphB,3)+
"_"+
GraphUtils.
getLabel(graphB,4)+
"_");
524 expectedInvariants.add(invariantFIXEDContract);
526 for (
int i=0; i<contracts.size(); i++)
531 List<XoverSite> xoverSites =
535 assertEquals(expectedNumberOfSites.get(i), xoverSites.size());
543 boolean writeCode =
false;
546 String varName =
"invariant" + contracts.get(i) +
"Contract";
547 System.out.println(
"Set<String> " + varName +
" = new HashSet<String>();");
554 if (v.getGraphOwner()==graphA)
556 else if (v.getGraphOwner()==graphB)
559 g =
"t1.getInnerGraph()";
561 g =
"t2.getInnerGraph()";
565 s = s +
"+GraphUtils.getLabel("+g+
","+v.getGraphOwner().
indexOf(v)+
")+\"_\"";
571 if (v.getGraphOwner()==graphA)
573 else if (v.getGraphOwner()==graphB)
576 g =
"t1.getInnerGraph()";
578 g =
"t2.getInnerGraph()";
582 s = s +
"+GraphUtils.getLabel("+g+
","+v.getGraphOwner().
indexOf(v)+
")+\"_\"";
584 System.out.println(varName +
".add("+s+
");");
586 System.out.println(
"expectedInvariants.add("+varName+
");");
592 for (
Vertex v : site.getA())
595 v.getGraphOwner().indexOf(v)) +
"_";
597 label = label +
"@@@_";
598 for (
Vertex v : site.getB())
601 v.getGraphOwner().indexOf(v)) +
"_";
603 assertTrue(expectedInvariants.get(i).contains(label),
604 "For contract " + i +
" (" + contracts.get(i)
605 +
") - Missing label: "+label);
827 HashMap<APClass,ArrayList<APClass>> cpMap =
828 new HashMap<APClass,ArrayList<APClass>>();
829 ArrayList<APClass> lstA =
new ArrayList<APClass>();
831 cpMap.put(
APCA, lstA);
832 ArrayList<APClass> lstB =
new ArrayList<APClass>();
835 cpMap.put(
APCB, lstB);
836 ArrayList<APClass> lstC =
new ArrayList<APClass>();
838 cpMap.put(
APCC, lstC);
839 ArrayList<APClass> lstD =
new ArrayList<APClass>();
841 cpMap.put(
APCD, lstD);
843 HashMap<APClass,APClass> capMap =
new HashMap<APClass,APClass>();
844 HashSet<APClass> forbEnds =
new HashSet<APClass>();
848 new ArrayList<Vertex>(),
849 new ArrayList<Vertex>(),
850 new ArrayList<Vertex>(),
851 cpMap, capMap, forbEnds, cpMap);
873 IAtomContainer iacO =
chemBuilder.newAtomContainer();
874 IAtom aO =
new Atom(
"O",
new Point3d(0,0,0));
877 vO.
addAP(0,
new Point3d(0,-1,0), apc);
878 vO.
addAP(0,
new Point3d(2,0,0), apc);
879 vO.
addAP(0,
new Point3d(0,1,0), apc);
881 IAtomContainer iacC =
chemBuilder.newAtomContainer();
882 IAtom aC =
new Atom(
"C",
new Point3d(0,0,0));
885 vC.
addAP(0,
new Point3d(0,-1,0), apc);
886 vC.
addAP(0,
new Point3d(2,0,0), apc);
887 vC.
addAP(0,
new Point3d(0,1,0), apc);
889 IAtomContainer iacCd =
chemBuilder.newAtomContainer();
890 IAtom aCd =
new Atom(
"C",
new Point3d(0,0,0));
893 vC2.
addAP(0,
new Point3d(0,-1,0), apc);
894 vC2.
addAP(0,
new Point3d(0,1,0), apc);
905 IAtomContainer iacN =
chemBuilder.newAtomContainer();
906 IAtom aN =
new Atom(
"N",
new Point3d(0,0,0));
909 vN.
addAP(0,
new Point3d(0,-1,0), apc);
910 vN.
addAP(0,
new Point3d(2,0,0), apc);
911 vN.
addAP(0,
new Point3d(0,1,0), apc);
915 IAtomContainer iacD =
chemBuilder.newAtomContainer();
917 new Point3d(0,0,0)));
919 rcvM.
addAP(0,
new Point3d(-1,0,0), atMinus);
927 IAtomContainer iacE =
chemBuilder.newAtomContainer();
929 new Point3d(0,0,0)));
931 rcvP.
addAP(0,
new Point3d(-1,0,0), atPlus);
950 HashMap<APClass,ArrayList<APClass>> cpMap =
951 new HashMap<APClass,ArrayList<APClass>>();
952 ArrayList<APClass> lstA =
new ArrayList<APClass>();
954 cpMap.put(apc, lstA);
957 new ArrayList<Vertex>(),
958 new ArrayList<Vertex>(),
959 new ArrayList<Vertex>(),
961 new HashMap<APClass,APClass>(),
962 new HashSet<APClass>(),
968 List<Integer> biases =
new ArrayList<Integer>();
1001 Atom ac1 =
new Atom(
"C",
new Point3d());
1003 vC1.
addAP(0,
APCB,
new Point3d(1.1, 0.0, 0.0));
1004 vC1.
addAP(0,
APCB,
new Point3d(1.1, 1.0, 0.0));
1005 vC1.
addAP(0,
APCB,
new Point3d(1.1, 1.0, 2.0));
1006 vC1.
addAP(0,
APCB,
new Point3d(1.1,-1.0, 2.0));
1009 Atom ac31 =
new Atom(
"C",
new Point3d(0.0, 2.0, 0.0));
1010 Atom ac32 =
new Atom(
"C",
new Point3d(0.0, 0.0, 2.0));
1011 Atom ac33 =
new Atom(
"C",
new Point3d(0.0, 0.0, 0.0));
1015 vC3.
addBond(
new Bond(ac31, ac32));
1016 vC3.
addBond(
new Bond(ac32, ac33));
1017 vC3.
addBond(
new Bond(ac33, ac31));
1018 vC3.
addAP(0,
APCA,
new Point3d(0.0, 2.0, -1.0));
1019 vC3.
addAP(1,
APCA,
new Point3d(-1.0,-1.0, 3.0));
1020 vC3.
addAP(1,
APCA,
new Point3d(1.0, -1.0, 3.0));
1021 vC3.
addAP(2,
APCA,
new Point3d(-1.0,-1.0, 1.0));
1022 vC3.
addAP(2,
APCA,
new Point3d(1.0, -1.0, 1.0));
1025 Atom acl =
new Atom(
"Cl",
new Point3d());
1027 vCl.
addAP(0,
APCB,
new Point3d(1.1, 0.0, 0.0));
1030 Atom aN =
new Atom(
"N",
new Point3d());
1032 vN.
addAP(0,
APCB,
new Point3d(1.1, 0.0, 0.0));
1033 vN.
addAP(0,
APCA,
new Point3d(1.1, 1.0, 0.0));
1034 vN.
addAP(0,
APCB,
new Point3d(1.1, 1.0, 2.0));
1036 ArrayList<Vertex> fragments =
new ArrayList<Vertex>();
1089 HashMap<APClass,ArrayList<APClass>> cpMap =
1090 new HashMap<APClass,ArrayList<APClass>>();
1091 ArrayList<APClass> lstA =
new ArrayList<APClass>();
1093 cpMap.put(
APCA, lstA);
1094 ArrayList<APClass> lstB =
new ArrayList<APClass>();
1096 cpMap.put(
APCB, lstB);
1100 new ArrayList<Vertex>(),
1102 new ArrayList<Vertex>(),
1104 new HashMap<APClass,APClass>(),
1105 new HashSet<APClass>(),
1106 new HashMap<
APClass,ArrayList<APClass>>());
Class defining a space of building blocks.
void setAPclassBasedApproach(boolean useAPC)
Set the fragment space to behave according to APClass-based approach.
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 extendGraph(Vertex curVertex, boolean extend, boolean symmetryOnAps, GAParameters settings)
function that will keep extending the graph according to the growth/substitution probability.
static boolean addRing(Vertex vertex, Monitor mnt, boolean force, FragmentSpace fragSpace, GAParameters settings)
Tries to use any free AP of the given vertex to close ring in the graph by adding a chord.
DGraph[] getPairOfTestGraphs()
Generates a pair of graphs that include templates with free content.
void testExtractPattern_singleRingSystem()
IChemObjectBuilder chemBuilder
Set< DGraph > getExpectedSubgraphs(DGraph graph)
Vertex buildFragment(String elementSymbol, int apCount, boolean isRCV)
void testExtractPattern_returnsEmptyListIfNoRings()
void testExtractPattern_fusedRings()
Point3d getRandomVector()
FragmentSpace prepare()
Sets the compatibility matrix (src -> trg);.
void testLocateCompatibleXOverPoints()
void addRings(List< Vertex > vertices, DGraph g)
DGraph getThreeCycle()
Returns a 3-cycle.
static APClass DEFAULT_APCLASS
DGraph buildGraph(List< Vertex > vertices, List< List< Integer > > edges)
ExtractPatternCase getFusedRings()
Returns a molecule consisting of two pairs of fused rings connected by an oxygen atom.
This class collects the data identifying the subgraphs that would be swapped by a crossover event.
static final APClass RCACLASSPLUS
Conventional class of attachment points on ring-closing vertexes.
static final APClass RCACLASSMINUS
Conventional class of attachment points on ring-closing vertexes.
static APClass make(String ruleAndSubclass)
Creates an APClass if it does not exist already, or returns the reference to the existing instance.
An attachment point (AP) is a possibility to attach a Vertex onto the vertex holding the AP (i....
Container for the list of vertices and the edges that connect them.
int getSymmetricSetCount()
Returns the number of symmetric sets of vertices.
Vertex getSourceVertex()
Identifies and return the vertex from which the spanning tree originates.
void removeRing(Ring ring)
void addVertex(Vertex vertex)
Appends a vertex to this graph without creating any edge.
void removeVertex(Vertex vertex)
Remove a vertex from this graph.
int indexOf(Vertex v)
Returns the index of a vertex in the list of vertices of this graph.
Vertex getVertexAtPosition(int pos)
Returns the vertex that is in the given position of the list of vertices belonging to this graph.
static void setScaffold(Vertex v)
Update the graph so that the vertex argument is at the scaffold level i.e.
void appendVertexOnAP(AttachmentPoint srcAP, AttachmentPoint trgAP)
Append a vertex to this graph: adds the new vertex to the list of vertices belonging to the graph,...
List< Vertex > getVertexList()
static boolean compareGraphNodes(Vertex thisV, DGraph thisG, Vertex otherV, DGraph otherG)
Compares graphs by spanning vertices starting from the given vertex and following the direction of ed...
DGraph clone()
Returns almost "deep-copy" of this graph.
List< DGraph > extractPattern(GraphPattern pattern)
Extracts subgraphs that match the provided pattern.
void renumberGraphVertices()
Reassign vertex IDs to all vertices of this graph.
List< Vertex > getSymVerticesForVertex(Vertex v)
void addSymmetricSetOfVertices(SymmetricVertexes symSet)
Adds a symmetric set of vertices to this graph.
An empty vertex has the behaviors of a vertex, but has no molecular structure.
void addAP()
Adds an attachment point with no APClass or other attribute.
Class representing a continuously connected portion of chemical object holding attachment points.
void addAP(int atomPositionNumber)
Adds an attachment point with a dummy APClass.
Fragment clone()
Returns a deep copy of this fragments.
This class represents the closure of a ring in a spanning tree.
void addVertex(Vertex v)
Append a DENOPTIMVertex to the list.
A collection of Vertexs that are related by a relation that we call "symmetry", even though this clas...
void setInnerGraph(DGraph innerGraph)
void setContractLevel(ContractLevel contract)
Imposes the given contract to this template.
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
void setVertexId(long vertexId2)
void setAsRCV(boolean isRCV)
abstract List< AttachmentPoint > getAttachmentPoints()
void setUniquefyingProperty(String key)
Add the given key among the properties that are checked for equality when comparing vertices with the...
void setProperty(Object key, Object property)
AttachmentPoint getAP(int i)
Get attachment point i on this vertex.
The RingClosingAttractor represent the available valence/connection that allows to close a ring.
static final HashMap< APClass, String > RCALABELPERAPCLASS
Conventional labels for attractor pseudoatom.
Parameters and setting related to handling ring closures.
void setRingSizeBias(List< Integer > biases)
Sets the preference for certain ring sizes or the prohibition to generate certain rings (i....
A collection of counters user to count actions taken by the evolutionary algorithm.
void setParameters(RunTimeParameters otherParams)
Parameters for genetic algorithm.
static synchronized long getUniqueVertexIndex()
Unique counter for the number of graph vertices generated.
static String getLabel(Vertex v)
Enum specifying to what extent the template's inner graph can be changed.
FREE
Inner graphs are free to change within the confines of the required AttachmentPoints.
FIXED
Inner graphs are effectively equivalent to the Fragment class, as no change in the inner structure is...
FIXED_STRUCT
Inner graph keep the same structure, but the identify of vertices can change.
The type of building block.