From e434b28b3ef5a16324559fb265b5fb38a0e36d86 Mon Sep 17 00:00:00 2001 From: msoroush Date: Fri, 27 Sep 2019 13:44:00 -0400 Subject: [PATCH] Improve the efficiency of regrowth move for branched molecules. In branching point, we keep the configuration of all the branches, except one, to rebuild it using CBMC algorithm --- src/cbmc/DCCyclic.cpp | 83 +++++++++++++++++++++---------------------- src/cbmc/DCCyclic.h | 2 +- src/cbmc/DCGraph.cpp | 76 +++++++++++++++++++-------------------- src/cbmc/DCGraph.h | 2 +- 4 files changed, 80 insertions(+), 83 deletions(-) diff --git a/src/cbmc/DCCyclic.cpp b/src/cbmc/DCCyclic.cpp index e7b95db24..774023449 100644 --- a/src/cbmc/DCCyclic.cpp +++ b/src/cbmc/DCCyclic.cpp @@ -399,19 +399,18 @@ void DCCyclic::Regrowth(TrialMol& oldMol, TrialMol& newMol, uint molIndex) newMol.AddAtom(partner, oldMol.AtomPosition(partner)); oldMol.ConfirmOldAtom(partner); } - - if(nodes[current].edges.size() == 1) { - //If current is the terminal node, continue building all edges - BuildEdges(oldMol, newMol, molIndex, current); - } else { - //First we pick a edge and continue copying the coordinate - //Then continue to build the rest of the molecule from current - //Copy the edges of the node to fringe - fringe = nodes[current].edges; + //First we pick a edge that will be fix and continue copy the coordinate + //We continue the same until only one edge left from this node + //If current is the terminal node, we dont enter to while loop + //Then continue to build the rest of the molecule from current + + //Copy the edges of the node to currFringe + currFringe = nodes[current].edges; + while (currFringe.size() > 1) { //randomely pick one one of the edges connected to fixNode - uint pickFixEdg = data.prng.randIntExc(fringe.size()); + uint pickFixEdg = data.prng.randIntExc(currFringe.size()); //Travel to picked edges and make it as new fixNode - uint fixNode = fringe[pickFixEdg].destination; + uint fixNode = currFringe[pickFixEdg].destination; visited[fixNode] = true; destVisited[nodes[fixNode].atomIndex] = true; //Copy the all atoms bonded to fixNode's focus @@ -440,7 +439,7 @@ void DCCyclic::Regrowth(TrialMol& oldMol, TrialMol& newMol, uint molIndex) newMol.AddAtom(partner, oldMol.AtomPosition(partner)); oldMol.ConfirmOldAtom(partner); } - //Travel to new fixNode, remove traversed edge + //Travel to new fixNode, remove traverled edge fringe[0] = fringe.back(); fringe.pop_back(); visited[fixNode] = true; @@ -453,38 +452,38 @@ void DCCyclic::Regrowth(TrialMol& oldMol, TrialMol& newMol, uint molIndex) } } } - //Now Start building the rest of the molecule from current - //Copy the edges of the current node to fringe - fringe = nodes[current].edges; - //Remove the fixed edge from fringe - fringe.erase(fringe.begin() + pickFixEdg); - for(uint i = 0; i < fringe.size(); i++) { - destVisited[fringe[i].atomIndex] = true; - } - //Advance along edges, building as we go - while(!fringe.empty()) { - //Randomely pick one of the edges connected to node - uint pick = data.prng.randIntExc(fringe.size()); - DCComponent* comp = fringe[pick].connect; - //Call DCLinkedHedron and build all Atoms connected to selected edge - comp->PrepareNew(newMol, molIndex); - comp->BuildNew(newMol, molIndex); - comp->PrepareOld(oldMol, molIndex); - comp->BuildOld(oldMol, molIndex); - current = fringe[pick].destination; - //Remove the edge that we visited - fringe[pick] = fringe.back(); - fringe.pop_back(); - visited[current] = true; - for(uint i = 0; i < nodes[current].edges.size(); ++i) { - Edge& e = nodes[current].edges[i]; - if(!visited[e.destination] && !destVisited[e.atomIndex]) { - fringe.push_back(e); - destVisited[e.atomIndex] = true; - } + //Remove the fixed edge from currFring + currFringe.erase(currFringe.begin() + pickFixEdg); + } + + for(uint i = 0; i < currFringe.size(); i++) { + destVisited[currFringe[i].atomIndex] = true; + } + //Now Start building the rest of the molecule from current + //Start with only one left edge + //Advance along edges, building as we go + while(!currFringe.empty()) { + //Randomely pick one of the edges connected to node + uint pick = data.prng.randIntExc(currFringe.size()); + DCComponent* comp = currFringe[pick].connect; + //Call DCLinkedCycle and build all Atoms connected to selected edge + comp->PrepareNew(newMol, molIndex); + comp->BuildNew(newMol, molIndex); + comp->PrepareOld(oldMol, molIndex); + comp->BuildOld(oldMol, molIndex); + current = currFringe[pick].destination; + //Remove the edge that we visited + currFringe[pick] = currFringe.back(); + currFringe.pop_back(); + visited[current] = true; + for(uint i = 0; i < nodes[current].edges.size(); ++i) { + Edge& e = nodes[current].edges[i]; + if(!visited[e.destination] && !destVisited[e.atomIndex]) { + currFringe.push_back(e); + destVisited[e.atomIndex] = true; } } - } + } } } diff --git a/src/cbmc/DCCyclic.h b/src/cbmc/DCCyclic.h index 5d61e162c..2767b0ba5 100644 --- a/src/cbmc/DCCyclic.h +++ b/src/cbmc/DCCyclic.h @@ -79,7 +79,7 @@ class DCCyclic : public CBMC std::vector isRing; //To check if atom is belong to a ring std::vector ringIdx; //index to the row of cyclicAtoms std::vector nodes; - std::vector fringe; + std::vector fringe, currFringe; std::vector visited, destVisited; std::vector crankshaft; std::vector< std::vector > cyclicAtoms; diff --git a/src/cbmc/DCGraph.cpp b/src/cbmc/DCGraph.cpp index c8e6f9bbd..eb60a4768 100644 --- a/src/cbmc/DCGraph.cpp +++ b/src/cbmc/DCGraph.cpp @@ -272,19 +272,18 @@ void DCGraph::Regrowth(TrialMol& oldMol, TrialMol& newMol, uint molIndex) newMol.AddAtom(partner, oldMol.AtomPosition(partner)); oldMol.ConfirmOldAtom(partner); } - - if(nodes[current].edges.size() == 1) { - //If current is the terminal node, continue building all edges - BuildEdges(oldMol, newMol, molIndex, current); - } else { - //First we pick a edge and continue copying the coordinate - //Then continue to build the rest of the molecule from current - //Copy the edges of the node to fringe - fringe = nodes[current].edges; - //randomely pick one one of the edges connected to fixNode - uint pickFixEdg = data.prng.randIntExc(fringe.size()); + //First we pick a edge that will be fix and continue copy the coordinate + //We continue the same until only one edge left from this node + //If current is the terminal node, we dont enter to while loop + //Then continue to build the rest of the molecule from current + + //Copy the edges of the node to currFringe + currFringe = nodes[current].edges; + while (currFringe.size() > 1) { + //randomely pick one of the edges connected to current (fixNode) + uint pickFixEdg = data.prng.randIntExc(currFringe.size()); //Travel to picked edges and make it as new fixNode - uint fixNode = fringe[pickFixEdg].destination; + uint fixNode = currFringe[pickFixEdg].destination; visited[fixNode] = true; //Copy the all atoms bonded to fixNode's focus for(uint b = 0; b < nodes[fixNode].partnerIndex.size(); b++) { @@ -294,7 +293,7 @@ void DCGraph::Regrowth(TrialMol& oldMol, TrialMol& newMol, uint molIndex) } //Copy the edges of the new node to fringe fringe = nodes[fixNode].edges; - //remove the edge that we travelled from + //remove the edge that we traveled from for( uint f = 0; f < fringe.size(); f++) { if(fringe[f].destination == current) fringe.erase(fringe.begin() + f); @@ -320,34 +319,33 @@ void DCGraph::Regrowth(TrialMol& oldMol, TrialMol& newMol, uint molIndex) } } } - //Now Start building the rest of the molecule from current - //Copy the edges of the current node to fringe - fringe = nodes[current].edges; - //Remove the fixed edge from fringe - fringe.erase(fringe.begin() + pickFixEdg); - //Advance along edges, building as we go - while(!fringe.empty()) { - //Randomely pick one of the edges connected to node - uint pick = data.prng.randIntExc(fringe.size()); - DCComponent* comp = fringe[pick].component; - //Call DCLinkedHedron and build all Atoms connected to selected edge - comp->PrepareNew(newMol, molIndex); - comp->BuildNew(newMol, molIndex); - comp->PrepareOld(oldMol, molIndex); - comp->BuildOld(oldMol, molIndex); - current = fringe[pick].destination; - //Remove the edge that we visited - fringe[pick] = fringe.back(); - fringe.pop_back(); - visited[current] = true; - for(uint i = 0; i < nodes[current].edges.size(); ++i) { - Edge& e = nodes[current].edges[i]; - if(!visited[e.destination]) { - fringe.push_back(e); - } + //Remove the fixed edge from currFring + currFringe.erase(currFringe.begin() + pickFixEdg); + } + //Now Start building the rest of the molecule from current + //Start with only one left edge + //Advance along edges, building as we go + while(!currFringe.empty()) { + //Randomely pick one of the edges connected to node + uint pick = data.prng.randIntExc(currFringe.size()); + DCComponent* comp = currFringe[pick].component; + //Call DCLinkedHedron and build all Atoms connected to selected edge + comp->PrepareNew(newMol, molIndex); + comp->BuildNew(newMol, molIndex); + comp->PrepareOld(oldMol, molIndex); + comp->BuildOld(oldMol, molIndex); + current = currFringe[pick].destination; + //Remove the edge that we visited + currFringe[pick] = currFringe.back(); + currFringe.pop_back(); + visited[current] = true; + for(uint i = 0; i < nodes[current].edges.size(); ++i) { + Edge& e = nodes[current].edges[i]; + if(!visited[e.destination]) { + currFringe.push_back(e); } } - } + } } } diff --git a/src/cbmc/DCGraph.h b/src/cbmc/DCGraph.h index 12747395b..a841c6c44 100644 --- a/src/cbmc/DCGraph.h +++ b/src/cbmc/DCGraph.h @@ -74,7 +74,7 @@ class DCGraph : public CBMC DCData data; bool hasCrankShaft; std::vector nodes; - std::vector fringe; + std::vector fringe, currFringe; std::vector visited; std::vector shaftNodes; XYZArray coords;