23import java.util.ArrayList;
24import java.util.LinkedHashMap;
27import java.util.Map.Entry;
28import java.util.TreeMap;
29import java.util.logging.Level;
30import java.util.stream.Collectors;
32import org.openscience.cdk.interfaces.IAtomContainer;
33import org.paukov.combinatorics3.Generator;
35import denoptim.constants.DENOPTIMConstants;
36import denoptim.exception.DENOPTIMException;
37import denoptim.fragmenter.BridgeHeadFindingRule;
38import denoptim.fragspace.APMapFinder;
39import denoptim.fragspace.FragmentSpace;
40import denoptim.fragspace.FragmentSpaceParameters;
41import denoptim.fragspace.GraphLinkFinder;
42import denoptim.fragspace.IdFragmentAndAP;
43import denoptim.graph.APClass;
44import denoptim.graph.APMapping;
45import denoptim.graph.AttachmentPoint;
46import denoptim.graph.DGraph;
47import denoptim.graph.Edge;
48import denoptim.graph.RelatedAPPair;
49import denoptim.graph.Ring;
50import denoptim.graph.SymmetricAPs;
51import denoptim.graph.SymmetricVertexes;
52import denoptim.graph.Template;
53import denoptim.graph.Template.ContractLevel;
54import denoptim.graph.Vertex;
55import denoptim.graph.Vertex.BBType;
56import denoptim.graph.rings.ChainLink;
57import denoptim.graph.rings.ClosableChain;
58import denoptim.graph.rings.PathSubGraph;
59import denoptim.graph.rings.RandomCombOfRingsIterator;
60import denoptim.graph.rings.RingClosingAttractor;
61import denoptim.graph.rings.RingClosureParameters;
62import denoptim.io.DenoptimIO;
63import denoptim.logging.CounterID;
64import denoptim.logging.Monitor;
65import denoptim.molecularmodeling.ThreeDimTreeBuilder;
66import denoptim.programs.RunTimeParameters.ParametersType;
67import denoptim.programs.denovo.GAParameters;
68import denoptim.utils.CrossoverType;
69import denoptim.utils.GraphUtils;
70import denoptim.utils.MutationType;
71import denoptim.utils.Randomizer;
97 int maxSizeXoverSubGraph)
103 List<Vertex[]> compatibleVrtxPairs =
new ArrayList<Vertex[]>();
104 for (
Edge eA : graphA.getEdgeList())
106 Vertex vA = eA.getTrgAP().getOwner();
111 for (
Edge eB : graphB.getEdgeList())
113 Vertex vB = eB.getTrgAP().getOwner();
122 compatibleVrtxPairs.add(pair);
130 ArrayList<XoverSite> sites =
new ArrayList<XoverSite>();
131 for (
Vertex[] pair : compatibleVrtxPairs)
139 List<Vertex> descendantsA =
new ArrayList<Vertex>();
141 List<Vertex> descendantsB =
new ArrayList<Vertex>();
156 List<Vertex> branchOnVA =
new ArrayList<Vertex>();
158 branchOnVA.addAll(descendantsA);
159 List<Vertex> branchOnVB =
new ArrayList<Vertex>();
161 branchOnVB.addAll(descendantsB);
175 List<Vertex[]> usablePairs =
new ArrayList<Vertex[]>();
190 for (
Vertex[] otherPair : compatibleVrtxPairs)
194 Vertex nextToEndOnA = otherPair[0];
195 Vertex nextToEndOnB = otherPair[1];
198 if (endOnA==
null || endOnB==
null)
202 if (!descendantsA.contains(endOnA) && endOnA!=vA
203 || !descendantsB.contains(endOnB) && endOnB!=vB)
224 if (!usablePairs.contains(pairOfEnds))
225 usablePairs.add(pairOfEnds);
229 TreeMap<String,List<Vertex[]>> sitesByBranchIdA =
230 new TreeMap<String,List<Vertex[]>>();
231 TreeMap<String,List<Vertex[]>> sitesByBranchIdB =
232 new TreeMap<String,List<Vertex[]>>();
233 for (
Vertex[] pp : usablePairs)
237 if (sitesByBranchIdA.containsKey(branchIdA))
239 sitesByBranchIdA.get(branchIdA).add(pp);
241 ArrayList<Vertex[]> lst =
new ArrayList<Vertex[]>();
243 sitesByBranchIdA.put(branchIdA, lst);
245 if (sitesByBranchIdB.containsKey(branchIdB))
247 sitesByBranchIdB.get(branchIdB).add(pp);
249 ArrayList<Vertex[]> lst =
new ArrayList<Vertex[]>();
251 sitesByBranchIdB.put(branchIdB, lst);
257 TreeMap<String,List<Vertex[]>> fewestBranchesSide =
null;
258 if (sitesByBranchIdA.size() <= sitesByBranchIdB.size())
259 fewestBranchesSide = sitesByBranchIdA;
261 fewestBranchesSide = sitesByBranchIdB;
264 for (List<
Vertex[]> val : fewestBranchesSide.values())
265 val.add(
new Vertex[]{
null,
null});
270 List<List<Vertex[]>> preCombsOfEnds = Generator.cartesianProduct(
271 fewestBranchesSide.values())
274 .collect(Collectors.<List<
Vertex[]>>toList());
278 List<List<Vertex[]>> combsOfEnds =
new ArrayList<List<Vertex[]>>();
279 for (List<
Vertex[]> comb : preCombsOfEnds)
281 List<Vertex[]> nullPurgedComb =
new ArrayList<Vertex[]>();
282 for (
Vertex[] inPair : comb)
284 if (inPair[0]!=
null && inPair[1]!=
null)
285 nullPurgedComb.add(inPair);
289 if (nullPurgedComb.size()>0)
290 combsOfEnds.add(nullPurgedComb);
313 for (
Vertex vA : graphA.getVertexList())
322 for (
Vertex vB : graphB.getVertexList())
333 maxSizeXoverSubGraph))
335 if (!sites.contains(xos))
358 List<
Vertex[]> cominationOfEnds,
363 if (cominationOfEnds.size()==0)
384 Generator.permutation(cominationOfEnds)
407 List<
Vertex[]> chosenSequenceOfEndpoints,
416 boolean exclude =
false;
417 for (
Vertex[] pairA : chosenSequenceOfEndpoints)
419 for (
Vertex[] pairB : chosenSequenceOfEndpoints)
424 if (pairA[0]==pairB[0] || pairA[1]==pairB[1])
436 List<Vertex> subGraphEndInA =
new ArrayList<Vertex>();
437 List<Vertex> subGraphEndInB =
new ArrayList<Vertex>();
438 List<Vertex> alreadyIncludedFromA =
new ArrayList<Vertex>();
439 List<Vertex> alreadyIncludedFromB =
new ArrayList<Vertex>();
440 for (
Vertex[] otherPair : chosenSequenceOfEndpoints)
442 Vertex endOnA = otherPair[0];
443 Vertex endOnB = otherPair[1];
446 if (alreadyIncludedFromA.contains(endOnA)
447 || alreadyIncludedFromB.contains(endOnB))
452 subGraphEndInA.add(endOnA);
453 subGraphEndInB.add(endOnB);
457 ArrayList<Vertex> subGraphA =
new ArrayList<Vertex>();
459 if (!subGraphEndInA.contains(vA))
462 ArrayList<Vertex> subGraphB =
new ArrayList<Vertex>();
464 if (!subGraphEndInB.contains(vB))
468 if (subGraphA.size()>1 && subGraphB.size()>1)
475 if (subGraphA.get(0).sameAs(subGraphB.get(0),
new StringBuilder()))
495 List<Vertex> subGraphA,
497 List<XoverSite> collector)
499 DGraph gOwnerA = subGraphA.get(0).getGraphOwner();
500 DGraph gOwnerB = subGraphB.get(0).getGraphOwner();
512 if (allAPsA.size() < needyAPsB.size()
513 || allAPsB.size() < needyAPsA.size())
530 && jacketTmplB==
null)
533 needyAPsB, xoverType);
534 if (!collector.contains(xos))
545 for (
Vertex v : subGraphA)
548 for (
Vertex v : subGraphB)
569 allAPsA, needyAPsA, allAPsB, needyAPsB,
577 subGraphB, needyAPsB, xoverType);
578 if (!collector.contains(xos))
631 DGraph graph = vertex.getGraphOwner();
679 DGraph graph = vertex.getGraphOwner();
714 return extendLink(vertex, chosenAPId, -1 , mnt, fragSpace);
751 +vertex+
" has no edge user.");
756 +
"vertex (AP "+chosenAPId+
" of vertex "+vertex+
").");
758 return extendLink(e, chosenNewVrtxId, mnt, fragSpace);
797 LinkedHashMap<AttachmentPoint,Integer> apMap =
798 new LinkedHashMap<AttachmentPoint,Integer>();
799 for (Entry<AttachmentPoint, AttachmentPoint> e :
802 apMap.put(e.getKey(), e.getValue().getIndexInOwner());
805 DGraph graph = edge.getSrcAP().getOwner().getGraphOwner();
842 boolean force,
int chosenVrtxIdx,
int chosenApId,
845 DGraph g = vertex.getGraphOwner();
848 Edge e = vertex.getEdgeToParent();
851 String msg =
"Program Bug in substituteFragment: Unable to locate "
852 +
"parent edge for vertex "+vertex+
" in graph "+g;
853 settings.getLogger().log(Level.SEVERE, msg);
868 return extendGraph(parentVrt,
false,symmetry,force,chosenVrtxIdx,
869 chosenApId, settings);
885 long vid = vertex.getVertexId();
886 DGraph molGraph = vertex.getGraphOwner();
890 List<Vertex> toRemove =
new ArrayList<Vertex>();
925 long vid = vertex.getVertexId();
926 DGraph molGraph = vertex.getGraphOwner();
930 List<Vertex> toRemove =
new ArrayList<Vertex>();
934 if (!v.getMutationTypes(
new ArrayList<MutationType>())
981 vertex.getGraphOwner().removeCappingGroups();
983 List<AttachmentPoint> freeeAPs = vertex.getFreeAPThroughout();
984 if (freeeAPs.size()==0)
989 DGraph originalGraph = vertex.getGraphOwner();
996 List<Ring> setOfRingsOnTmpGraph =
null;
999 APClass apc = srcAP.getAPClass();
1002 if (!fragSpace.getRCCompatibilityMatrix().containsKey(apc))
1006 List<APClass> rcTrgAPCs = fragSpace.getRCCompatibilityMatrix().get(
1010 Vertex rcvOnSrcAP =
null;
1011 List<Vertex> candidateRCVs = fragSpace.getRCVsForAPClass(apc);
1012 boolean rcvIsChosenArbitrarily =
false;
1013 if (candidateRCVs.size()>0)
1017 rcvIsChosenArbitrarily =
true;
1018 rcvOnSrcAP = fragSpace.getPolarizedRCV(
true);
1022 List<Vertex> rcvAddedToGraph =
new ArrayList<Vertex>();
1024 rcvAddedToGraph.add(rcvOnSrcAP);
1029 for (
int i=0; i<20; i++)
1032 List<AttachmentPoint> apsToTry =
1034 int numberOfAttempts = apsToTry.size();
1036 for (
int iap=0; iap<numberOfAttempts; iap++)
1039 if (rcTrgAPCs.contains(candidate.
getAPClass()))
1044 apsToTry.remove(trgAP);
1053 Vertex rcvOnTrgAP =
null;
1054 if (rcvIsChosenArbitrarily)
1056 rcvOnTrgAP = fragSpace.getPolarizedRCV(
false);
1058 List<Vertex> candRCVs = fragSpace.getRCVsForAPClass(
1060 if (candRCVs.size()>0)
1064 List<Vertex> keptRCVs =
new ArrayList<Vertex>();
1065 for (
Vertex rcv : candRCVs)
1067 if (requiredAPC.
equals(rcv.getAP(0).getAPClass()))
1071 if (rcvOnTrgAP==
null)
1086 rcvAddedToGraph.add(rcvOnTrgAP);
1088 if (rcvAddedToGraph.size() < 2)
1097 settings.getLogger(), rng);
1103 settings.getMaxRingsAddedByMutation(),
1104 fragSpace, rcParams);
1110 setOfRingsOnTmpGraph = rCombIter.
next();
1113 if (setOfRingsOnTmpGraph.size()>0)
1117 for (
Vertex toRemove : rcvAddedToGraph)
1120 if (setOfRingsOnTmpGraph==
null || setOfRingsOnTmpGraph.size()==0)
1127 boolean done =
false;
1128 for (
Ring rOnTmp : setOfRingsOnTmpGraph)
1132 tmpGraph.
indexOf(rOnTmp.getHeadVertex().getParent()));
1134 rOnTmp.getHeadVertex().getEdgeToParent().getSrcAP()
1135 .getIndexInOwner());
1141 headRCV = rOnTmp.getHeadVertex().
clone();
1149 tmpGraph.
indexOf(rOnTmp.getTailVertex().getParent()));
1151 rOnTmp.getTailVertex().getEdgeToParent().getSrcAP()
1152 .getIndexInOwner());
1158 tailRCV = rOnTmp.getTailVertex().
clone();
1165 originalGraph.
addRing(headRCV, tailRCV);
1170 vertex.getGraphOwner().addCappingGroups(fragSpace);
1207 vertex.getGraphOwner().removeCappingGroups();
1209 List<AttachmentPoint> freeAPs = vertex.getFreeAPThroughout();
1210 if (freeAPs.size()==0)
1216 DGraph graph = vertex.getGraphOwner();
1221 List<List<RelatedAPPair>> candidatePairsSets =
1226 rng.
nextBoolean(settings.getSymmetryProbability()),
1227 settings.getLogger(), rng);
1228 if (candidatePairsSets.size()==0)
1238 List<List<RelatedAPPair>> szBiasedCandidatePairsSets =
1239 new ArrayList<List<RelatedAPPair>>();
1240 for (List<RelatedAPPair> pairSet : candidatePairsSets)
1243 pairSet.get(0).property;
1247 for (
int i=0; i<allowedBridgeLengths.length; i++)
1249 int allowedBridgeLength = allowedBridgeLengths[i];
1250 int possibleRingSize = allowedBridgeLength
1251 + existingBridgeLength;
1261 for (
int z=0; z<weight; z++)
1263 szBiasedCandidatePairsSets.add(pairSet);
1267 if (szBiasedCandidatePairsSets.size()==0)
1275 szBiasedCandidatePairsSets);
1280 String elsInHalfFrag = chosenPairsSet.get(0).propID.substring(0,1);
1281 if (elsInHalfFrag.matches(
"[a-zA-Z]"))
1282 elsInHalfFrag =
"0";
1283 boolean newRingIsAromatic =
true;
1284 String elInIncomingFrag =
"0el";
1285 switch (elsInHalfFrag)
1290 elInIncomingFrag =
"0el";
1291 newRingIsAromatic =
false;
1297 elInIncomingFrag =
"4el";
1303 elInIncomingFrag =
"3el";
1308 elInIncomingFrag =
"2el";
1314 elInIncomingFrag =
"1el";
1317 throw new Error(
"Unknown number of pi-electrons in fragment to "
1318 +
"be used for ring fusion operation.");
1324 chosenPairsSet.get(0).property;
1326 List<Vertex> usableBridges =
null;
1327 if (newRingIsAromatic)
1337 chosenPairsSet.get(0).apA.getAPClass(),
1338 chosenPairsSet.get(0).apB.getAPClass(),
1343 if (usableBridges.size()==0)
1352 List<Vertex> szBiasedUsableBridges =
new ArrayList<Vertex>();
1353 for (
Vertex candidateBridge : usableBridges)
1355 int thisBridgeLength = (int) candidateBridge.getProperty(
1358 int resultingRingSize = existingBridgeLength + thisBridgeLength;
1368 for (
int z=0; z<weigth; z++)
1370 szBiasedUsableBridges.add(candidateBridge);
1374 if (szBiasedUsableBridges.size()==0)
1383 List<AttachmentPoint> apsInFusion =
new ArrayList<AttachmentPoint>();
1384 int[] idApOnBridge =
new int[2];
1385 if (newRingIsAromatic)
1391 idApOnBridge[0] = apsInFusion.get(0).getIndexInOwner();
1392 idApOnBridge[1] = apsInFusion.get(1).getIndexInOwner();
1394 idApOnBridge[0] = apsInFusion.get(1).getIndexInOwner();
1395 idApOnBridge[1] = apsInFusion.get(0).getIndexInOwner();
1398 idApOnBridge[0] = Integer.parseInt(incomingVertex.
getProperty(
1400 idApOnBridge[1] = Integer.parseInt(incomingVertex.
getProperty(
1404 boolean done =
false;
1415 Vertex rcvBridge = fragSpace.getPolarizedRCV(
true);
1417 rcvBridge.
getAP(0));
1419 Vertex rcvTail = fragSpace.getPolarizedRCV(
false);
1421 graph.
addRing(rcvBridge, rcvTail);
1426 vertex.getGraphOwner().addCappingGroups(fragSpace);
1449 boolean symmetryOnAps,
1453 return extendGraph(curVertex, extend, symmetryOnAps,
false, -1, -1,
1484 boolean symmetryOnAps,
1507 boolean status =
false;
1510 if (!curVrtx.hasFreeAP())
1515 DGraph molGraph = curVrtx.getGraphOwner();
1516 int lvl = molGraph.
getLevel(curVrtx);
1518 ArrayList<Long> addedVertices =
new ArrayList<>();
1520 List<AttachmentPoint> lstDaps = curVrtx.getAttachmentPoints();
1521 List<AttachmentPoint> toDoAPs =
new ArrayList<AttachmentPoint>();
1522 toDoAPs.addAll(lstDaps);
1523 for (
int i=0; i<lstDaps.size(); i++)
1544 boolean allowOnlyRingClosure =
false;
1556 double extendGraphProb = molSizeProb * byLevelProb * crowdingProb;
1557 boolean fgrow = settings.getRandomizer().nextBoolean(
1562 && settings.getRandomizer().nextBoolean(byLevelProb
1565 allowOnlyRingClosure =
true;
1573 if (!allowOnlyRingClosure
1578 apId, molGraph, addedVertices, settings);
1587 if (allowOnlyRingClosure)
1612 if ((curVrtx.getGraphOwner().getHeavyAtomsCount() +
1622 settings.getSymmetryProbability(),
1625 if (curVrtx.getSymmetricAPs(ap).size()!=0
1626 && (cpOnSymAPs || symmetryOnAps)
1627 && !allowOnlyRingClosure)
1629 symAPs.addAll(curVrtx.getSymmetricAPs(ap));
1632 boolean allOnSameSrc =
true;
1635 if (!symAP.hasSameSrcAtom(ap))
1637 allOnSameSrc =
false;
1654 crowdedness = crowdedness + 1;
1658 double shot = settings.getRandomizer().nextDouble();
1667 crowdedness, settings);
1669 if (shot > crowdProb)
1673 crowdedness = crowdedness + 1;
1693 symVerts.
add(curVrtx);
1697 if ((curVrtx.getGraphOwner().getHeavyAtomsCount() +
1699 * symAPs.size()) > maxHeavyAtoms)
1705 List<AttachmentPoint> allAPsFromSymVerts =
new ArrayList<>();
1706 for (
Vertex symVrt : symVerts)
1711 apOnVrt.getIndexInOwner());
1715 if (apOnVrt.sameAs(apOnSymVrt)
1717 && !symAPs.contains(apOnSymVrt))
1719 allAPsFromSymVerts.add(apOnSymVrt);
1723 symAPs.addAll(allAPsFromSymVerts);
1731 if (!symAP.isAvailable())
1747 addedVertices.add(newVrtId);
1748 newSymSetOfVertices.
add(fragVertex);
1752 if (newSymSetOfVertices.size() > 1)
1761 for (
int i=0; i<addedVertices.size(); i++)
1763 long vid = addedVertices.get(i);
1769 if (addedVertices.size() > 0)
1814 int dapidx,
int chosenVrtxIdx,
int chosenApId,
1817 List<AttachmentPoint> lstDaps = curVertex.getAttachmentPoints();
1823 if (!fragSpace.useAPclassBasedApproach())
1825 int fid = fragSpace.getRandomizer().nextInt(
1826 fragSpace.getFragmentLibrary().size());
1831 List<IdFragmentAndAP> candidates =
1832 fragSpace.getFragAPsCompatibleWithClass(
1834 if (candidates.size() > 0)
1836 if (chosenVrtxIdx>-1 && chosenApId>-1)
1842 res = fragSpace.getRandomizer().randomlyChooseOne(candidates);
1868 List<Vertex> rcvs = fragSpace.getRCVs();
1870 if (!fragSpace.useAPclassBasedApproach())
1874 List<Vertex> candidates = fragSpace.getRCVsForAPClass(
1876 if (candidates.size() > 0)
1896 boolean res =
false;
1906 curVertex, dapidx, molGraph);
1917 int numCands = lscFfCc.size();
1920 int chosenId = settings.getRandomizer().nextInt(numCands);
1922 ArrayList<Integer> newFragIds = chosenFfCc.
getFragIDs();
1923 int molIdNewFrag = newFragIds.get(0);
1925 int dapNewFrag = newFragIds.get(2);
1926 if (molIdNewFrag != -1)
1930 newvid, molIdNewFrag, typeNewFrag,
1933 molGraph.appendVertexOnAP(curVertex.getAP(dapidx),
1934 newVrtx.
getAP(dapNewFrag));
1938 addedVertices.add(newvid);
1940 molGraph.getClosableChains().removeAll(
1942 APClass apc = curVertex.getAttachmentPoints().get(
1943 dapidx).getAPClass();
1946 settings.getSymmetryProbability(),
1955 String msg =
"BUG: Incorrect vertex num. Contact author.";
1956 settings.getLogger().log(Level.SEVERE, msg);
2032 ArrayList<FragForClosabChains> lstChosenFfCc =
2033 new ArrayList<FragForClosabChains>();
2035 if (molGraph.getClosableChains().size() == 0)
2037 return lstChosenFfCc;
2044 int posInCc = cc.involvesVertex(curVertex);
2059 if (cc.getSize() > (posInCc+1))
2062 ChainLink nextChainLink = cc.getLink(posInCc+1);
2063 nfid = nextChainLink.
getIdx();
2075 if ((posInCc-1) >= 0)
2078 ChainLink nextChainLink = cc.getLink(posInCc-1);
2079 nfid = nextChainLink.
getIdx();
2090 ArrayList<Integer> eligibleFrgId =
new ArrayList<Integer>();
2091 eligibleFrgId.add(nfid);
2092 eligibleFrgId.add(nfty.
toOldInt());
2093 eligibleFrgId.add(nfap);
2094 boolean found =
false;
2097 int fidA = ffcc.getFragIDs().get(0);
2099 int fapA = ffcc.getFragIDs().get(2);
2100 if (nfid==fidA && nfty==ftyA && nfap==fapA)
2103 ffcc.getCompatibleCC().add(cc);
2107 ffcc.getIncompatibleCC().add(cc);
2112 ArrayList<ClosableChain> compatChains =
2113 new ArrayList<ClosableChain>();
2114 ArrayList<ClosableChain> incompatChains =
2115 new ArrayList<ClosableChain>();
2118 incompatChains.addAll(otherFfCc.getCompatibleCC());
2126 lstChosenFfCc.add(newChosenCc);
2133 Edge edge = molGraph.getEdgeWithParent(
2134 curVertex.getVertexId());
2141 int posInCc = cc.involvesVertexAndAP(curVertex, dapidx, chidAp);
2155 List<Integer> altertnativeDirections =
new ArrayList<>();
2156 altertnativeDirections.add(-1);
2157 altertnativeDirections.add(+1);
2158 for (
int altDir : altertnativeDirections)
2160 ChainLink parentLink = cc.getLink(posInCc + altDir);
2161 int pLnkId = parentLink.
getIdx();
2174 if (pLnkId==prntId && pLnkTyp==prntTyp && pLnkAp == prntAp &&
2177 if (cc.getSize() > (posInCc+altDir)
2178 && (posInCc+altDir) >= 0)
2180 ChainLink nextChainLink = cc.getLink(posInCc + altDir);
2181 nfid = nextChainLink.
getIdx();
2198 ArrayList<Integer> eligibleFrgId =
new ArrayList<Integer>();
2199 eligibleFrgId.add(nfid);
2200 eligibleFrgId.add(nfty.
toOldInt());
2201 eligibleFrgId.add(nfap);
2202 boolean found =
false;
2205 int fidA = ffcc.getFragIDs().get(0);
2207 int fapA = ffcc.getFragIDs().get(2);
2208 if (nfid==fidA && nfty==ftyA && nfap==fapA)
2211 ffcc.getCompatibleCC().add(cc);
2215 ffcc.getIncompatibleCC().add(cc);
2220 ArrayList<ClosableChain> compatChains =
2221 new ArrayList<ClosableChain>();
2222 ArrayList<ClosableChain> incompatChains =
2223 new ArrayList<ClosableChain>();
2226 incompatChains.addAll(otherFfCc.getCompatibleCC());
2233 lstChosenFfCc.add(newChosenCc);
2237 return lstChosenFfCc;
2255 DGraph gA = site.getA().get(0).getGraphOwner();
2256 DGraph gB = site.getB().get(0).getGraphOwner();
2259 List<AttachmentPoint> allAPsOnA = gA.
getSubgraphAPs(site.getA());
2260 List<AttachmentPoint> allAPsOnB = gB.
getSubgraphAPs(site.getB());
2264 List<AttachmentPoint> needyAPsOnA = site.getAPsNeedingMappingA();
2265 List<AttachmentPoint> needyAPsOnB = site.getAPsNeedingMappingB();
2272 if (!ap.isSrcInUserThroughout())
2281 if (!ap.isSrcInUserThroughout())
2288 if (apToParentA==
null || apToParentB==
null)
2291 +
"point connecting a subgraph to the rest of the graph. "
2292 +
"This violates assumption that crossover does not "
2293 +
"involve scaffold or vertexes without parent.");
2306 fixedRootAPs.put(apToParentA, apToParentB);
2312 allAPsOnA, needyAPsOnA,
2313 allAPsOnB, needyAPsOnB, fixedRootAPs,
2332 LinkedHashMap<AttachmentPoint,AttachmentPoint>
2333 apMapA =
new LinkedHashMap<AttachmentPoint,AttachmentPoint>();
2334 LinkedHashMap<AttachmentPoint,AttachmentPoint>
2335 apMapB =
new LinkedHashMap<AttachmentPoint,AttachmentPoint>();
2350 apMapA.put(apOnA, apOnSubGraphB);
2351 apMapB.put(apOnB, apOnSubGraphA);
2378 double symmetryProbability,
Randomizer randomizer)
2412 List<Vertex> mutable = graph.getMutableSites(
2413 settings.getExcludedMutationTypes());
2421 Vertex vA = site.apA.getOwner();
2422 Vertex vB = site.apB.getOwner();
2423 if (!mutable.contains(vA))
2425 if (!mutable.contains(vB))
2430 if (mutable.size() == 0)
2433 String msg =
"Graph has no mutable site. Mutation aborted.";
2434 settings.getLogger().info(msg);
2437 boolean doneMutation =
true;
2439 settings.getMultiSiteMutationWeights(),
2440 settings.getRandomizer().nextDouble());
2441 for (
int i=0; i<numberOfMutations; i++)
2445 mutable = graph.getMutableSites(
2446 settings.getExcludedMutationTypes());
2449 Vertex v = settings.getRandomizer().randomlyChooseOne(mutable);
2454 return doneMutation;
2475 List<MutationType> mTypes = vertex.getMutationTypes(
2476 settings.getExcludedMutationTypes());
2477 if (mTypes.size() == 0)
2481 MutationType mType = settings.getRandomizer().randomlyChooseOne(mTypes);
2503 int pos = vertex.getGraphOwner().
indexOf(vertex);
2507 }
catch (IllegalArgumentException|NullPointerException e)
2509 String debugFile =
"failedMutation_" + mType
2510 +
"_" + vertex.getVertexId() +
"(" + pos +
")_"
2511 + settings.timeStamp +
".sdf";
2513 settings.getLogger(), settings.getRandomizer());
2514 settings.getLogger().warning(
"Fatal exception while performing "
2515 +
"mutation. See file '" + debugFile +
"' to reproduce the "
2560 DGraph graph = vertex.getGraphOwner();
2564 settings.getLogger().info(
"Vertex has no owner - "
2565 +
"Mutation aborted");
2568 if (!vertex.getMutationTypes(settings.getExcludedMutationTypes())
2572 settings.getLogger().info(
"Vertex does not allow mutation type "
2573 +
"'" + mType +
"' - Mutation aborted");
2578 int positionOfVertex = graph.
indexOf(vertex);
2585 +
" (" + positionOfVertex +
")";
2588 boolean done =
false;
2592 done =
rebuildBranch(vertex, force, chosenVrtxIdx, chosenApId,
2625 List<Integer> candidates =
new ArrayList<Integer>();
2628 candidates.add(c.getEdgeToParent().getSrcAP()
2629 .getIndexInOwner());
2631 if (candidates.size() == 0)
2637 chosenApId = settings.getRandomizer().randomlyChooseOne(
2640 done =
extendLink(vertex, chosenApId, chosenVrtxIdx, mnt,
2662 vertex.getGraphOwner().removeCappingGroupsOn(vertex);
2663 done =
extendGraph(vertex,
false,
false, force, chosenVrtxIdx,
2664 chosenApId, settings);
2676 String msg =
"Mutation '" + mType.toString() +
"' on vertex "
2677 + vertex.toString() +
" (position " + positionOfVertex
2678 +
" in graph " + graphId+
"): ";
2690 msg = msg +
"unsuccessful";
2692 settings.getLogger().info(msg);
General set of constants used in DENOPTIM.
static final String VRTPROPBRIDGELENGTH
Name of Vertex property used to record how long a ring-closing bridge is.
static final String VRTPROPBRIDGEEND_B
Name of Vertex property used to record which AP is selected for bridge formation on side 'B'.
static final Object STOREDVID
Key of the property remembering vertex IDs.
static final String VRTPROPBRIDGEEND_A
Name of Vertex property used to record which AP is selected for bridge formation on side 'A'.
SMARTS-based rules to identify potential bridge head atoms for ring fusion operations.
int getExistingBridgeLength()
int[] getAllowedBridgeLength()
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.
Class defining a space of building blocks.
boolean imposeSymmetryOnAPsOfClass(APClass apClass)
Checks if the symmetry settings impose use of symmetry on attachment points of the given AP class.
Parameters defining the fragment space.
FragmentSpace getFragmentSpace()
An utility class to encapsulate the search for vertexes that satisfy constraints.
Vertex getChosenAlternativeLink()
Returns the vertex chosen as alternative.
APMapping getChosenAPMapping()
Returns the AP mapping that allows the usage of the vertex chosen either as alternative to be install...
boolean foundAlternativeLink()
Data structure containing information that identifies a single AP of a vertex/fragment.
Helper methods for the genetic algorithm.
static double getGrowthByLevelProbability(int level, GAParameters settings)
Calculates the probability of adding a fragment to the given level.
static int chooseNumberOfSitesToMutate(double[] multiSiteMutationProb, double hit)
Takes a decision on how many sites to mutate on a candidate.
static List< Vertex > getUsableAliphaticBridges(APClass apcA, APClass apcB, int[] allowedLengths, FragmentSpace fragSpace)
Finds all vertexes that can be used as aliphatic bridge.
static double getCrowdingProbability(AttachmentPoint ap, GAParameters settings)
Calculated the probability of using and attachment point rooted on an atom that is holding other atta...
static List< List< RelatedAPPair > > searchRingFusionSites(DGraph graph, GAParameters gaParams)
static int getCrowdedness(AttachmentPoint ap)
Calculate the current crowdedness of the given attachment point.
static List< Vertex > getUsableAromaticBridges(String elInIncomingFrag, int[] allowedLengths, FragmentSpace fragSpace)
Finds all vertexes that can be used as aromatic bridge, i.e., can be used to create an aromatic ring ...
static double getMolSizeProbability(DGraph graph, GAParameters settings)
Calculated the probability of extending a graph based on the current size of the molecular representa...
Private class representing a selected closable chain of fragments.
ArrayList< ClosableChain > incompatChains
FragForClosabChains(ArrayList< ClosableChain > compatChains, ArrayList< ClosableChain > incompatChains, ArrayList< Integer > fragIds)
ArrayList< Integer > fragIds
ArrayList< ClosableChain > compatChains
ArrayList< ClosableChain > getCompatibleCC()
ArrayList< ClosableChain > getIncompatibleCC()
void addCompatibleCC(ClosableChain icc)
ArrayList< Integer > getFragIDs()
Collection of operators meant to alter graphs and associated utilities.
static IdFragmentAndAP getFrgApForSrcAp(Vertex curVertex, int dapidx, FragmentSpace fragSpace)
Select a compatible fragment for the given attachment point.
static boolean performMutation(Vertex vertex, MutationType mType, boolean force, int chosenVrtxIdx, int chosenApId, Monitor mnt, GAParameters settings)
Mutates the given vertex according to the given mutation type, if possible.
static boolean extendGraph(Vertex curVrtx, boolean extend, boolean symmetryOnAps, boolean force, int chosenVrtxIdx, int chosenApId, GAParameters settings)
function that will keep extending the graph.
static boolean extendLink(Vertex vertex, int chosenAPId, Monitor mnt, FragmentSpace fragSpace)
Inserts a vertex in between two connected vertexes that are identified by the one vertex holding the ...
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 applySymmetry(boolean apclassImposed, double symmetryProbability, Randomizer randomizer)
Decides whether to apply constitutional symmetry or not.
static void checkAndAddXoverSites(FragmentSpace fragSpace, List< Vertex > subGraphA, List< Vertex > subGraphB, CrossoverType xoverType, List< XoverSite > collector)
Here we check that the given subgraphs have a mapping that allows to swap them, and full fill any oth...
static boolean performMutation(Vertex vertex, MutationType mType, Monitor mnt, GAParameters settings)
Mutates the given vertex according to the given mutation type, if possible.
static boolean substituteLink(Vertex vertex, int chosenVrtxIdx, Monitor mnt, FragmentSpace fragSpace)
Substitutes a vertex while keeping its surrounding.
static boolean isCrossoverPossible(Edge eA, Edge eB, FragmentSpace fragSpace)
Evaluate AP class-compatibility of a pair of edges with respect to crossover.
static void processCombinationOfEndPoints(Vertex[] pair, List< Vertex[]> cominationOfEnds, List< XoverSite > collector, FragmentSpace fragSpace)
Given a pair of seed vertexes that define where a pair of subgraphs stars in the corresponding origin...
static boolean attachFragmentInClosableChain(Vertex curVertex, int dapidx, DGraph molGraph, ArrayList< Long > addedVertices, GAParameters settings)
static void processPermutationOfEndPoints(Vertex[] pair, List< Vertex[]> chosenSequenceOfEndpoints, List< XoverSite > collector, FragmentSpace fragSpace)
Given a pair of seed vertexes that define where a pair of subgraphs stars in the corresponding origin...
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 ArrayList< FragForClosabChains > getFragmentForClosableChain(Vertex curVertex, int dapidx, DGraph molGraph)
Method to select fragments that increase the likeliness of generating closable chains.
static boolean performMutation(Vertex vertex, Monitor mnt, GAParameters settings)
Tries to do mutate the given vertex.
static IdFragmentAndAP getFrgApForSrcAp(Vertex curVertex, int dapidx, int chosenVrtxIdx, int chosenApId, FragmentSpace fragSpace)
Select a compatible fragment for the given attachment point.
static IdFragmentAndAP getRCVForSrcAp(Vertex curVertex, int dapidx, FragmentSpace fragSpace)
Select a compatible ring-closing vertex for the given attachment point.
static boolean deleteFragment(Vertex vertex)
Deletion mutation removes the vertex and also the symmetric partners on its parent.
static boolean rebuildBranch(Vertex vertex, boolean force, int chosenVrtxIdx, int chosenApId, GAParameters settings)
Substitutes a vertex and any child branch.
static boolean addFusedRing(Vertex vertex, Monitor mnt, boolean force, FragmentSpace fragSpace, GAParameters settings)
Tries to add a fused ring using a pair of free APs, one of which on the given vertex.
static boolean deleteLink(Vertex vertex, int chosenVrtxIdx, Monitor mnt, FragmentSpace fragSpace)
Removes a vertex while merging as many of the child branches into the parent vertex.
static boolean extendLink(Vertex vertex, int chosenAPId, int chosenNewVrtxId, Monitor mnt, FragmentSpace fragSpace)
Inserts a vertex in between two connected vertexes that are identified by the one vertex holding the ...
static boolean performMutation(DGraph graph, Monitor mnt, GAParameters settings)
Tries to do mutate the given graph.
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.
static boolean extendLink(Edge edge, int chosenBBIdx, Monitor mnt, FragmentSpace fragSpace)
Replace an edge with two edges with a new vertex in between, thus inserting a vertex in between two d...
static boolean deleteChain(Vertex vertex, Monitor mnt, FragmentSpace fragSpace)
Deletes the given vertex and all other vertexes that are not connected to more than 2 non-capping gro...
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.
boolean isCPMapCompatibleWith(APClass other, FragmentSpace fragSpace)
Check compatibility as defined in the compatibility matrix considering this AP as source and the othe...
Class representing a mapping between attachment points (APs).
LinkedHashMap< Integer, Integer > toIntMappig()
Produces an index-based version of this mapping where each index represents the attachment point as i...
An attachment point (AP) is a possibility to attach a Vertex onto the vertex holding the AP (i....
AttachmentPoint getLinkedAP()
Gets the attachment point (AP) that is connected to this AP via the edge user.
APClass getAPClass()
Returns the Attachment Point class.
boolean isAvailable()
Check availability of this attachment point.
Edge getEdgeUserThroughout()
Gets the edge that is using this AP, or null if no edge is using this AP.
Container for the list of vertices and the edges that connect them.
boolean removeVertexAndWeld(Vertex vertex, FragmentSpace fragSpace)
Remove a given vertex belonging to this graph and re-connects the resulting graph branches as much as...
boolean replaceVertex(Vertex vertex, int bbId, BBType bbt, LinkedHashMap< Integer, Integer > apIdMap, FragmentSpace fragSpace)
Replaced a given vertex belonging to this graph with a new vertex generated specifically for this pur...
Vertex getVertexWithId(long vid)
Searches for a vertex with the given identifier.
DGraph extractSubgraph(int index)
Creates a new graph that corresponds to the subgraph of this graph when exploring the spanning tree f...
boolean isIsomorphicTo(DGraph other)
Checks if this graph is "DENOPTIM-isomorphic" to the other one given.
ArrayList< Ring > getRingsInvolvingVertex(Vertex v)
Returns the list of rings that include the given vertex in their fundamental cycle.
void getChildrenTree(Vertex vertex, List< Vertex > children)
Gets all the children of the current vertex recursively.
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.
Vertex getDeepestAmongThese(List< Vertex > list)
Identify the oldest ancestor (i.e., most great grandparent) in the given collection.
String getBranchIdOfVertexAsStr(Vertex v)
Returns the branch identifier as a literal string.
List< AttachmentPoint > getAvailableAPsThroughout()
Returns the list of attachment points contained in this graph that are available throughout the templ...
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< AttachmentPoint > getInterfaceAPs(List< Vertex > subGraphB)
Searches for all AttachmentPoints that represent the interface between a subgraph,...
DGraph clone()
Returns almost "deep-copy" of this graph.
boolean replaceSubGraph(List< Vertex > subGrpVrtxs, DGraph incomingGraph, LinkedHashMap< AttachmentPoint, AttachmentPoint > apMap, FragmentSpace fragSpace)
Replaced the subgraph represented by a given collection of vertices that belong to this graph.
int getLevel(Vertex v)
Calculates the level of a vertex in this graph.
void addSymmetricSetOfVertices(SymmetricVertexes symSet)
Adds a symmetric set of vertices to this graph.
SymmetricVertexes getSymSetForVertex(Vertex v)
Returns the set of vertexes symmetric to the given one.
List< AttachmentPoint > getSubgraphAPs(List< Vertex > subGraphB)
Searches for all AttachmentPoints that are owned by vertices in a subgraph but either available or us...
boolean hasSymmetryInvolvingVertex(Vertex v)
boolean insertVertex(Edge edge, int bbId, BBType bbt, LinkedHashMap< AttachmentPoint, Integer > apMap, FragmentSpace fragSpace)
Inserts a given vertex in between two vertices connected by the given edge.
void getChildTreeLimited(Vertex vertex, List< Vertex > children, boolean stopBeforeRCVs)
Gets all the children of the current vertex recursively.
boolean removeBranchStartingAt(Vertex v, boolean symmetry)
Deletes the branch, i.e., the specified vertex and its children.
Template getTemplateJacket()
boolean removeChainUpToBranching(Vertex v, FragmentSpace fragSpace)
Mutates the graph by removing the chain where a given vertex is located up to the first branching (i....
void setLocalMsg(String msg)
boolean isIsostructuralTo(DGraph other)
Checks if this graph is "DENOPTIM-isostructural" to the other one given.
This class represents the edge between two vertices.
AttachmentPoint getTrgAP()
AttachmentPoint getSrcAP()
This class represents the closure of a ring in a spanning tree.
A collection of AttachmentPoints that are related by a relation that we call "symmetry",...
boolean add(T item)
Adds an item to this list, if not already present.
A collection of Vertexs that are related by a relation that we call "symmetry", even though this clas...
ContractLevel getContractLevel()
Returns the contract level of this template, i.e., to what extent the content of this template can be...
void clearIAtomContainer()
Removes the molecular representation.
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
abstract Vertex clone()
Returns a deep-copy of this vertex.
List< AttachmentPoint > getAPsWithAPClassStartingWith(String root)
Finds only APs that have APClass starting with the given string.
int getBuildingBlockId()
Returns the index of the building block that should correspond to the position of the building block ...
Edge getEdgeToParent()
Looks into the edges that use any of the APs that belong to this vertex and returns the edge that has...
void setVertexId(long vertexId2)
Vertex getParent()
Looks into the edges that use any of the APs that belong to this vertex and returns the vertex which ...
Vertex.BBType getBuildingBlockType()
DGraph getGraphOwner()
Returns the graph this vertex belongs to or null.
ArrayList< Vertex > getChilddren()
Looks into the edges that use any of the APs that belong to this vertex and returns the list of verti...
Object getProperty(Object property)
abstract int getHeavyAtomsCount()
ArrayList< AttachmentPoint > getFreeAPThroughout()
Gets attachment points that are availability throughout the graph level, i.e., checks also across the...
AttachmentPoint getAP(int i)
Get attachment point i on this vertex.
static Vertex newVertexFromLibrary(int bbId, Vertex.BBType bbt, FragmentSpace fragSpace)
Builds a new molecular fragment kind of vertex.
ChainLink represents a vertex in a closable chain.
Vertex.BBType getFragType()
ClosableChain represents a chain of fragments (chain links) that is closable (or candidate closable).
This object represents a path in a DGraph.
int getPathLength()
Returns the length of the list of edges involved in this path.
List< Vertex > getVertecesPath()
Returns the list of verteces involved.
A class for iterating over sets of ring combinations generated by considering any constrain and setti...
The RingClosingAttractor represent the available valence/connection that allows to close a ring.
static final Map< APClass, APClass > RCAAPCMAP
Recognized APClasses on RingClosingAttractor and compatible types.
Parameters and setting related to handling ring closures.
void allowRingClosures(boolean value)
List< Integer > getRingSizeBias()
boolean selectFragmentsFromClosableChains()
Utility methods for input/output.
static void writeGraphToSDF(File file, DGraph graph, boolean append, boolean make3D, Logger logger, Randomizer randomizer)
Writes the graph to SDF file.
A collection of counters user to count actions taken by the evolutionary algorithm.
Tool to build build three-dimensional (3D) tree-like molecular structures from DGraph.
void setAlignBBsIn3D(boolean align)
Sets the flag that controls whether building blocks have to be aligned according to the AP vectors or...
IAtomContainer convertGraphTo3DAtomContainer(DGraph graph)
Created a three-dimensional molecular representation from a given DGraph.
RunTimeParameters getParameters(ParametersType type)
Randomizer getRandomizer()
Returns the current program-specific randomizer.
Parameters for genetic algorithm.
static synchronized void ensureVertexIDConsistency(long l)
Method used to ensure consistency between internal atomic integer and vertex id from imported graphs.
static synchronized long getUniqueVertexIndex()
Unique counter for the number of graph vertices generated.
Tool to generate random numbers and random decisions.
boolean nextBoolean()
Returns the next pseudo-random, uniformly distributed boolean value from this random number generator...
public< T > T randomlyChooseOne(Collection< T > c)
Chooses one member among the given collection.
Enum specifying to what extent the template's inner graph can be changed.
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.
static BBType parseInt(int i)
Translates the integer into the enum.
FAILEDMUTATTEMTS_PERFORM_NOADDLINK_EDIT
FAILEDMUTATTEMTS_PERFORM_NODELETE
FAILEDMUTATTEMTS_PERFORM_NOADDRING
FAILEDMUTATTEMTS_PERFORM_NOADDLINK_FIND
FAILEDMUTATTEMTS_PERFORM_NODELLINK_EDIT
FAILEDMUTATTEMTS_PERFORM_NOADDRING_NORINGCOMB
FAILEDMUTATTEMTS_PERFORM_NOADDFUSEDRING_NOSITE
FAILEDMUTATTEMTS_PERFORM_NOADDFUSEDRING_NOBRIDGE
FAILEDMUTATTEMTS_PERFORM_NOOWNER
FAILEDMUTATTEMTS_PERFORM_NOADDLINK
FAILEDMUTATTEMTS_PERFORM_NOEXTEND
FAILEDMUTATTEMTS_PERFORM_NOMUTSITE
FAILEDMUTATTEMTS_PERFORM_NOADDFUSEDRING_NOFREEAP
FAILEDMUTATTEMTS_PERFORM_NODELETECHAIN
FAILEDMUTATTEMTS_PERFORM_NOCHANGELINK_EDIT
FAILEDMUTATTEMTS_PERFORM_NOCHANGELINK
FAILEDMUTATTEMTS_PERFORM_NOCHANGEBRANCH
FAILEDMUTATTEMTS_PERFORM_NOADDRING_NOFREEAP
FAILEDMUTATTEMTS_PERFORM_BADMUTTYPE
FAILEDMUTATTEMTS_PERFORM_NOCHANGELINK_FIND
Identifier of the type of parameters.
FS_PARAMS
Parameters pertaining the definition of the fragment space.
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...
DELETECHAIN
Removes a vertex and all its neighbors recursively until a branching point, i.e., until a vertex that...