$darkmode
DENOPTIM
GraphOperationsTest.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2022 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.ga;
20
21import static org.junit.jupiter.api.Assertions.assertEquals;
22import static org.junit.jupiter.api.Assertions.assertTrue;
23
24import java.io.File;
25import java.util.ArrayList;
26import java.util.Arrays;
27import java.util.Collection;
28import java.util.Comparator;
29import java.util.HashMap;
30import java.util.HashSet;
31import java.util.List;
32import java.util.Random;
33import java.util.Set;
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;
39
40import javax.vecmath.Point3d;
41
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;
53
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;
77
84public class GraphOperationsTest {
85
86 private static APClass APCA, APCB, APCC, APCD;
87
88 IChemObjectBuilder chemBuilder = DefaultChemObjectBuilder.getInstance();
89 private final Random rng = new Random();
90 private static APClass DEFAULT_APCLASS;
91
92//------------------------------------------------------------------------------
93
94 @BeforeAll
95 static void setUpClass() {
96 try {
97 DEFAULT_APCLASS = APClass.make("norule:0");
98 } catch (DENOPTIMException e) {
99 e.printStackTrace();
100 }
101 }
102
103//------------------------------------------------------------------------------
104
105 @Test
106 public void testExtractPattern_singleRingSystem() throws Throwable
107 {
108 DGraph g = getThreeCycle();
109
110 List<DGraph> subgraphs = g.extractPattern(GraphPattern.RING);
111
112 assertEquals(1, subgraphs.size());
113 DGraph actual = subgraphs.get(0);
114 DGraph expected = g;
115
116 assertEquals(expected.getVertexCount(), actual.getVertexCount());
117 assertEquals(expected.getEdgeCount(), actual.getEdgeCount());
118 assertEquals(1, actual.getRingCount());
119
120 assertTrue(DGraph.compareGraphNodes(expected.getSourceVertex(),
121 expected, actual.getSourceVertex(), actual));
122 }
123
124//------------------------------------------------------------------------------
125
126 @Test
128 throws Throwable
129 {
130 DGraph g = getThreeCycle();
131 g.removeRing(g.getRings().get(0));
132 List<DGraph> subgraphs = g.extractPattern(GraphPattern.RING);
133
134 assertEquals(0, subgraphs.size());
135 }
136
137//------------------------------------------------------------------------------
138
139 @Test
140 public void testExtractPattern_fusedRings() throws Throwable
141 {
143
144 List<DGraph> subgraphs = testCase.g.extractPattern(GraphPattern.RING);
145
146 assertTrue(testCase.matchesExpected(subgraphs));
147 }
148
149//------------------------------------------------------------------------------
150
172 private ExtractPatternCase getFusedRings() throws Throwable
173 {
174 BiFunction<String, Boolean, Vertex> vertexSupplier =
175 (s, isRCV) -> {
176 int apCount = 0;
177 switch (s) {
178 case "Cl":
179 apCount = 1;
180 break;
181 case "O":
182 apCount = 2;
183 break;
184 case "N":
185 apCount = 3;
186 break;
187 case "C":
188 apCount = 4;
189 break;
190 }
191 return buildFragment(s, apCount, isRCV);
192 };
193
194 /* We label the vertices in order of top left to bottom right. */
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());
205
206 /* Here we specify the connections between atoms. Previously
207 connected vertices are not connected twice. Chords are not connected. */
208 List<List<Integer>> edges = Arrays.asList(
209 Arrays.asList(1),
210 Arrays.asList(2, 3, 4),
211 Arrays.asList(),
212 Arrays.asList(5, 6),
213 Arrays.asList(),
214 Arrays.asList(),
215 Arrays.asList(7),
216 Arrays.asList(8),
217 Arrays.asList(9, 10),
218 Arrays.asList(),
219 Arrays.asList(11),
220 Arrays.asList(12)
221 );
222
223 DGraph g = null;
224 try
225 {
226 g = buildGraph(vertices, edges);
227 } catch (DENOPTIMException e)
228 {
229 e.printStackTrace();
230 }
232 DGraph.setScaffold(vertices.get(0));
233 addRings(vertices, g);
234 Set<DGraph> expectedSubgraphs = getExpectedSubgraphs(g);
235 return new ExtractPatternCase(g, 2, expectedSubgraphs);
236 }
237
238//------------------------------------------------------------------------------
239
240 private DGraph buildGraph(List<Vertex> vertices,
241 List<List<Integer>> edges)
242 throws DENOPTIMException {
243 DGraph g = new DGraph();
244 g.addVertex(vertices.get(0));
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);
249
250 AttachmentPoint srcAP = srcVertex
252 .stream()
253 .filter(ap -> ap.getEdgeUser() == null)
254 .findFirst()
255 .get();
256 AttachmentPoint trgAP = trgVertex
258 .stream()
259 .filter(ap -> ap.getEdgeUser() == null)
260 .findFirst()
261 .get();
262
263 try {
264 g.appendVertexOnAP(srcAP, trgAP);
265 } catch (DENOPTIMException e) {
266 // Should not happen
267 e.printStackTrace();
268 }
269 }
270 }
271 return g;
272 }
273
274//------------------------------------------------------------------------------
275
276 private void addRings(List<Vertex> vertices, DGraph g) {
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
284 .stream()
285 .map(vertices::get)
286 .collect(Collectors.toList())
287 )
288 .collect(Collectors.toList());
289
290 for (List<Vertex> vs : ringVertices) {
291 Ring r = new Ring();
292 for (Vertex v : vs) {
293 r.addVertex(v);
294 }
295 g.addRing(r);
296 }
297 }
298
299//------------------------------------------------------------------------------
300
301 private Set<DGraph> getExpectedSubgraphs(DGraph graph) {
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());
307
308 List<DGraph> expectedSubgraphs = new ArrayList<>(2);
309 for (Set<Integer> keepVertex : keepVertices) {
310 DGraph expSubgraph = graph.clone();
311 List<Vertex> vertices = expSubgraph.getVertexList();
312 Set<Vertex> removeVertices = IntStream
313 .range(0, vertices.size())
314 .filter(i -> !keepVertex.contains(i))
315 .mapToObj(vertices::get)
316 .collect(Collectors.toSet());
317
318 for (Vertex removeVertex : removeVertices) {
319 expSubgraph.removeVertex(removeVertex);
320 }
321 expectedSubgraphs.add(expSubgraph);
322 }
323
324 return new HashSet<>(expectedSubgraphs);
325 }
326
327//------------------------------------------------------------------------------
328
329 private Vertex buildFragment(String elementSymbol, int apCount,
330 boolean isRCV)
331 {
332 try
333 {
334 IAtomContainer atomContainer = chemBuilder.newAtomContainer();
335 IAtom oxygen = chemBuilder.newAtom();
336 oxygen.setSymbol(elementSymbol);
337 atomContainer.addAtom(oxygen);
338
339 Fragment v = new Fragment(
340 GraphUtils.getUniqueVertexIndex(), atomContainer,
341 BBType.FRAGMENT, isRCV);
342 for (int i = 0; i < apCount; i++)
343 {
345 }
346 return v;
347 } catch (Throwable t)
348 {
349 return null;
350 }
351 }
352
353//------------------------------------------------------------------------------
354
355 private Point3d getRandomVector()
356 {
357 double precision = 10*10*10*10;
358 return new Point3d(
359 (double) (Math.round(rng.nextDouble() * precision)) / precision,
360 (double) (Math.round(rng.nextDouble() * precision)) / precision,
361 (double) (Math.round(rng.nextDouble() * precision)) / precision
362 );
363 }
364
365//------------------------------------------------------------------------------
366
374 {
375 EmptyVertex v1 = new EmptyVertex(0);
376 EmptyVertex rcv1 = new EmptyVertex(1, new ArrayList<>(),
377 new ArrayList<>(), true);
378 EmptyVertex rcv2 = new EmptyVertex(2, new ArrayList<>(),
379 new ArrayList<>(), true);
380
381 List<EmptyVertex> vertices = Arrays.asList(v1, rcv1, rcv2);
382 for (EmptyVertex v : vertices) {
383 v.setBuildingBlockType(BBType.FRAGMENT);
384 v.addAP();
385 }
386 // Need an additional AP on v1
387 v1.addAP();
388
389 DGraph g = new DGraph();
390 g.addVertex(v1);
391 g.appendVertexOnAP(v1.getAP(0), rcv1.getAP(0));
392 g.appendVertexOnAP(v1.getAP(1), rcv2.getAP(0));
393
394 Ring r = new Ring(new ArrayList<>(
395 Arrays.asList(rcv1, v1, rcv2)));
396 g.addRing(r);
397
399 return g;
400 }
401
402//------------------------------------------------------------------------------
403
404 private static final class ExtractPatternCase
405 {
406 final DGraph g;
407 final int expectedSize;
408 final Set<DGraph> expectedGraphs;
409 final Comparator<DGraph> graphComparator = (gA, gB) ->
410 gA.sameAs(gB, new StringBuilder()) ? 0 : -1;
411
413 Set<DGraph> expectedGraphs) {
414 this.g = g;
415 this.expectedSize = expectedSize;
416 this.expectedGraphs = expectedGraphs;
417 }
418
419 private boolean matchesExpected(Collection<DGraph> actuals) {
420 if (actuals.size() != expectedSize) {
421 return false;
422 }
423
424 Set<DGraph> unmatchedGraphs = new HashSet<>(expectedGraphs);
425 for (DGraph g : actuals)
426 {
427 boolean hasMatch = expectedGraphs
428 .stream()
429 .anyMatch(exp -> graphComparator.compare(g, exp) == 0);
430 if (hasMatch) {
431 unmatchedGraphs = unmatchedGraphs
432 .stream()
433 .filter(exp -> graphComparator.compare(g, exp) != 0)
434 .collect(Collectors.toSet());
435 } else {
436 return false;
437 }
438 }
439
440 // Check that no graphs are missing from actual
441 return unmatchedGraphs.size() == 0;
442 }
443 }
444
445//------------------------------------------------------------------------------
446
447 @Test
448 public void testLocateCompatibleXOverPoints() throws Exception
449 {
450 FragmentSpace fragSpace = prepare();
451 DGraph[] pair = getPairOfTestGraphs();
452 DGraph graphA = pair[0];
453 DGraph graphB = pair[1];
454
455 Template t1 = (Template) graphA.getVertexAtPosition(1);
456 Template t2 = (Template) graphB.getVertexAtPosition(1);
457 // Making some empty vertexes unique to enable swapping (otherwise they
458 // are seen as the same node and excluded from xover sites list)
460 String k = "Uniquefier";
462 v5A.setProperty(k, "123");
465 v3B.setProperty(k, "789");
466
467 // Prepare the input and expected output
468 List<ContractLevel> contracts = new ArrayList<ContractLevel>();
469 contracts.add(ContractLevel.FREE);
470 contracts.add(ContractLevel.FIXED_STRUCT);
471 contracts.add(ContractLevel.FIXED);
472
473 List<Integer> expectedNumberOfSites = new ArrayList<Integer>();
474 expectedNumberOfSites.add(17);
475 expectedNumberOfSites.add(12); // Only two allowed xovers
476 expectedNumberOfSites.add(10); // No crossover inside template
477
478 List<Set<String>> expectedInvariants = new ArrayList<Set<String>>();
479 // This code is generated by this very method. See below.
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)+"_");
482 invariantFREEContract.add(""+GraphUtils.getLabel(graphA,1)+"_"+GraphUtils.getLabel(graphA,4)+"_"+GraphUtils.getLabel(graphA,2)+"_"+GraphUtils.getLabel(graphA,5)+"_"+"@@@_"+GraphUtils.getLabel(graphB,1)+"_"+GraphUtils.getLabel(graphB,5)+"_"+GraphUtils.getLabel(graphB,2)+"_");
483 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,2)+"_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
484 invariantFREEContract.add(""+GraphUtils.getLabel(graphA,1)+"_"+GraphUtils.getLabel(graphA,4)+"_"+GraphUtils.getLabel(graphA,2)+"_"+GraphUtils.getLabel(graphA,5)+"_"+"@@@_"+GraphUtils.getLabel(graphB,2)+"_");
485 invariantFREEContract.add(""+GraphUtils.getLabel(graphA,2)+"_"+GraphUtils.getLabel(graphA,3)+"_"+"@@@_"+GraphUtils.getLabel(graphB,1)+"_"+GraphUtils.getLabel(graphB,5)+"_"+GraphUtils.getLabel(graphB,2)+"_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
486 invariantFREEContract.add(""+GraphUtils.getLabel(graphA,2)+"_"+"@@@_"+GraphUtils.getLabel(graphB,1)+"_"+GraphUtils.getLabel(graphB,5)+"_"+GraphUtils.getLabel(graphB,2)+"_");
487 invariantFREEContract.add(""+GraphUtils.getLabel(graphA,2)+"_"+GraphUtils.getLabel(graphA,3)+"_"+"@@@_"+GraphUtils.getLabel(graphB,2)+"_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
488 invariantFREEContract.add(""+GraphUtils.getLabel(graphA,3)+"_"+"@@@_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
489 invariantFREEContract.add(""+GraphUtils.getLabel(graphA,5)+"_"+"@@@_"+GraphUtils.getLabel(graphB,1)+"_"+GraphUtils.getLabel(graphB,5)+"_"+GraphUtils.getLabel(graphB,2)+"_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
490 invariantFREEContract.add(""+GraphUtils.getLabel(graphA,5)+"_"+"@@@_"+GraphUtils.getLabel(graphB,2)+"_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
491 invariantFREEContract.add(""+GraphUtils.getLabel(t1.getInnerGraph(),2)+"_"+GraphUtils.getLabel(t1.getInnerGraph(),3)+"_"+"@@@_"+GraphUtils.getLabel(t2.getInnerGraph(),1)+"_"+GraphUtils.getLabel(t2.getInnerGraph(),2)+"_"+GraphUtils.getLabel(t2.getInnerGraph(),3)+"_");
492 invariantFREEContract.add(""+GraphUtils.getLabel(t1.getInnerGraph(),2)+"_"+"@@@_"+GraphUtils.getLabel(t2.getInnerGraph(),1)+"_"+GraphUtils.getLabel(t2.getInnerGraph(),2)+"_");
493 invariantFREEContract.add(""+GraphUtils.getLabel(t1.getInnerGraph(),2)+"_"+GraphUtils.getLabel(t1.getInnerGraph(),3)+"_"+"@@@_"+GraphUtils.getLabel(t2.getInnerGraph(),2)+"_"+GraphUtils.getLabel(t2.getInnerGraph(),3)+"_");
494 invariantFREEContract.add(""+GraphUtils.getLabel(t1.getInnerGraph(),2)+"_"+"@@@_"+GraphUtils.getLabel(t2.getInnerGraph(),2)+"_");
495 invariantFREEContract.add(""+GraphUtils.getLabel(t1.getInnerGraph(),3)+"_"+"@@@_"+GraphUtils.getLabel(t2.getInnerGraph(),3)+"_");
496 invariantFREEContract.add(""+GraphUtils.getLabel(t1.getInnerGraph(),4)+"_"+GraphUtils.getLabel(t1.getInnerGraph(),5)+"_"+"@@@_"+GraphUtils.getLabel(t2.getInnerGraph(),3)+"_");
497 invariantFREEContract.add(""+GraphUtils.getLabel(t1.getInnerGraph(),5)+"_"+"@@@_"+GraphUtils.getLabel(t2.getInnerGraph(),3)+"_");
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)+"_");
501 invariantFIXED_STRUCTContract.add(""+GraphUtils.getLabel(graphA,1)+"_"+GraphUtils.getLabel(graphA,4)+"_"+GraphUtils.getLabel(graphA,2)+"_"+GraphUtils.getLabel(graphA,5)+"_"+"@@@_"+GraphUtils.getLabel(graphB,1)+"_"+GraphUtils.getLabel(graphB,5)+"_"+GraphUtils.getLabel(graphB,2)+"_");
502 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,2)+"_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
503 invariantFIXED_STRUCTContract.add(""+GraphUtils.getLabel(graphA,1)+"_"+GraphUtils.getLabel(graphA,4)+"_"+GraphUtils.getLabel(graphA,2)+"_"+GraphUtils.getLabel(graphA,5)+"_"+"@@@_"+GraphUtils.getLabel(graphB,2)+"_");
504 invariantFIXED_STRUCTContract.add(""+GraphUtils.getLabel(graphA,2)+"_"+GraphUtils.getLabel(graphA,3)+"_"+"@@@_"+GraphUtils.getLabel(graphB,1)+"_"+GraphUtils.getLabel(graphB,5)+"_"+GraphUtils.getLabel(graphB,2)+"_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
505 invariantFIXED_STRUCTContract.add(""+GraphUtils.getLabel(graphA,2)+"_"+"@@@_"+GraphUtils.getLabel(graphB,1)+"_"+GraphUtils.getLabel(graphB,5)+"_"+GraphUtils.getLabel(graphB,2)+"_");
506 invariantFIXED_STRUCTContract.add(""+GraphUtils.getLabel(graphA,2)+"_"+GraphUtils.getLabel(graphA,3)+"_"+"@@@_"+GraphUtils.getLabel(graphB,2)+"_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
507 invariantFIXED_STRUCTContract.add(""+GraphUtils.getLabel(graphA,3)+"_"+"@@@_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
508 invariantFIXED_STRUCTContract.add(""+GraphUtils.getLabel(graphA,5)+"_"+"@@@_"+GraphUtils.getLabel(graphB,1)+"_"+GraphUtils.getLabel(graphB,5)+"_"+GraphUtils.getLabel(graphB,2)+"_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
509 invariantFIXED_STRUCTContract.add(""+GraphUtils.getLabel(graphA,5)+"_"+"@@@_"+GraphUtils.getLabel(graphB,2)+"_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
510 invariantFIXED_STRUCTContract.add(""+GraphUtils.getLabel(t1.getInnerGraph(),3)+"_"+"@@@_"+GraphUtils.getLabel(t2.getInnerGraph(),3)+"_");
511 invariantFIXED_STRUCTContract.add(""+GraphUtils.getLabel(t1.getInnerGraph(),5)+"_"+"@@@_"+GraphUtils.getLabel(t2.getInnerGraph(),3)+"_");
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)+"_");
515 invariantFIXEDContract.add(""+GraphUtils.getLabel(graphA,1)+"_"+GraphUtils.getLabel(graphA,4)+"_"+GraphUtils.getLabel(graphA,2)+"_"+GraphUtils.getLabel(graphA,5)+"_"+"@@@_"+GraphUtils.getLabel(graphB,1)+"_"+GraphUtils.getLabel(graphB,5)+"_"+GraphUtils.getLabel(graphB,2)+"_");
516 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,2)+"_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
517 invariantFIXEDContract.add(""+GraphUtils.getLabel(graphA,1)+"_"+GraphUtils.getLabel(graphA,4)+"_"+GraphUtils.getLabel(graphA,2)+"_"+GraphUtils.getLabel(graphA,5)+"_"+"@@@_"+GraphUtils.getLabel(graphB,2)+"_");
518 invariantFIXEDContract.add(""+GraphUtils.getLabel(graphA,2)+"_"+GraphUtils.getLabel(graphA,3)+"_"+"@@@_"+GraphUtils.getLabel(graphB,1)+"_"+GraphUtils.getLabel(graphB,5)+"_"+GraphUtils.getLabel(graphB,2)+"_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
519 invariantFIXEDContract.add(""+GraphUtils.getLabel(graphA,2)+"_"+"@@@_"+GraphUtils.getLabel(graphB,1)+"_"+GraphUtils.getLabel(graphB,5)+"_"+GraphUtils.getLabel(graphB,2)+"_");
520 invariantFIXEDContract.add(""+GraphUtils.getLabel(graphA,2)+"_"+GraphUtils.getLabel(graphA,3)+"_"+"@@@_"+GraphUtils.getLabel(graphB,2)+"_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
521 invariantFIXEDContract.add(""+GraphUtils.getLabel(graphA,3)+"_"+"@@@_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
522 invariantFIXEDContract.add(""+GraphUtils.getLabel(graphA,5)+"_"+"@@@_"+GraphUtils.getLabel(graphB,1)+"_"+GraphUtils.getLabel(graphB,5)+"_"+GraphUtils.getLabel(graphB,2)+"_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
523 invariantFIXEDContract.add(""+GraphUtils.getLabel(graphA,5)+"_"+"@@@_"+GraphUtils.getLabel(graphB,2)+"_"+GraphUtils.getLabel(graphB,3)+"_"+GraphUtils.getLabel(graphB,4)+"_");
524 expectedInvariants.add(invariantFIXEDContract);
525
526 for (int i=0; i<contracts.size(); i++)
527 {
528 t1.setContractLevel(contracts.get(i));
529 t2.setContractLevel(contracts.get(i));
530
531 List<XoverSite> xoverSites =
533 fragSpace, 100);
534
535 assertEquals(expectedNumberOfSites.get(i), xoverSites.size());
536
537 // NB: this is code that is unlocked only in development phase to
538 // generate the code that defined the expected invariant.
539 // Here, we exploit the fact that every vertex has a unique label as a
540 // property and the combination of sites generates an invariant.
541 // To generate this labels programmatically the following code is used
542 // but only after having checked manually.
543 boolean writeCode = false; //NB: make this true to generate the code!
544 if (writeCode)
545 {
546 String varName = "invariant" + contracts.get(i) + "Contract";
547 System.out.println("Set<String> " + varName + " = new HashSet<String>();");
548 for (XoverSite x : xoverSites)
549 {
550 String s = "\"\"";
551 for (Vertex v : x.getA())
552 {
553 String g = "";
554 if (v.getGraphOwner()==graphA)
555 g = "graphA";
556 else if (v.getGraphOwner()==graphB)
557 g = "graphB";
558 else if (v.getGraphOwner()==t1.getInnerGraph())
559 g = "t1.getInnerGraph()";
560 else if (v.getGraphOwner()==t2.getInnerGraph())
561 g = "t2.getInnerGraph()";
562 else
563 g = "noGraph";
564
565 s = s + "+GraphUtils.getLabel("+g+","+v.getGraphOwner().indexOf(v)+")+\"_\"";
566 }
567 s = s + "+\"@@@_\"";
568 for (Vertex v : x.getB())
569 {
570 String g = "";
571 if (v.getGraphOwner()==graphA)
572 g = "graphA";
573 else if (v.getGraphOwner()==graphB)
574 g = "graphB";
575 else if (v.getGraphOwner()==t1.getInnerGraph())
576 g = "t1.getInnerGraph()";
577 else if (v.getGraphOwner()==t2.getInnerGraph())
578 g = "t2.getInnerGraph()";
579 else
580 g = "noGraph";
581
582 s = s + "+GraphUtils.getLabel("+g+","+v.getGraphOwner().indexOf(v)+")+\"_\"";
583 }
584 System.out.println(varName + ".add("+s+");");
585 }
586 System.out.println("expectedInvariants.add("+varName+");");
587 }
588
589 for (XoverSite site : xoverSites)
590 {
591 String label = "";
592 for (Vertex v : site.getA())
593 {
594 label = label + GraphUtils.getLabel(v.getGraphOwner(),
595 v.getGraphOwner().indexOf(v)) + "_";
596 }
597 label = label + "@@@_";
598 for (Vertex v : site.getB())
599 {
600 label = label + GraphUtils.getLabel(v.getGraphOwner(),
601 v.getGraphOwner().indexOf(v)) + "_";
602 }
603 assertTrue(expectedInvariants.get(i).contains(label),
604 "For contract " + i + " (" + contracts.get(i)
605 + ") - Missing label: "+label);
606 }
607 }
608 }
609
610//------------------------------------------------------------------------------
611
644 private DGraph[] getPairOfTestGraphs() throws Exception
645 {
646 prepare();
647
648 // Prepare special building block: template T1
649 EmptyVertex v0 = new EmptyVertex(0);
650 v0.addAP(APCA);
651 v0.addAP(APCA);
652 v0.setProperty("Label", "tv0");
653
654 EmptyVertex v1 = new EmptyVertex(1);
655 v1.addAP(APCA);
656 v1.addAP(APCA);
657 v1.addAP(APCB);
658 v1.addAP(APCC);
659 v1.setProperty("Label", "tv1");
660
661 EmptyVertex v2 = new EmptyVertex(2);
662 v2.addAP(APCA);
663 v2.addAP(APCC);
664 v2.setProperty("Label", "tv2");
665
666 EmptyVertex v3 = new EmptyVertex(3);
667 v3.addAP(APCA);
668 v3.addAP(APCA);
669 v3.setProperty("Label", "tv3");
670
671 EmptyVertex v4 = new EmptyVertex(4);
672 v4.addAP(APCA);
673 v4.addAP(APCA);
674 v4.setProperty("Label", "tv4");
675
676 EmptyVertex v5 = new EmptyVertex(5);
677 v5.addAP(APCA);
678 v5.addAP(APCA);
679 v5.setProperty("Label", "tv5");
680
681 DGraph g = new DGraph();
682 g.addVertex(v0);
683 g.setGraphId(-1);
684 g.appendVertexOnAP(v0.getAP(0), v1.getAP(0));
685 g.appendVertexOnAP(v1.getAP(2), v2.getAP(1));
686 g.appendVertexOnAP(v2.getAP(0), v3.getAP(0));
687 g.appendVertexOnAP(v1.getAP(1), v4.getAP(1));
688 g.appendVertexOnAP(v4.getAP(0), v5.getAP(1));
689
690 Template t1 = new Template(BBType.NONE);
691 t1.setInnerGraph(g);
692 t1.setProperty("Label", "t1");
694
695 // Assemble the first graph: graphA
696
697 EmptyVertex m1 = new EmptyVertex(101);
698 m1.addAP(APCA);
699 m1.setProperty("Label", "m101");
700
701 EmptyVertex m2 = new EmptyVertex(102);
702 m2.addAP(APCA);
703 m2.addAP(APCB);
704 m2.setProperty("Label", "m102");
705
706 EmptyVertex m3 = new EmptyVertex(103);
707 m3.addAP(APCB);
708 m3.setProperty("Label", "m103");
709
710 EmptyVertex m4 = new EmptyVertex(104);
711 m4.addAP(APCC);
712 m4.setProperty("Label", "m104");
713
714 EmptyVertex m5 = new EmptyVertex(105);
715 m5.addAP(APCA);
716 m5.setProperty("Label", "m105");
717
718 DGraph graphA = new DGraph();
719 graphA.addVertex(m1);
720 graphA.appendVertexOnAP(m1.getAP(0), t1.getAP(0));
721 graphA.appendVertexOnAP(t1.getAP(2), m2.getAP(0));
722 graphA.appendVertexOnAP(m2.getAP(1), m3.getAP(0));
723 graphA.appendVertexOnAP(t1.getAP(1), m4.getAP(0));
724 graphA.appendVertexOnAP(t1.getAP(3), m5.getAP(0));
725
726 graphA.setGraphId(11111);
727
728 //Prepare special building block: template T2
729 EmptyVertex w1 = new EmptyVertex(11);
730 w1.addAP(APCA);
731 w1.addAP(APCB);
732 w1.addAP(APCC);
733 w1.setProperty("Label", "tw11");
734
735 EmptyVertex w2 = new EmptyVertex(12);
736 w2.addAP(APCB);
737 w2.addAP(APCC);
738 w2.setProperty("Label", "tw12");
739
740 EmptyVertex w3 = new EmptyVertex(13);
741 w3.addAP(APCA);
742 w3.addAP(APCB);
743 w3.setProperty("Label", "tw13");
744
745 EmptyVertex w4 = new EmptyVertex(14);
746 w4.addAP(APCA);
747 w4.addAP(APCA);
748 w4.setProperty("Label", "tw14");
749
750 DGraph g2 = new DGraph();
751 g2.addVertex(w1);
752 g2.appendVertexOnAP(w1.getAP(1), w2.getAP(1));
753 g2.appendVertexOnAP(w2.getAP(0), w3.getAP(1));
754 g2.appendVertexOnAP(w3.getAP(0), w4.getAP(0));
755 g2.setGraphId(-2);
756
757 Template t2 = new Template(BBType.NONE);
758 t2.setInnerGraph(g2);
759 t2.setProperty("Label", "t2");
761
762 // Assemble the second graph: graphB
763
764 EmptyVertex f1 = new EmptyVertex(1001);
765 f1.addAP(APCA);
766 f1.setProperty("Label", "f1001");
767
768 EmptyVertex f2 = new EmptyVertex(1002);
769 f2.addAP(APCA);
770 f2.addAP(APCB);
771 f2.setProperty("Label", "f1002");
772
773 EmptyVertex f3 = new EmptyVertex(1003);
774 f3.addAP(APCB);
775 f3.addAP(APCC);
776 f3.setProperty("Label", "f1003");
777
778 EmptyVertex f4 = new EmptyVertex(1004);
779 f4.addAP(APCC);
780 f4.setProperty("Label", "f1004");
781
782 EmptyVertex f5 = new EmptyVertex(1005);
783 f5.addAP(APCC);
784 f5.setProperty("Label", "f1005");
785
786 DGraph graphB = new DGraph();
787 graphB.addVertex(f1);
788 graphB.appendVertexOnAP(f1.getAP(0), t2.getAP(0));
789 graphB.appendVertexOnAP(t2.getAP(2), f2.getAP(0));
790 graphB.appendVertexOnAP(f2.getAP(1), f3.getAP(0));
791 graphB.appendVertexOnAP(f3.getAP(1), f4.getAP(0));
792 graphB.appendVertexOnAP(t2.getAP(1), f5.getAP(0));
793 graphB.setGraphId(22222);
794
795 DGraph[] pair = new DGraph[2];
796 pair[0] = graphA;
797 pair[1] = graphB;
798
799 return pair;
800 }
801
802//------------------------------------------------------------------------------
803
819 private FragmentSpace prepare() throws Exception
820 {
821 // Prepare APClass compatibility rules
822 APCA = APClass.make("A", 0);
823 APCB = APClass.make("B", 0);
824 APCC = APClass.make("C", 0);
825 APCD = APClass.make("D", 0);
826
827 HashMap<APClass,ArrayList<APClass>> cpMap =
828 new HashMap<APClass,ArrayList<APClass>>();
829 ArrayList<APClass> lstA = new ArrayList<APClass>();
830 lstA.add(APCA);
831 cpMap.put(APCA, lstA);
832 ArrayList<APClass> lstB = new ArrayList<APClass>();
833 lstB.add(APCB);
834 lstB.add(APCC);
835 cpMap.put(APCB, lstB);
836 ArrayList<APClass> lstC = new ArrayList<APClass>();
837 lstC.add(APCC);
838 cpMap.put(APCC, lstC);
839 ArrayList<APClass> lstD = new ArrayList<APClass>();
840 lstD.add(APCD);
841 cpMap.put(APCD, lstD);
842
843 HashMap<APClass,APClass> capMap = new HashMap<APClass,APClass>();
844 HashSet<APClass> forbEnds = new HashSet<APClass>();
845
847 FragmentSpace fs = new FragmentSpace(fsp,
848 new ArrayList<Vertex>(),
849 new ArrayList<Vertex>(),
850 new ArrayList<Vertex>(),
851 cpMap, capMap, forbEnds, cpMap);
853
854 return fs;
855 }
856
857//------------------------------------------------------------------------------
858
859 @Test
860 public void testAddRing() throws Exception
861 {
862 /* This is the graph we work with
863 *
864 * * * * RCV_M
865 * | | | |
866 * RCV_P--[O]----[C]--[C]--[C]--[C]--[C]----[N]--RCV_M
867 * vO vC vC2 vC3 vC4 vC5 vN
868 *
869 */
870
871 APClass apc = APClass.make("A", 0);
872
873 IAtomContainer iacO = chemBuilder.newAtomContainer();
874 IAtom aO = new Atom("O",new Point3d(0,0,0));
875 iacO.addAtom(aO);
876 Fragment vO = new Fragment(0, iacO,BBType.FRAGMENT);
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);
880
881 IAtomContainer iacC = chemBuilder.newAtomContainer();
882 IAtom aC = new Atom("C",new Point3d(0,0,0));
883 iacC.addAtom(aC);
884 Fragment vC = new Fragment(1, iacC,BBType.FRAGMENT);
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);
888
889 IAtomContainer iacCd = chemBuilder.newAtomContainer();
890 IAtom aCd = new Atom("C",new Point3d(0,0,0));
891 iacCd.addAtom(aCd);
892 Fragment vC2 = new Fragment(2, iacCd,BBType.FRAGMENT);
893 vC2.addAP(0, new Point3d(0,-1,0), apc);
894 vC2.addAP(0, new Point3d(0,1,0), apc);
895
896 Fragment vC3 = vC2.clone();
897 vC3.setVertexId(33);
898
899 Fragment vC4 = vC2.clone();
900 vC4.setVertexId(34);
901
902 Fragment vC5 = vC.clone();
903 vC5.setVertexId(3);
904
905 IAtomContainer iacN = chemBuilder.newAtomContainer();
906 IAtom aN = new Atom("N",new Point3d(0,0,0));
907 iacN.addAtom(aN);
908 Fragment vN = new Fragment(4, iacN,BBType.FRAGMENT);
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);
912
913 APClass atMinus = APClass.RCACLASSMINUS;
914
915 IAtomContainer iacD = chemBuilder.newAtomContainer();
916 iacD.addAtom(new PseudoAtom(RingClosingAttractor.RCALABELPERAPCLASS.get(atMinus),
917 new Point3d(0,0,0)));
918 Fragment rcvM = new Fragment(6, iacD,BBType.FRAGMENT);
919 rcvM.addAP(0, new Point3d(-1,0,0), atMinus);
920 rcvM.setAsRCV(true);
921
922 Fragment rcvM2 = rcvM.clone();
923 rcvM2.setVertexId(7);
924
926
927 IAtomContainer iacE = chemBuilder.newAtomContainer();
928 iacE.addAtom(new PseudoAtom(RingClosingAttractor.RCALABELPERAPCLASS.get(atPlus),
929 new Point3d(0,0,0)));
930 Fragment rcvP = new Fragment(8, iacE,BBType.FRAGMENT);
931 rcvP.addAP(0, new Point3d(-1,0,0), atPlus);
932 rcvP.setAsRCV(true);
933
934 DGraph graph = new DGraph();
935 graph.addVertex(vC);
936 graph.appendVertexOnAP(vC.getAP(0), vO.getAP(2));
937 graph.appendVertexOnAP(vO.getAP(1), rcvP.getAP(0));
938 graph.appendVertexOnAP(vC.getAP(2), vC2.getAP(1));
939 graph.appendVertexOnAP(vC2.getAP(0), vC3.getAP(0));
940 graph.appendVertexOnAP(vC3.getAP(1), vC4.getAP(0));
941 graph.appendVertexOnAP(vC4.getAP(1), vC5.getAP(0));
942 graph.appendVertexOnAP(vC5.getAP(2), vN.getAP(0));
943 graph.appendVertexOnAP(vN.getAP(1), rcvM.getAP(0));
944 graph.appendVertexOnAP(vN.getAP(2), rcvM2.getAP(0));
945
946 // Prepare environment to run graph operation. First, a monitor of events
947 Monitor mnt = new Monitor();
948
949 // Then, a fragment space that allows ring closures
950 HashMap<APClass,ArrayList<APClass>> cpMap =
951 new HashMap<APClass,ArrayList<APClass>>();
952 ArrayList<APClass> lstA = new ArrayList<APClass>();
953 lstA.add(apc);
954 cpMap.put(apc, lstA);
956 FragmentSpace fs = new FragmentSpace(fsp,
957 new ArrayList<Vertex>(),
958 new ArrayList<Vertex>(),
959 new ArrayList<Vertex>(),
960 cpMap,
961 new HashMap<APClass,APClass>(),
962 new HashSet<APClass>(),
963 cpMap);
965
966 // Then, settings of ring-closing machinery
968 List<Integer> biases = new ArrayList<Integer>();
969 for (int i=0; i<rcParams.getMaxRingSize(); i++)
970 {
971 biases.add(0); // 0 means ring-closure not allowed
972 }
973 biases.set(5, 1);
974 rcParams.setRingSizeBias(biases);
975
976 // Then, some GA-parameters
977 GAParameters gaParams = new GAParameters();
978 gaParams.setParameters(rcParams);
979
980 // All ready, do the ring-adding mutation
981 assertEquals(0, graph.getRingCount());
982 GraphOperations.addRing(vC5, mnt, true, fs, gaParams);
983 assertEquals(1, graph.getRingCount());
984 }
985
986//------------------------------------------------------------------------------
987
988 /*
989 * Here we test whether the method detects that extension should be done in
990 * all symmetric location, including APs belonging to the same vertex and
991 * outside of it.
992 */
993
994 @Test
995 public void testExtendGraph() throws Exception
996 {
997 APClass APCA = APClass.make("A", 0);
998 APClass APCB = APClass.make("B", 0);
999
1000 Fragment vC1 = new Fragment();
1001 Atom ac1 = new Atom("C", new Point3d());
1002 vC1.addAtom(ac1);
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));
1007
1008 Fragment vC3 = new Fragment();
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));
1012 vC3.addAtom(ac31);
1013 vC3.addAtom(ac32);
1014 vC3.addAtom(ac33);
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));
1023
1024 Fragment vCl = new Fragment();
1025 Atom acl = new Atom("Cl", new Point3d());
1026 vCl.addAtom(acl);
1027 vCl.addAP(0, APCB, new Point3d(1.1, 0.0, 0.0));
1028
1029 Fragment vN = new Fragment();
1030 Atom aN = new Atom("N", new Point3d());
1031 vN.addAtom(aN);
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));
1035
1036 ArrayList<Vertex> fragments = new ArrayList<Vertex>();
1037 fragments.add(vC1);
1038 fragments.add(vC3);
1039 fragments.add(vCl);
1040 fragments.add(vN);
1041
1042 // Use clones of the vertexes to simulate the construction from BBSpace
1043 Vertex cvC1a = vC1.clone();
1044 cvC1a.setVertexId(1);
1045 Vertex cvC1b = vC1.clone();
1046 cvC1b.setVertexId(2);
1047 Vertex cvC3a = vC3.clone();
1048 cvC3a.setVertexId(3);
1049 Vertex cvC3b = vC3.clone();
1050 cvC3b.setVertexId(4);
1051 Vertex cvN = vN.clone();
1052 cvN.setVertexId(0);
1053
1054 /* This is the graph we work with ('*' is a free AP)
1055 *
1056 * * *
1057 * / /
1058 * *-C---C-*
1059 * \ /
1060 * C
1061 * / *
1062 * / /
1063 * N(root)-----C-*
1064 * \ \
1065 * \ *
1066 * C---C-*
1067 * \ / \
1068 * C *
1069 * / \
1070 * *-C *
1071 * / \
1072 * * *
1073 *
1074 */
1075
1076 DGraph graph = new DGraph();
1077 graph.addVertex(cvN);
1078 graph.appendVertexOnAP(cvN.getAP(0), cvC3a.getAP(0));
1079 graph.appendVertexOnAP(cvN.getAP(1), cvC1a.getAP(0));
1080 graph.appendVertexOnAP(cvN.getAP(2), cvC3b.getAP(0));
1081 graph.appendVertexOnAP(cvC3b.getAP(2), cvC1b.getAP(0));
1082 graph.addSymmetricSetOfVertices(new SymmetricVertexes(Arrays.asList(
1083 cvC3a, cvC3b)));
1084
1085 //Logger logger = Logger.getLogger("DummyLogger");
1086 //Randomizer rng = new Randomizer();
1087 //DenoptimIO.writeGraphToSDF(new File("/tmp/graph.sdf"), graph, false, logger, rng);
1088
1089 HashMap<APClass,ArrayList<APClass>> cpMap =
1090 new HashMap<APClass,ArrayList<APClass>>();
1091 ArrayList<APClass> lstA = new ArrayList<APClass>();
1092 lstA.add(APCB);
1093 cpMap.put(APCA, lstA);
1094 ArrayList<APClass> lstB = new ArrayList<APClass>();
1095 lstA.add(APCA);
1096 cpMap.put(APCB, lstB);
1097
1099 FragmentSpace fs = new FragmentSpace(fsParams,
1100 new ArrayList<Vertex>(),
1101 fragments,
1102 new ArrayList<Vertex>(),
1103 cpMap,
1104 new HashMap<APClass,APClass>(),
1105 new HashSet<APClass>(),
1106 new HashMap<APClass,ArrayList<APClass>>());
1107 fs.setAPclassBasedApproach(true);
1108
1109 GAParameters gaParams = new GAParameters();
1110 gaParams.setParameters(fsParams);
1111
1112 assertEquals(5, graph.getVertexCount());
1113
1114 GraphOperations.extendGraph(cvC3a, false, true, true, 2, 0, gaParams);
1115
1116 assertEquals(12, graph.getVertexCount());
1117 assertEquals(2, graph.getSymmetricSetCount());
1118 assertEquals(2, graph.getSymVerticesForVertex(cvC3a).size());
1119 assertEquals(7, graph.getSymVerticesForVertex(
1120 graph.getVertexAtPosition(graph.getVertexCount()-1)).size());
1121 }
1122
1123//------------------------------------------------------------------------------
1124
1125}
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.
boolean matchesExpected(Collection< DGraph > actuals)
ExtractPatternCase(DGraph g, int expectedSize, Set< DGraph > expectedGraphs)
DGraph[] getPairOfTestGraphs()
Generates a pair of graphs that include templates with free content.
Set< DGraph > getExpectedSubgraphs(DGraph graph)
Vertex buildFragment(String elementSymbol, int apCount, boolean isRCV)
FragmentSpace prepare()
Sets the compatibility matrix (src -> trg);.
void addRings(List< Vertex > vertices, DGraph g)
DGraph getThreeCycle()
Returns a 3-cycle.
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.
Definition: XoverSite.java:36
static final APClass RCACLASSPLUS
Conventional class of attachment points on ring-closing vertexes.
Definition: APClass.java:84
static final APClass RCACLASSMINUS
Conventional class of attachment points on ring-closing vertexes.
Definition: APClass.java:91
static APClass make(String ruleAndSubclass)
Creates an APClass if it does not exist already, or returns the reference to the existing instance.
Definition: APClass.java:136
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.
Definition: DGraph.java:102
int getSymmetricSetCount()
Returns the number of symmetric sets of vertices.
Definition: DGraph.java:313
Vertex getSourceVertex()
Identifies and return the vertex from which the spanning tree originates.
Definition: DGraph.java:740
void removeRing(Ring ring)
Definition: DGraph.java:2637
void addVertex(Vertex vertex)
Appends a vertex to this graph without creating any edge.
Definition: DGraph.java:1097
void removeVertex(Vertex vertex)
Remove a vertex from this graph.
Definition: DGraph.java:1119
void setGraphId(int id)
Definition: DGraph.java:258
int indexOf(Vertex v)
Returns the index of a vertex in the list of vertices of this graph.
Definition: DGraph.java:2569
Vertex getVertexAtPosition(int pos)
Returns the vertex that is in the given position of the list of vertices belonging to this graph.
Definition: DGraph.java:2514
static void setScaffold(Vertex v)
Update the graph so that the vertex argument is at the scaffold level i.e.
Definition: DGraph.java:6863
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,...
Definition: DGraph.java:5776
List< Vertex > getVertexList()
Definition: DGraph.java:719
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...
Definition: DGraph.java:3825
DGraph clone()
Returns almost "deep-copy" of this graph.
Definition: DGraph.java:3186
List< DGraph > extractPattern(GraphPattern pattern)
Extracts subgraphs that match the provided pattern.
Definition: DGraph.java:4457
void renumberGraphVertices()
Reassign vertex IDs to all vertices of this graph.
Definition: DGraph.java:5283
List< Vertex > getSymVerticesForVertex(Vertex v)
Definition: DGraph.java:335
List< Ring > getRings()
Definition: DGraph.java:771
void addSymmetricSetOfVertices(SymmetricVertexes symSet)
Adds a symmetric set of vertices to this graph.
Definition: DGraph.java:661
void addRing(Ring ring)
Definition: DGraph.java:1030
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.
Definition: Fragment.java:61
void addAP(int atomPositionNumber)
Adds an attachment point with a dummy APClass.
Definition: Fragment.java:343
void addBond(IBond bond)
Definition: Fragment.java:871
Fragment clone()
Returns a deep copy of this fragments.
Definition: Fragment.java:733
void addAtom(IAtom atom)
Definition: Fragment.java:836
This class represents the closure of a ring in a spanning tree.
Definition: Ring.java:40
void addVertex(Vertex v)
Append a DENOPTIMVertex to the list.
Definition: Ring.java:71
A collection of Vertexs that are related by a relation that we call "symmetry", even though this clas...
void setInnerGraph(DGraph innerGraph)
Definition: Template.java:298
void setContractLevel(ContractLevel contract)
Imposes the given contract to this template.
Definition: Template.java:214
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
Definition: Vertex.java:61
void setVertexId(long vertexId2)
Definition: Vertex.java:261
void setAsRCV(boolean isRCV)
Definition: Vertex.java:254
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...
Definition: Vertex.java:1112
void setProperty(Object key, Object property)
Definition: Vertex.java:1148
AttachmentPoint getAP(int i)
Get attachment point i on this vertex.
Definition: Vertex.java:920
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.
Definition: Monitor.java:37
void setParameters(RunTimeParameters otherParams)
Parameters for genetic algorithm.
Utilities for graphs.
Definition: GraphUtils.java:40
static synchronized long getUniqueVertexIndex()
Unique counter for the number of graph vertices generated.
Definition: GraphUtils.java:97
static String getLabel(Vertex v)
Enum specifying to what extent the template's inner graph can be changed.
Definition: Template.java:104
FREE
Inner graphs are free to change within the confines of the required AttachmentPoints.
Definition: Template.java:109
FIXED
Inner graphs are effectively equivalent to the Fragment class, as no change in the inner structure is...
Definition: Template.java:116
FIXED_STRUCT
Inner graph keep the same structure, but the identify of vertices can change.
Definition: Template.java:124
The type of building block.
Definition: Vertex.java:86