$darkmode
DENOPTIM
GraphLinkFinderTest.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.fragspace;
20
21import static org.junit.jupiter.api.Assertions.assertEquals;
22import static org.junit.jupiter.api.Assertions.assertTrue;
23
24import java.util.ArrayList;
25import java.util.Arrays;
26import java.util.HashMap;
27import java.util.HashSet;
28import java.util.LinkedHashMap;
29import java.util.List;
30import java.util.Map;
31import java.util.Map.Entry;
32import java.util.Set;
33
34import org.junit.jupiter.api.Test;
35
36import denoptim.exception.DENOPTIMException;
37import denoptim.graph.APClass;
38import denoptim.graph.APMapping;
39import denoptim.graph.AttachmentPoint;
40import denoptim.graph.DGraph;
41import denoptim.graph.Edge;
42import denoptim.graph.EmptyVertex;
43import denoptim.graph.Vertex;
44import denoptim.graph.Vertex.BBType;
45
53{
54 private static APClass APCA, APCB, APCC, APCD, APCE, APCF;
55
56//------------------------------------------------------------------------------
57
59 {
60 APCA = APClass.make("A", 0);
61 APCB = APClass.make("B", 0);
62 APCC = APClass.make("C", 0);
63 APCD = APClass.make("D", 99);
64 APCE = APClass.make("E", 13);
65 APCF = APClass.make("F", 17);
66
67 HashMap<APClass,ArrayList<APClass>> cpMap =
68 new HashMap<APClass,ArrayList<APClass>>();
69 ArrayList<APClass> lstA = new ArrayList<APClass>();
70 lstA.add(APCA);
71 cpMap.put(APCA, lstA);
72 ArrayList<APClass> lstB = new ArrayList<APClass>();
73 lstB.add(APCB);
74 lstB.add(APCC);
75 cpMap.put(APCB, lstB);
76 ArrayList<APClass> lstC = new ArrayList<APClass>();
77 lstC.add(APCB);
78 lstC.add(APCC);
79 cpMap.put(APCC, lstC);
80 ArrayList<APClass> lstD = new ArrayList<APClass>();
81 lstD.add(APCD);
82 cpMap.put(APCD, lstD);
83 ArrayList<APClass> lstE = new ArrayList<APClass>();
84 lstE.add(APCE);
85 cpMap.put(APCE, lstE);
86
87
88 /* Compatibility matrix
89 *
90 * | A | B | C | D | E | F
91 * ---------------------------------
92 * A | T | | | | |
93 * ---------------------------------
94 * B | | T | T | | |
95 * ---------------------------------
96 * C | | T | T | | |
97 * ---------------------------------
98 * D | | | | T | |
99 * ---------------------------------
100 * E | | | | | T |
101 * ---------------------------------
102 * F | | | | | |
103 *
104 * NB: F has NONE!
105 */
106
107 HashMap<APClass,APClass> capMap = new HashMap<APClass,APClass>();
108 HashSet<APClass> forbEnds = new HashSet<APClass>();
109
111 FragmentSpace fs = new FragmentSpace(fsp,
112 new ArrayList<Vertex>(),
113 new ArrayList<Vertex>(),
114 new ArrayList<Vertex>(),
115 cpMap, capMap, forbEnds, cpMap);
117
118 EmptyVertex s = new EmptyVertex();
120 s.addAP(APCA);
122
123 EmptyVertex v0 = new EmptyVertex();
125 v0.addAP(APCA);
126 v0.addAP(APCB);
127 v0.addAP(APCB);
129
130 EmptyVertex v1 = new EmptyVertex();
132 v1.addAP(APCB);
134
135 EmptyVertex v2 = new EmptyVertex();
137 v2.addAP(APCA);
138 v2.addAP(APCA);
140
141 EmptyVertex v3 = new EmptyVertex();
143 v3.addAP(APCB);
144 v3.addAP(APCB);
146
147 EmptyVertex v4 = new EmptyVertex();
149 v4.addAP(APCA);
150 v4.addAP(APCB);
151 v4.addAP(APCB);
153
154 EmptyVertex v5 = new EmptyVertex();
156 v5.addAP(APCA);
157 v5.addAP(APCC);
158 v5.addAP(APCB);
160
161 EmptyVertex v6 = new EmptyVertex();
163 v6.addAP(APCD);
164 v6.addAP(APCD);
166
167 EmptyVertex v7 = new EmptyVertex();
169 v7.addAP(APCA);
171
172 EmptyVertex v8 = new EmptyVertex();
174 v8.addAP(APCB);
176
177 EmptyVertex v9 = new EmptyVertex();
179 v9.addAP(APCA);
180 v9.addAP(APCA);
181 v9.addAP(APCB);
182 v9.addAP(APCB);
184
185 EmptyVertex v10 = new EmptyVertex();
187 v10.addAP(APCA);
188 v10.addAP(APCC);
189 v10.addAP(APCD);
190 v10.addAP(APCB);
192
193 EmptyVertex v11 = new EmptyVertex();
195 v11.addAP(APCA);
196 v11.addAP(APCD);
197 v11.addAP(APCA);
198 v11.addAP(APCA);
199 v11.addAP(APCC);
200 v11.addAP(APCB);
201 v11.addAP(APCB);
202 v11.addAP(APCB);
204
205 EmptyVertex v12 = new EmptyVertex();
207 v12.addAP(APCE);
208 v12.addAP(APCE);
209 v12.addAP(APCE);
211
212 EmptyVertex v13 = new EmptyVertex();
214 v13.addAP(APCF);
215 v13.addAP(APCB);
216 v13.addAP(APCA);
219
220 return fs;
221 }
222
223//------------------------------------------------------------------------------
224
231 {
232 FragmentSpace fs = prepare();
233 DGraph graph = new DGraph();
235 graph.addVertex(s);
237 graph.addVertex(v0);
239 graph.addVertex(v1);
240 graph.addEdge(new Edge(s.getAP(0), v0.getAP(0)));
241 graph.addEdge(new Edge(v0.getAP(1), v1.getAP(0)));
242 graph.renumberGraphVertices();
243 return graph;
244 }
245
246//------------------------------------------------------------------------------
247
254 {
255 FragmentSpace fs = prepare();
256 DGraph graph = new DGraph();
258 graph.addVertex(v0);
260 graph.addVertex(v1);
261 graph.addEdge(new Edge(v0.getAP(1), v1.getAP(1)));
262 graph.renumberGraphVertices();
263 return graph;
264 }
265
266//------------------------------------------------------------------------------
267
274 {
275 FragmentSpace fs = prepare();
276 DGraph graph = new DGraph();
278 graph.addVertex(v0);
280 graph.addVertex(v1);
281 graph.addEdge(new Edge(v0.getAP(0), v1.getAP(0)));
282 graph.renumberGraphVertices();
283 return graph;
284 }
285
286//------------------------------------------------------------------------------
287
288 @Test
289 public void testLinkFromVertex() throws Exception
290 {
291 FragmentSpace fs = prepare();
292 DGraph graph = makeTestGraphA();
293 GraphLinkFinder glf = new GraphLinkFinder(fs,
294 graph.getVertexAtPosition(1), -1, true);
295 // NB: the boolean makes the search complete (within the limits that
296 // prevent combinatorial explosion)
297 // NB: "-1" is for "no selection of specific new building block".
298
299 // These are the expected numbers of AP mappings found for the three
300 // vertexes that can be alternative links.
301 Map<Integer,Integer> expected = new HashMap<Integer,Integer>();
302 expected.put(4, 4);
303 expected.put(5, 4);
304 expected.put(9, 12);
305 expected.put(10, 6);
306 expected.put(11, 84);
307 expected.put(13, 2);
308
309 LinkedHashMap<Vertex, List<APMapping>> allAltLinks =
311 Set<Vertex> keys = allAltLinks.keySet();
312 for (Vertex k : keys)
313 {
314 int bbId = k.getBuildingBlockId();
315 assertTrue(expected.containsKey(bbId), "Vertex with building block "
316 + "ID '" + bbId + "' should not be among the results.");
317 assertEquals(expected.get(bbId), allAltLinks.get(k).size(),
318 "Number of APmapping is wrong for bbId '" + bbId + "'.");
319 }
320 }
321
322//------------------------------------------------------------------------------
323
324 @Test
325 public void testLinkFromEdge() throws Exception
326 {
327 FragmentSpace fs = prepare();
328 DGraph graph = makeTestGraphA();
329 Edge targetEdge = graph.getEdgeAtPosition(1);
330 GraphLinkFinder glf = new GraphLinkFinder(fs, targetEdge, -1, true);
331 // NB: the boolean makes the search complete (within the limits the
332 // prevent combinatorial explosion)
333 // NB: "-1" is for "no selection of specific new building block".
334
335 // Expected results in terms of <bbId:list of classes>
336 Map<Integer,List<APClass>> expected =
337 new HashMap<Integer,List<APClass>>();
338 expected.put(0, new ArrayList<APClass>(Arrays.asList(
340 expected.put(3, new ArrayList<APClass>(Arrays.asList(
342 expected.put(4, new ArrayList<APClass>(Arrays.asList(
344 expected.put(5, new ArrayList<APClass>(Arrays.asList(
346 expected.put(9, new ArrayList<APClass>(Arrays.asList(
348 expected.put(10, new ArrayList<APClass>(Arrays.asList(
350 expected.put(11, new ArrayList<APClass>(Arrays.asList(
362 APCB,APCB,APCB,APCB)));
363
366 }
367
368//------------------------------------------------------------------------------
369
370 @Test
371 public void testLinkFromEdgeOneMatch() throws Exception
372 {
373 FragmentSpace fs = prepare();
374 DGraph graph = makeTestGraphE();
375 Edge targetEdge = graph.getEdgeAtPosition(0);
376 GraphLinkFinder glf = new GraphLinkFinder(fs, targetEdge, -1, true);
377 // NB: the boolean makes the search complete (within the limits the
378 // prevent combinatorial explosion)
379 // NB: "-1" is for "no selection of specific new building block".
380
381 // Expected results in terms of <bbId:list of classes>
382 Map<Integer,List<APClass>> expected =
383 new HashMap<Integer,List<APClass>>();
384 expected.put(12, new ArrayList<APClass>(Arrays.asList(
388
391 }
392
393//------------------------------------------------------------------------------
394
395 @Test
396 public void testLinkFromEdgeNoMatch() throws Exception
397 {
398 FragmentSpace fs = prepare();
399 DGraph graph = makeTestGraphF();
400 Edge targetEdge = graph.getEdgeAtPosition(0);
401 GraphLinkFinder glf = new GraphLinkFinder(fs, targetEdge, -1, true);
402 // NB: the boolean makes the search complete (within the limits the
403 // prevent combinatorial explosion)
404 // NB: "-1" is for "no selection of specific new building block".
405
406 // Expected results in terms of <bbId:list of classes>
407 Map<Integer,List<APClass>> expected =
408 new HashMap<Integer,List<APClass>>();
409
412 }
413
414//------------------------------------------------------------------------------
415
417 Map<Integer,List<APClass>> expected,
418 Map<Vertex, List<APMapping>> actual)
419 {
420 // Set this to true to print the mappings on stdout
421 boolean debug = false;
422
423 for (Vertex k : actual.keySet())
424 {
425 int bbId = k.getBuildingBlockId();
426
427 if (debug)
428 {
429 System.out.println("BBID: "+bbId);
430 }
431
432 List<APMapping> list = actual.get(k);
433
434 assertTrue(expected.containsKey(bbId), "Vertex with building block "
435 + "ID '" + bbId + "' should not among the results.");
436 assertEquals(expected.get(bbId).size() / 4, actual.get(k).size(),
437 "Number of APmappings is wrong for bbId '" + bbId + "'.");
438
439 int i=-1;
440 List<APClass> refList = expected.get(bbId);
441 for (APMapping apm : list)
442 {
443 if (debug)
444 {
445 System.out.println(" -> "+apm.toString());
446 }
447 for (Entry<AttachmentPoint, AttachmentPoint> e
448 : apm.entrySet())
449 {
450 if (debug)
451 {
452 System.out.println(" -> "+e.getKey().getAPClass()
453 +" "+e.getValue().getAPClass());
454 }
455 i++;
456 assertEquals(refList.get(i),e.getKey().getAPClass(),
457 "APClass in APMapping for bbId "+bbId+" entry " +i);
458 i++;
459 assertEquals(refList.get(i),e.getValue().getAPClass(),
460 "APClass in APMapping for bbId "+bbId+" entry " +i);
461 }
462 }
463 }
464
465 }
466
467//------------------------------------------------------------------------------
468
469}
Class defining a space of building blocks.
void appendVertexToLibrary(Vertex v, Vertex.BBType bbt, ArrayList< Vertex > library)
Takes a vertex and add it to a given library.
Vertex getVertexFromLibrary(Vertex.BBType bbType, int bbIdx)
Returns a clone of the requested building block.
void setAPclassBasedApproach(boolean useAPC)
Set the fragment space to behave according to APClass-based approach.
void groupAndClassifyFragments(boolean apClassBasedApproch)
Performs grouping and classification operations on the library of building blocks of BBType#FRAGMENT.
ArrayList< Vertex > getScaffoldLibrary()
ArrayList< Vertex > getFragmentLibrary()
Parameters defining the fragment space.
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
Class representing a mapping between attachment points (APs).
Definition: APMapping.java:42
Container for the list of vertices and the edges that connect them.
Definition: DGraph.java:102
Edge getEdgeAtPosition(int pos)
Definition: DGraph.java:2649
void addVertex(Vertex vertex)
Appends a vertex to this graph without creating any edge.
Definition: DGraph.java:1097
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
void renumberGraphVertices()
Reassign vertex IDs to all vertices of this graph.
Definition: DGraph.java:5283
void addEdge(Edge edge)
Adds the edge to the list of edges belonging to this graph.
Definition: DGraph.java:1021
This class represents the edge between two vertices.
Definition: Edge.java:38
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.
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
Definition: Vertex.java:61
void setBuildingBlockType(Vertex.BBType buildingBlockType)
Definition: Vertex.java:305
AttachmentPoint getAP(int i)
Get attachment point i on this vertex.
Definition: Vertex.java:920
The type of building block.
Definition: Vertex.java:86