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))
462 subGraphEndInA.add(endOnA);
463 subGraphEndInB.add(endOnB);
467 ArrayList<Vertex> subGraphA =
new ArrayList<Vertex>();
469 if (!subGraphEndInA.contains(vA))
472 ArrayList<Vertex> subGraphB =
new ArrayList<Vertex>();
474 if (!subGraphEndInB.contains(vB))
478 if (subGraphA.size()>1 && subGraphB.size()>1)
485 if (subGraphA.get(0).sameAs(subGraphB.get(0),
new StringBuilder()))
505 List<Vertex> subGraphA,
507 List<XoverSite> collector)
509 DGraph gOwnerA = subGraphA.get(0).getGraphOwner();
510 DGraph gOwnerB = subGraphB.get(0).getGraphOwner();
522 if (allAPsA.size() < needyAPsB.size()
523 || allAPsB.size() < needyAPsA.size())
540 && jacketTmplB==
null)
543 needyAPsB, xoverType);
544 if (!collector.contains(xos))
555 for (
Vertex v : subGraphA)
558 for (
Vertex v : subGraphB)
579 allAPsA, needyAPsA, allAPsB, needyAPsB,
587 subGraphB, needyAPsB, xoverType);
588 if (!collector.contains(xos))
641 DGraph graph = vertex.getGraphOwner();
689 DGraph graph = vertex.getGraphOwner();
724 return extendLink(vertex, chosenAPId, -1 , mnt, fragSpace);
761 +vertex+
" has no edge user.");
766 +
"vertex (AP "+chosenAPId+
" of vertex "+vertex+
").");
768 return extendLink(e, chosenNewVrtxId, mnt, fragSpace);
807 LinkedHashMap<AttachmentPoint,Integer> apMap =
808 new LinkedHashMap<AttachmentPoint,Integer>();
809 for (Entry<AttachmentPoint, AttachmentPoint> e :
812 apMap.put(e.getKey(), e.getValue().getIndexInOwner());
815 DGraph graph = edge.getSrcAP().getOwner().getGraphOwner();
852 boolean force,
int chosenVrtxIdx,
int chosenApId,
855 DGraph g = vertex.getGraphOwner();
858 Edge e = vertex.getEdgeToParent();
861 String msg =
"Program Bug in substituteFragment: Unable to locate "
862 +
"parent edge for vertex "+vertex+
" in graph "+g;
863 settings.getLogger().log(Level.SEVERE, msg);
878 return extendGraph(parentVrt,
false,symmetry,force,chosenVrtxIdx,
879 chosenApId, settings);
895 long vid = vertex.getVertexId();
896 DGraph molGraph = vertex.getGraphOwner();
900 List<Vertex> toRemove =
new ArrayList<Vertex>();
935 long vid = vertex.getVertexId();
936 DGraph molGraph = vertex.getGraphOwner();
940 List<Vertex> toRemove =
new ArrayList<Vertex>();
944 if (!v.getMutationTypes(
new ArrayList<MutationType>())
991 vertex.getGraphOwner().removeCappingGroups();
993 List<AttachmentPoint> freeeAPs = vertex.getFreeAPThroughout();
994 if (freeeAPs.size()==0)
999 DGraph originalGraph = vertex.getGraphOwner();
1006 List<Ring> setOfRingsOnTmpGraph =
null;
1009 APClass apc = srcAP.getAPClass();
1012 if (!fragSpace.getRCCompatibilityMatrix().containsKey(apc))
1016 List<APClass> rcTrgAPCs = fragSpace.getRCCompatibilityMatrix().get(
1020 Vertex rcvOnSrcAP =
null;
1021 List<Vertex> candidateRCVs = fragSpace.getRCVsForAPClass(apc);
1022 boolean rcvIsChosenArbitrarily =
false;
1023 if (candidateRCVs.size()>0)
1027 rcvIsChosenArbitrarily =
true;
1028 rcvOnSrcAP = fragSpace.getPolarizedRCV(
true);
1032 List<Vertex> rcvAddedToGraph =
new ArrayList<Vertex>();
1034 rcvAddedToGraph.add(rcvOnSrcAP);
1039 for (
int i=0; i<20; i++)
1042 List<AttachmentPoint> apsToTry =
1044 int numberOfAttempts = apsToTry.size();
1046 for (
int iap=0; iap<numberOfAttempts; iap++)
1049 if (rcTrgAPCs.contains(candidate.
getAPClass()))
1054 apsToTry.remove(trgAP);
1063 Vertex rcvOnTrgAP =
null;
1064 if (rcvIsChosenArbitrarily)
1066 rcvOnTrgAP = fragSpace.getPolarizedRCV(
false);
1068 List<Vertex> candRCVs = fragSpace.getRCVsForAPClass(
1070 if (candRCVs.size()>0)
1074 List<Vertex> keptRCVs =
new ArrayList<Vertex>();
1075 for (
Vertex rcv : candRCVs)
1077 if (requiredAPC.
equals(rcv.getAP(0).getAPClass()))
1081 if (rcvOnTrgAP==
null)
1096 rcvAddedToGraph.add(rcvOnTrgAP);
1098 if (rcvAddedToGraph.size() < 2)
1107 settings.getLogger(), rng);
1113 settings.getMaxRingsAddedByMutation(),
1114 fragSpace, rcParams);
1120 setOfRingsOnTmpGraph = rCombIter.
next();
1123 if (setOfRingsOnTmpGraph.size()>0)
1127 for (
Vertex toRemove : rcvAddedToGraph)
1130 if (setOfRingsOnTmpGraph==
null || setOfRingsOnTmpGraph.size()==0)
1137 boolean done =
false;
1138 for (
Ring rOnTmp : setOfRingsOnTmpGraph)
1142 tmpGraph.
indexOf(rOnTmp.getHeadVertex().getParent()));
1144 rOnTmp.getHeadVertex().getEdgeToParent().getSrcAP()
1145 .getIndexInOwner());
1151 headRCV = rOnTmp.getHeadVertex().
clone();
1159 tmpGraph.
indexOf(rOnTmp.getTailVertex().getParent()));
1161 rOnTmp.getTailVertex().getEdgeToParent().getSrcAP()
1162 .getIndexInOwner());
1168 tailRCV = rOnTmp.getTailVertex().
clone();
1175 originalGraph.
addRing(headRCV, tailRCV);
1180 vertex.getGraphOwner().addCappingGroups(fragSpace);
1217 vertex.getGraphOwner().removeCappingGroups();
1219 List<AttachmentPoint> freeAPs = vertex.getFreeAPThroughout();
1220 if (freeAPs.size()==0)
1226 DGraph graph = vertex.getGraphOwner();
1231 List<List<RelatedAPPair>> candidatePairsSets =
1236 rng.
nextBoolean(settings.getSymmetryProbability()),
1237 settings.getLogger(), rng);
1238 if (candidatePairsSets.size()==0)
1248 List<List<RelatedAPPair>> szBiasedCandidatePairsSets =
1249 new ArrayList<List<RelatedAPPair>>();
1250 for (List<RelatedAPPair> pairSet : candidatePairsSets)
1253 pairSet.get(0).property;
1257 for (
int i=0; i<allowedBridgeLengths.length; i++)
1259 int allowedBridgeLength = allowedBridgeLengths[i];
1260 int possibleRingSize = allowedBridgeLength
1261 + existingBridgeLength;
1271 for (
int z=0; z<weight; z++)
1273 szBiasedCandidatePairsSets.add(pairSet);
1277 if (szBiasedCandidatePairsSets.size()==0)
1285 szBiasedCandidatePairsSets);
1290 String elsInHalfFrag = chosenPairsSet.get(0).propID.substring(0,1);
1291 if (elsInHalfFrag.matches(
"[a-zA-Z]"))
1292 elsInHalfFrag =
"0";
1293 boolean newRingIsAromatic =
true;
1294 String elInIncomingFrag =
"0el";
1295 switch (elsInHalfFrag)
1300 elInIncomingFrag =
"0el";
1301 newRingIsAromatic =
false;
1307 elInIncomingFrag =
"4el";
1313 elInIncomingFrag =
"3el";
1318 elInIncomingFrag =
"2el";
1324 elInIncomingFrag =
"1el";
1327 throw new Error(
"Unknown number of pi-electrons in fragment to "
1328 +
"be used for ring fusion operation.");
1334 chosenPairsSet.get(0).property;
1336 List<Vertex> usableBridges =
null;
1337 if (newRingIsAromatic)
1347 chosenPairsSet.get(0).apA.getAPClass(),
1348 chosenPairsSet.get(0).apB.getAPClass(),
1353 if (usableBridges.size()==0)
1362 List<Vertex> szBiasedUsableBridges =
new ArrayList<Vertex>();
1363 for (
Vertex candidateBridge : usableBridges)
1365 int thisBridgeLength = (int) candidateBridge.getProperty(
1368 int resultingRingSize = existingBridgeLength + thisBridgeLength;
1378 for (
int z=0; z<weigth; z++)
1380 szBiasedUsableBridges.add(candidateBridge);
1384 if (szBiasedUsableBridges.size()==0)
1393 List<AttachmentPoint> apsInFusion =
new ArrayList<AttachmentPoint>();
1394 int[] idApOnBridge =
new int[2];
1395 if (newRingIsAromatic)
1401 idApOnBridge[0] = apsInFusion.get(0).getIndexInOwner();
1402 idApOnBridge[1] = apsInFusion.get(1).getIndexInOwner();
1404 idApOnBridge[0] = apsInFusion.get(1).getIndexInOwner();
1405 idApOnBridge[1] = apsInFusion.get(0).getIndexInOwner();
1408 idApOnBridge[0] = Integer.parseInt(incomingVertex.
getProperty(
1410 idApOnBridge[1] = Integer.parseInt(incomingVertex.
getProperty(
1414 boolean done =
false;
1425 Vertex rcvBridge = fragSpace.getPolarizedRCV(
true);
1427 rcvBridge.
getAP(0));
1429 Vertex rcvTail = fragSpace.getPolarizedRCV(
false);
1431 graph.
addRing(rcvBridge, rcvTail);
1436 vertex.getGraphOwner().addCappingGroups(fragSpace);
1459 boolean symmetryOnAps,
1463 return extendGraph(curVertex, extend, symmetryOnAps,
false, -1, -1,
1494 boolean symmetryOnAps,
1517 boolean status =
false;
1520 if (!curVrtx.hasFreeAP())
1525 DGraph molGraph = curVrtx.getGraphOwner();
1526 int lvl = molGraph.
getLevel(curVrtx);
1528 ArrayList<Long> addedVertices =
new ArrayList<>();
1530 List<AttachmentPoint> lstDaps = curVrtx.getAttachmentPoints();
1531 List<AttachmentPoint> toDoAPs =
new ArrayList<AttachmentPoint>();
1532 toDoAPs.addAll(lstDaps);
1533 for (
int i=0; i<lstDaps.size(); i++)
1554 boolean allowOnlyRingClosure =
false;
1566 double extendGraphProb = molSizeProb * byLevelProb * crowdingProb;
1567 boolean fgrow = settings.getRandomizer().nextBoolean(
1572 && settings.getRandomizer().nextBoolean(byLevelProb
1575 allowOnlyRingClosure =
true;
1583 if (!allowOnlyRingClosure
1588 apId, molGraph, addedVertices, settings);
1597 if (allowOnlyRingClosure)
1622 if ((curVrtx.getGraphOwner().getHeavyAtomsCount() +
1632 settings.getSymmetryProbability(),
1635 if (curVrtx.getSymmetricAPs(ap).size()!=0
1636 && (cpOnSymAPs || symmetryOnAps)
1637 && !allowOnlyRingClosure)
1639 symAPs.addAll(curVrtx.getSymmetricAPs(ap));
1642 boolean allOnSameSrc =
true;
1645 if (!symAP.hasSameSrcAtom(ap))
1647 allOnSameSrc =
false;
1664 crowdedness = crowdedness + 1;
1668 double shot = settings.getRandomizer().nextDouble();
1677 crowdedness, settings);
1679 if (shot > crowdProb)
1683 crowdedness = crowdedness + 1;
1703 symVerts.
add(curVrtx);
1707 if ((curVrtx.getGraphOwner().getHeavyAtomsCount() +
1709 * symAPs.size()) > maxHeavyAtoms)
1715 List<AttachmentPoint> allAPsFromSymVerts =
new ArrayList<>();
1716 for (
Vertex symVrt : symVerts)
1721 apOnVrt.getIndexInOwner());
1725 if (apOnVrt.sameAs(apOnSymVrt)
1727 && !symAPs.contains(apOnSymVrt))
1729 allAPsFromSymVerts.add(apOnSymVrt);
1733 symAPs.addAll(allAPsFromSymVerts);
1741 if (!symAP.isAvailable())
1757 addedVertices.add(newVrtId);
1758 newSymSetOfVertices.
add(fragVertex);
1762 if (newSymSetOfVertices.size() > 1)
1771 for (
int i=0; i<addedVertices.size(); i++)
1773 long vid = addedVertices.get(i);
1779 if (addedVertices.size() > 0)
1824 int dapidx,
int chosenVrtxIdx,
int chosenApId,
1827 List<AttachmentPoint> lstDaps = curVertex.getAttachmentPoints();
1833 if (!fragSpace.useAPclassBasedApproach())
1835 int fid = fragSpace.getRandomizer().nextInt(
1836 fragSpace.getFragmentLibrary().size());
1841 List<IdFragmentAndAP> candidates =
1842 fragSpace.getFragAPsCompatibleWithClass(
1844 if (candidates.size() > 0)
1846 if (chosenVrtxIdx>-1 && chosenApId>-1)
1852 res = fragSpace.getRandomizer().randomlyChooseOne(candidates);
1878 List<Vertex> rcvs = fragSpace.getRCVs();
1880 if (!fragSpace.useAPclassBasedApproach())
1884 List<Vertex> candidates = fragSpace.getRCVsForAPClass(
1886 if (candidates.size() > 0)
1906 boolean res =
false;
1916 curVertex, dapidx, molGraph);
1927 int numCands = lscFfCc.size();
1930 int chosenId = settings.getRandomizer().nextInt(numCands);
1932 ArrayList<Integer> newFragIds = chosenFfCc.
getFragIDs();
1933 int molIdNewFrag = newFragIds.get(0);
1935 int dapNewFrag = newFragIds.get(2);
1936 if (molIdNewFrag != -1)
1940 newvid, molIdNewFrag, typeNewFrag,
1943 molGraph.appendVertexOnAP(curVertex.getAP(dapidx),
1944 newVrtx.
getAP(dapNewFrag));
1948 addedVertices.add(newvid);
1950 molGraph.getClosableChains().removeAll(
1952 APClass apc = curVertex.getAttachmentPoints().get(
1953 dapidx).getAPClass();
1956 settings.getSymmetryProbability(),
1965 String msg =
"BUG: Incorrect vertex num. Contact author.";
1966 settings.getLogger().log(Level.SEVERE, msg);
2042 ArrayList<FragForClosabChains> lstChosenFfCc =
2043 new ArrayList<FragForClosabChains>();
2045 if (molGraph.getClosableChains().size() == 0)
2047 return lstChosenFfCc;
2054 int posInCc = cc.involvesVertex(curVertex);
2069 if (cc.getSize() > (posInCc+1))
2072 ChainLink nextChainLink = cc.getLink(posInCc+1);
2073 nfid = nextChainLink.
getIdx();
2085 if ((posInCc-1) >= 0)
2088 ChainLink nextChainLink = cc.getLink(posInCc-1);
2089 nfid = nextChainLink.
getIdx();
2100 ArrayList<Integer> eligibleFrgId =
new ArrayList<Integer>();
2101 eligibleFrgId.add(nfid);
2102 eligibleFrgId.add(nfty.
toOldInt());
2103 eligibleFrgId.add(nfap);
2104 boolean found =
false;
2107 int fidA = ffcc.getFragIDs().get(0);
2109 int fapA = ffcc.getFragIDs().get(2);
2110 if (nfid==fidA && nfty==ftyA && nfap==fapA)
2113 ffcc.getCompatibleCC().add(cc);
2117 ffcc.getIncompatibleCC().add(cc);
2122 ArrayList<ClosableChain> compatChains =
2123 new ArrayList<ClosableChain>();
2124 ArrayList<ClosableChain> incompatChains =
2125 new ArrayList<ClosableChain>();
2128 incompatChains.addAll(otherFfCc.getCompatibleCC());
2136 lstChosenFfCc.add(newChosenCc);
2143 Edge edge = molGraph.getEdgeWithParent(
2144 curVertex.getVertexId());
2151 int posInCc = cc.involvesVertexAndAP(curVertex, dapidx, chidAp);
2165 List<Integer> altertnativeDirections =
new ArrayList<>();
2166 altertnativeDirections.add(-1);
2167 altertnativeDirections.add(+1);
2168 for (
int altDir : altertnativeDirections)
2170 ChainLink parentLink = cc.getLink(posInCc + altDir);
2171 int pLnkId = parentLink.
getIdx();
2184 if (pLnkId==prntId && pLnkTyp==prntTyp && pLnkAp == prntAp &&
2187 if (cc.getSize() > (posInCc+altDir)
2188 && (posInCc+altDir) >= 0)
2190 ChainLink nextChainLink = cc.getLink(posInCc + altDir);
2191 nfid = nextChainLink.
getIdx();
2208 ArrayList<Integer> eligibleFrgId =
new ArrayList<Integer>();
2209 eligibleFrgId.add(nfid);
2210 eligibleFrgId.add(nfty.
toOldInt());
2211 eligibleFrgId.add(nfap);
2212 boolean found =
false;
2215 int fidA = ffcc.getFragIDs().get(0);
2217 int fapA = ffcc.getFragIDs().get(2);
2218 if (nfid==fidA && nfty==ftyA && nfap==fapA)
2221 ffcc.getCompatibleCC().add(cc);
2225 ffcc.getIncompatibleCC().add(cc);
2230 ArrayList<ClosableChain> compatChains =
2231 new ArrayList<ClosableChain>();
2232 ArrayList<ClosableChain> incompatChains =
2233 new ArrayList<ClosableChain>();
2236 incompatChains.addAll(otherFfCc.getCompatibleCC());
2243 lstChosenFfCc.add(newChosenCc);
2247 return lstChosenFfCc;
2265 DGraph gA = site.getA().get(0).getGraphOwner();
2266 DGraph gB = site.getB().get(0).getGraphOwner();
2269 List<AttachmentPoint> allAPsOnA = gA.
getSubgraphAPs(site.getA());
2270 List<AttachmentPoint> allAPsOnB = gB.
getSubgraphAPs(site.getB());
2274 List<AttachmentPoint> needyAPsOnA = site.getAPsNeedingMappingA();
2275 List<AttachmentPoint> needyAPsOnB = site.getAPsNeedingMappingB();
2282 if (!ap.isSrcInUserThroughout())
2291 if (!ap.isSrcInUserThroughout())
2298 if (apToParentA==
null || apToParentB==
null)
2301 +
"point connecting a subgraph to the rest of the graph. "
2302 +
"This violates assumption that crossover does not "
2303 +
"involve scaffold or vertexes without parent.");
2316 fixedRootAPs.put(apToParentA, apToParentB);
2322 allAPsOnA, needyAPsOnA,
2323 allAPsOnB, needyAPsOnB, fixedRootAPs,
2342 LinkedHashMap<AttachmentPoint,AttachmentPoint>
2343 apMapA =
new LinkedHashMap<AttachmentPoint,AttachmentPoint>();
2344 LinkedHashMap<AttachmentPoint,AttachmentPoint>
2345 apMapB =
new LinkedHashMap<AttachmentPoint,AttachmentPoint>();
2360 apMapA.put(apOnA, apOnSubGraphB);
2361 apMapB.put(apOnB, apOnSubGraphA);
2388 double symmetryProbability,
Randomizer randomizer)
2422 List<Vertex> mutable = graph.getMutableSites(
2423 settings.getExcludedMutationTypes());
2431 Vertex vA = site.apA.getOwner();
2432 Vertex vB = site.apB.getOwner();
2433 if (!mutable.contains(vA))
2435 if (!mutable.contains(vB))
2440 if (mutable.size() == 0)
2443 String msg =
"Graph has no mutable site. Mutation aborted.";
2444 settings.getLogger().info(msg);
2447 boolean doneMutation =
true;
2449 settings.getMultiSiteMutationWeights(),
2450 settings.getRandomizer().nextDouble());
2451 for (
int i=0; i<numberOfMutations; i++)
2455 mutable = graph.getMutableSites(
2456 settings.getExcludedMutationTypes());
2459 Vertex v = settings.getRandomizer().randomlyChooseOne(mutable);
2464 return doneMutation;
2485 List<MutationType> mTypes = vertex.getMutationTypes(
2486 settings.getExcludedMutationTypes());
2487 if (mTypes.size() == 0)
2491 MutationType mType = settings.getRandomizer().randomlyChooseOne(mTypes);
2513 int pos = vertex.getGraphOwner().
indexOf(vertex);
2517 }
catch (IllegalArgumentException|NullPointerException e)
2519 String debugFile =
"failedMutation_" + mType
2520 +
"_" + vertex.getVertexId() +
"(" + pos +
")_"
2521 + settings.timeStamp +
".sdf";
2523 settings.getLogger(), settings.getRandomizer());
2524 settings.getLogger().warning(
"Fatal exception while performing "
2525 +
"mutation. See file '" + debugFile +
"' to reproduce the "
2570 DGraph graph = vertex.getGraphOwner();
2574 settings.getLogger().info(
"Vertex has no owner - "
2575 +
"Mutation aborted");
2578 if (!vertex.getMutationTypes(settings.getExcludedMutationTypes())
2582 settings.getLogger().info(
"Vertex does not allow mutation type "
2583 +
"'" + mType +
"' - Mutation aborted");
2588 int positionOfVertex = graph.
indexOf(vertex);
2595 +
" (" + positionOfVertex +
")";
2598 boolean done =
false;
2602 done =
rebuildBranch(vertex, force, chosenVrtxIdx, chosenApId,
2635 List<Integer> candidates =
new ArrayList<Integer>();
2638 candidates.add(c.getEdgeToParent().getSrcAP()
2639 .getIndexInOwner());
2641 if (candidates.size() == 0)
2647 chosenApId = settings.getRandomizer().randomlyChooseOne(
2650 done =
extendLink(vertex, chosenApId, chosenVrtxIdx, mnt,
2672 vertex.getGraphOwner().removeCappingGroupsOn(vertex);
2673 done =
extendGraph(vertex,
false,
false, force, chosenVrtxIdx,
2674 chosenApId, settings);
2686 String msg =
"Mutation '" + mType.toString() +
"' on vertex "
2687 + vertex.toString() +
" (position " + positionOfVertex
2688 +
" in graph " + graphId+
"): ";
2700 msg = msg +
"unsuccessful";
2702 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...