$darkmode
DENOPTIM
GraphLinkFinder.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 java.util.ArrayList;
22import java.util.LinkedHashMap;
23import java.util.List;
24
25import denoptim.exception.DENOPTIMException;
26import denoptim.graph.APClass;
27import denoptim.graph.APMapping;
28import denoptim.graph.AttachmentPoint;
29import denoptim.graph.Edge;
30import denoptim.graph.Vertex;
31import denoptim.graph.Vertex.BBType;
32
46public class GraphLinkFinder
47{
54
62
70 private LinkedHashMap<Vertex,List<APMapping>> allCompatLinks =
71 new LinkedHashMap<Vertex,List<APMapping>>();
72
80 private static int maxCombs = 250;
81
85 private boolean foundNewLink = false;
86
91
92//------------------------------------------------------------------------------
93
101 public GraphLinkFinder(FragmentSpace fragSpace, Vertex originalLink)
102 throws DENOPTIMException
103 {
104 this(fragSpace, originalLink, -1, false);
105 }
106
107//------------------------------------------------------------------------------
108
120 Vertex originalLink, int newBuildingBlockID)
121 throws DENOPTIMException
122 {
123 this(fragSpace, originalLink, newBuildingBlockID, false);
124 }
125
126//------------------------------------------------------------------------------
127
142 Vertex originalLink, int newBuildingBlockID,
143 boolean screenAll) throws DENOPTIMException
144 {
145 this.fragmentSpace = fragSpace;
146
147 ArrayList<Vertex> candidates = getCandidateBBs(
148 originalLink.getBuildingBlockType(), newBuildingBlockID);
149
150 int candidatesOrigSize = candidates.size();
151 for (int i=0; i<candidatesOrigSize; i++)
152 {
153 if (foundNewLink && !screenAll)
154 break;
155
156 Vertex originalBB = fragSpace.getRandomizer().randomlyChooseOne(
157 candidates);
158 candidates.remove(originalBB);
159 try
160 {
162 originalBB.getBuildingBlockType(),
163 originalBB.getBuildingBlockId());
164 } catch (DENOPTIMException e)
165 {
166 e.printStackTrace();
167 continue;
168 }
169
170 // NB: the new link cannot be the same building block as the old one
172 originalLink.getBuildingBlockId())
173 {
174 continue;
175 }
176
177 if (chosenNewLink.getNumberOfAPs() < (originalLink.getNumberOfAPs() -
178 originalLink.getFreeAPCountThroughout()))
179 {
180 continue;
181 }
182
183 // We map all the compatibilities before choosing a specific mapping
184 APMapFinder apmf = new APMapFinder(fragSpace, originalLink,
185 chosenNewLink, screenAll);
186
187 if (!apmf.foundMapping())
188 {
189 this.chosenNewLink = null;
190 continue;
191 } else {
192 this.foundNewLink = true;
193 }
194
196
197 if (screenAll)
198 {
200 }
201 }
202 }
203
204//------------------------------------------------------------------------------
205
206 private ArrayList<Vertex> getCandidateBBs(BBType bbt, int bbId)
207 throws DENOPTIMException
208 {
209 ArrayList<Vertex> candidates = new ArrayList<Vertex>();
210 if (bbId<0)
211 {
212 switch (bbt)
213 {
214 case FRAGMENT:
215 candidates.addAll(fragmentSpace.getFragmentLibrary());
216 break;
217 case SCAFFOLD:
218 candidates.addAll(fragmentSpace.getScaffoldLibrary());
219 case CAP:
220 break;
221 default:
222 break;
223 }
224 } else {
225 Vertex chosenOne = fragmentSpace.getVertexFromLibrary(bbt, bbId);
226 candidates.add(chosenOne);
227 }
228 return candidates;
229 }
230
231//------------------------------------------------------------------------------
232
245 public GraphLinkFinder(FragmentSpace fragSpace, Edge originalEdge)
246 throws DENOPTIMException
247 {
248 this(fragSpace, originalEdge,-1,false);
249 }
250
251//------------------------------------------------------------------------------
252
265 public GraphLinkFinder(FragmentSpace fragSpace, Edge originalEdge,
266 int newBuildingBlockID) throws DENOPTIMException
267 {
268 this(fragSpace, originalEdge,newBuildingBlockID,false);
269 }
270
271//------------------------------------------------------------------------------
272
289 Edge originalEdge, int newBuildingBlockID,
290 boolean screenAll) throws DENOPTIMException
291 {
292 this.fragmentSpace = fragSpace;
293 ArrayList<Vertex> candidates = getCandidateBBs(
294 originalEdge.getTrgAP().getOwner().getBuildingBlockType(),
295 newBuildingBlockID);
296
297 int candidatesOrigSize = candidates.size();
298 for (int i=0; i<candidatesOrigSize; i++)
299 {
300 if (foundNewLink && !screenAll)
301 break;
302
303 Vertex originalBB = fragSpace.getRandomizer().randomlyChooseOne(
304 candidates);
305 candidates.remove(originalBB);
306 try
307 {
309 originalBB.getBuildingBlockType(),
310 originalBB.getBuildingBlockId());
311 } catch (DENOPTIMException e)
312 {
313 e.printStackTrace();
314 continue;
315 }
316
318 {
319 continue;
320 }
321
322 // We map all the compatibilities before choosing a specific mapping
323 LinkedHashMap<AttachmentPoint,List<AttachmentPoint>> apCompatilities =
324 new LinkedHashMap<AttachmentPoint,List<AttachmentPoint>>();
325
326 List<AttachmentPoint> needeAPs = new ArrayList<AttachmentPoint>();
327 needeAPs.add(originalEdge.getSrcAP());
328 needeAPs.add(originalEdge.getTrgAP());
329 for (int j=0; j<2;j++)
330 {
331 AttachmentPoint oAP = needeAPs.get(j);
332 APClass oriAPC = oAP.getAPClass();
334 {
335 boolean compatible = false;
337 {
338 if (j==0
339 && oriAPC.isCPMapCompatibleWith(
340 cAP.getAPClass(),
342 compatible = true;
343 else if (j==1
344 && cAP.getAPClass().isCPMapCompatibleWith(
345 oriAPC, fragmentSpace))
346 compatible = true;
347 } else {
348 compatible = true;
349 }
350 if (compatible)
351 {
352 if (apCompatilities.containsKey(oAP))
353 {
354 apCompatilities.get(oAP).add(cAP);
355 } else {
356 List<AttachmentPoint> lst =
357 new ArrayList<AttachmentPoint>();
358 lst.add(cAP);
359 apCompatilities.put(oAP,lst);
360 }
361 }
362 }
363 }
364 // keys is used just to keep the map keys sorted in a separate list
365 // so that the order is randomized only once, then it is retained.
366 List<AttachmentPoint> keys =
367 new ArrayList<AttachmentPoint>(
368 apCompatilities.keySet());
369 if (keys.size() < 2)
370 {
371 continue;
372 }
373
374 // Get all possible combinations of compatible AP pairs
375 List<APMapping> apMappings = new ArrayList<APMapping>();
376 int currentKey = 0;
377 APMapping currentMapping = new APMapping();
378 // yes, a nested loop would do it, but for now I use the same code
379 // as for when there is no limit to the number of keys (here, always 2)
381 currentKey, apCompatilities, currentMapping, apMappings,
382 screenAll, maxCombs);
383
384 if (apMappings.isEmpty())
385 {
386 this.chosenNewLink = null;
387 continue;
388 } else {
389 this.foundNewLink = true;
390 }
391
392 this.chosenAPMap = fragSpace.getRandomizer().randomlyChooseOne(
393 apMappings);
394 if (screenAll)
395 {
396 allCompatLinks.put(chosenNewLink, apMappings);
397 }
398 }
399 }
400
401//------------------------------------------------------------------------------
402
411 {
412 return chosenNewLink;
413 }
414
415//------------------------------------------------------------------------------
416
444 {
445 return chosenAPMap;
446 }
447
448//------------------------------------------------------------------------------
449
460 public LinkedHashMap<Vertex, List<APMapping>> getAllAlternativesFound()
461 {
462 return allCompatLinks;
463 }
464
465//------------------------------------------------------------------------------
466
467 public boolean foundAlternativeLink()
468 {
469 return foundNewLink;
470 }
471
472//------------------------------------------------------------------------------
473
474}
An utility class to encapsulate the search for an AttachmentPoint-AttachmentPoint mapping.
APMapping getChosenAPMapping()
Returns the AttachmentPoint-AttachmentPoint mapping chosen among the possible mappings.
boolean foundMapping()
Returns true if any mapping has been found.
List< APMapping > getAllAPMappings()
Returns all AttachmentPoint-AttachmentPoint mapping found.
Class defining a space of building blocks.
boolean useAPclassBasedApproach()
Check usage of APClass-based approach, i.e., uses attachment points with annotated data (i....
Vertex getVertexFromLibrary(Vertex.BBType bbType, int bbIdx)
Returns a clone of the requested building block.
ArrayList< Vertex > getScaffoldLibrary()
ArrayList< Vertex > getFragmentLibrary()
Utility class for the fragment space.
static boolean recursiveCombiner(List< AttachmentPoint > keys, int currentKey, Map< AttachmentPoint, List< AttachmentPoint > > possibilities, APMapping combination, List< APMapping > completeCombinations, boolean screenAll, int maxCombs)
Search for all possible combinations of compatible APs.
boolean isCPMapCompatibleWith(APClass other, FragmentSpace fragSpace)
Check compatibility as defined in the compatibility matrix considering this AP as source and the othe...
Definition: APClass.java:455
Class representing a mapping between attachment points (APs).
Definition: APMapping.java:42
An attachment point (AP) is a possibility to attach a Vertex onto the vertex holding the AP (i....
APClass getAPClass()
Returns the Attachment Point class.
This class represents the edge between two vertices.
Definition: Edge.java:38
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
Definition: Vertex.java:61
int getBuildingBlockId()
Returns the index of the building block that should correspond to the position of the building block ...
Definition: Vertex.java:284
Vertex.BBType getBuildingBlockType()
Definition: Vertex.java:298
abstract List< AttachmentPoint > getAttachmentPoints()
The type of building block.
Definition: Vertex.java:86