- Timestamp:
- Oct 18, 2009, 7:58:38 PM (15 years ago)
- Branches:
- Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
- Children:
- 4455f4
- Parents:
- 43587e
- git-author:
- Frederik Heber <heber@…> (10/18/09 19:41:20)
- git-committer:
- Frederik Heber <heber@…> (10/18/09 19:58:38)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/molecule_graph.cpp
r43587e r9eefda 16 16 #include "molecule.hpp" 17 17 18 struct BFSAccounting 19 { 20 atom **PredecessorList; 21 int *ShortestPathList; 22 enum Shading *ColorList; 23 class StackClass<atom *> *BFSStack; 24 class StackClass<atom *> *TouchedStack; 25 int AtomCount; 26 int BondOrder; 27 atom *Root; 28 bool BackStepping; 29 int CurrentGraphNr; 30 int ComponentNr; 31 }; 32 33 /** Accounting data for Depth First Search. 34 */ 35 struct DFSAccounting 36 { 37 class StackClass<atom *> *AtomStack; 38 class StackClass<bond *> *BackEdgeStack; 39 int CurrentGraphNr; 40 int ComponentNumber; 41 atom *Root; 42 bool BackStepping; 43 }; 44 18 45 /************************************* Functions for class molecule *********************************/ 19 20 46 21 47 /** Creates an adjacency list of the molecule. … … 29 55 atom *Walker, *OtherWalker; 30 56 31 if (!input) 32 { 57 if (!input) { 33 58 cout << Verbose(1) << "Opening silica failed \n"; 34 59 }; … … 42 67 *input >> ws >> atom2; 43 68 44 if (atom2<atom1) //Sort indices of atoms in order69 if (atom2 < atom1) //Sort indices of atoms in order 45 70 flip(atom1, atom2); 46 Walker =FindAtom(atom1);47 OtherWalker =FindAtom(atom2);71 Walker = FindAtom(atom1); 72 OtherWalker = FindAtom(atom2); 48 73 AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices. 49 74 } 50 } ;51 75 } 76 ; 52 77 53 78 /** Creates an adjacency list of the molecule. … … 83 108 *out << Verbose(0) << "Begin of CreateAdjacencyList." << endl; 84 109 // remove every bond from the list 85 if ((first->next != last) && (last->previous != first)) { 86 cleanup(first, last);110 if ((first->next != last) && (last->previous != first)) { // there are bonds present 111 cleanup(first, last); 87 112 } 88 113 … … 95 120 96 121 // create a list to map Tesselpoint::nr to atom * 97 AtomMap = Malloc<atom *> (AtomCount, "molecule::CreateAdjacencyList - **AtomCount");122 AtomMap = Malloc<atom *> (AtomCount, "molecule::CreateAdjacencyList - **AtomCount"); 98 123 Walker = start; 99 124 while (Walker->next != end) { … … 113 138 //*out << Verbose(0) << "Current Atom is " << *Walker << "." << endl; 114 139 // 3c. check for possible bond between each atom in this and every one in the 27 cells 115 for (n[0] =-1;n[0]<=1;n[0]++)116 for (n[1] =-1;n[1]<=1;n[1]++)117 for (n[2] =-1;n[2]<=1;n[2]++) {140 for (n[0] = -1; n[0] <= 1; n[0]++) 141 for (n[1] = -1; n[1] <= 1; n[1]++) 142 for (n[2] = -1; n[2] <= 1; n[2]++) { 118 143 OtherList = LC->GetRelativeToCurrentCell(n); 119 144 //*out << Verbose(2) << "Current relative cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << " containing " << List->size() << " points." << endl; … … 124 149 //*out << Verbose(1) << "Checking distance " << OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size) << " against typical bond length of " << bonddistance*bonddistance << "." << endl; 125 150 MinDistance = OtherWalker->type->CovalentRadius + Walker->type->CovalentRadius; 126 MinDistance *= (IsAngstroem) ? 1. : 1. /AtomicLengthToAngstroem;151 MinDistance *= (IsAngstroem) ? 1. : 1. / AtomicLengthToAngstroem; 127 152 MaxDistance = MinDistance + BONDTHRESHOLD; 128 153 MinDistance -= BONDTHRESHOLD; 129 154 distance = OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size); 130 if ((OtherWalker->father->nr > Walker->father->nr) && (distance <= MaxDistance *MaxDistance) && (distance >= MinDistance*MinDistance)) { // create bond if distance is smaller155 if ((OtherWalker->father->nr > Walker->father->nr) && (distance <= MaxDistance * MaxDistance) && (distance >= MinDistance * MinDistance)) { // create bond if distance is smaller 131 156 //*out << Verbose(1) << "Adding Bond between " << *Walker << " and " << *OtherWalker << " in distance " << sqrt(distance) << "." << endl; 132 AddBond(Walker->father, OtherWalker->father, 1); 157 AddBond(Walker->father, OtherWalker->father, 1); // also increases molecule::BondCount 133 158 } else { 134 159 //*out << Verbose(1) << "Not Adding: Wrong label order or distance too great." << endl; … … 142 167 } 143 168 Free(&AtomMap); 144 delete (LC);169 delete (LC); 145 170 *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << BondDistance << "." << endl; 146 171 … … 149 174 150 175 // output bonds for debugging (if bond chain list was correctly installed) 151 ActOnAllAtoms( &atom::OutputBondOfAtom, out);176 ActOnAllAtoms(&atom::OutputBondOfAtom, out); 152 177 } else 153 178 *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl; 154 179 *out << Verbose(0) << "End of CreateAdjacencyList." << endl; 155 }; 180 } 181 ; 156 182 157 183 /** Prints a list of all bonds to \a *out. … … 162 188 *out << Verbose(1) << endl << "From contents of bond chain list:"; 163 189 bond *Binder = first; 164 while (Binder->next != last) {190 while (Binder->next != last) { 165 191 Binder = Binder->next; 166 192 *out << *Binder << "\t" << endl; 167 193 } 168 194 *out << endl; 169 }; 195 } 196 ; 170 197 171 198 /** correct bond degree by comparing valence and bond degree. … … 184 211 *out << Verbose(1) << "Correcting Bond degree of each bond ... " << endl; 185 212 do { 186 No = SumPerAtom( &atom::CorrectBondDegree, out);213 No = SumPerAtom(&atom::CorrectBondDegree, out); 187 214 } while (No); 188 215 *out << " done." << endl; … … 193 220 194 221 return (No); 195 }; 222 } 223 ; 196 224 197 225 /** Counts all cyclic bonds and returns their number. … … 212 240 while (Subgraphs->next != NULL) { 213 241 Subgraphs = Subgraphs->next; 214 delete (Subgraphs->previous);215 } 216 delete (Subgraphs);217 delete[] (MinimumRingSize);218 } 219 while (Binder->next != last) {242 delete (Subgraphs->previous); 243 } 244 delete (Subgraphs); 245 delete[] (MinimumRingSize); 246 } 247 while (Binder->next != last) { 220 248 Binder = Binder->next; 221 249 if (Binder->Cyclic) 222 250 NoCyclicBonds++; 223 251 } 224 delete (BackEdgeStack);252 delete (BackEdgeStack); 225 253 return NoCyclicBonds; 226 } ;227 254 } 255 ; 228 256 229 257 /** Returns Shading as a char string. … … 233 261 string molecule::GetColor(enum Shading color) 234 262 { 235 switch (color) {263 switch (color) { 236 264 case white: 237 265 return "white"; … … 250 278 break; 251 279 }; 252 }; 253 254 void SetWalkersGraphNr(ofstream *out, bool &BackStepping, atom *&Walker, int &CurrentGraphNr, class StackClass<atom *> *&AtomStack) 255 { 256 if (!BackStepping) { // if we don't just return from (8) 257 Walker->GraphNr = CurrentGraphNr; 258 Walker->LowpointNr = CurrentGraphNr; 280 } 281 ; 282 283 /** Sets atom::GraphNr and atom::LowpointNr to BFSAccounting::CurrentGraphNr. 284 * \param *out output stream for debugging 285 * \param *Walker current node 286 * \param &BFS structure with accounting data for BFS 287 */ 288 void DepthFirstSearchAnalysis_SetWalkersGraphNr(ofstream *out, atom *&Walker, struct DFSAccounting &DFS) 289 { 290 if (!DFS.BackStepping) { // if we don't just return from (8) 291 Walker->GraphNr = DFS.CurrentGraphNr; 292 Walker->LowpointNr = DFS.CurrentGraphNr; 259 293 *out << Verbose(1) << "Setting Walker[" << Walker->Name << "]'s number to " << Walker->GraphNr << " with Lowpoint " << Walker->LowpointNr << "." << endl; 260 AtomStack->Push(Walker); 261 CurrentGraphNr++; 262 } 263 }; 264 265 void ProbeAlongUnusedBond(ofstream *out, molecule *mol, bond *&Binder, bool &BackStepping, atom *&Walker, class StackClass<bond *> *&BackEdgeStack) 294 DFS.AtomStack->Push(Walker); 295 DFS.CurrentGraphNr++; 296 } 297 } 298 ; 299 300 /** During DFS goes along unvisited bond and touches other atom. 301 * Sets bond::type, if 302 * -# BackEdge: set atom::LowpointNr and push on \a BackEdgeStack 303 * -# TreeEgde: set atom::Ancestor and continue with Walker along this edge 304 * Continue until molecule::FindNextUnused() finds no more unused bonds. 305 * \param *out output stream for debugging 306 * \param *mol molecule with atoms and finding unused bonds 307 * \param *&Binder current edge 308 * \param &DFS DFS accounting data 309 */ 310 void DepthFirstSearchAnalysis_ProbeAlongUnusedBond(ofstream *out, molecule *mol, atom *&Walker, bond *&Binder, struct DFSAccounting &DFS) 266 311 { 267 312 atom *OtherAtom = NULL; 268 313 269 314 do { // (3) if Walker has no unused egdes, go to (5) 270 BackStepping = false; // reset backstepping flag for (8)315 DFS.BackStepping = false; // reset backstepping flag for (8) 271 316 if (Binder == NULL) // if we don't just return from (11), Binder is already set to next unused 272 317 Binder = mol->FindNextUnused(Walker); … … 281 326 // (4a) ... if "other" atom has been visited (GraphNr != 0), set lowpoint to minimum of both, go to (3) 282 327 Binder->Type = BackEdge; 283 BackEdgeStack->Push(Binder);284 Walker->LowpointNr = ( Walker->LowpointNr < OtherAtom->GraphNr) ? Walker->LowpointNr : OtherAtom->GraphNr;328 DFS.BackEdgeStack->Push(Binder); 329 Walker->LowpointNr = (Walker->LowpointNr < OtherAtom->GraphNr) ? Walker->LowpointNr : OtherAtom->GraphNr; 285 330 *out << Verbose(3) << "(4a) Visited: Setting Lowpoint of Walker[" << Walker->Name << "] to " << Walker->LowpointNr << "." << endl; 286 331 } else { … … 293 338 } 294 339 Binder = NULL; 295 } while (1); // (3) 296 }; 297 298 void CheckForaNewComponent(ofstream *out, molecule *mol, bool &BackStepping, atom *&Walker, atom *&Root, int &ComponentNumber, class StackClass<atom *> *&AtomStack, MoleculeLeafClass *&LeafWalker ) 340 } while (1); // (3) 341 } 342 ; 343 344 /** Checks whether we have a new component. 345 * if atom::LowpointNr of \a *&Walker is greater than atom::GraphNr of its atom::Ancestor, we have a new component. 346 * Meaning that if we touch upon a node who suddenly has a smaller atom::LowpointNr than its ancestor, then we 347 * have a found a new branch in the graph tree. 348 * \param *out output stream for debugging 349 * \param *mol molecule with atoms and finding unused bonds 350 * \param *&Walker current node 351 * \param &DFS DFS accounting data 352 */ 353 void DepthFirstSearchAnalysis_CheckForaNewComponent(ofstream *out, molecule *mol, atom *&Walker, struct DFSAccounting &DFS, MoleculeLeafClass *&LeafWalker) 299 354 { 300 355 atom *OtherAtom = NULL; … … 303 358 *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl; 304 359 305 if (Walker->Ancestor->GraphNr != Root->GraphNr) {360 if (Walker->Ancestor->GraphNr != DFS.Root->GraphNr) { 306 361 // (6) (Ancestor of Walker is not Root) 307 362 if (Walker->LowpointNr < Walker->Ancestor->GraphNr) { … … 313 368 Walker->Ancestor->SeparationVertex = true; 314 369 *out << Verbose(2) << "(7) Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s is a separating vertex, creating component." << endl; 315 mol->SetNextComponentNumber(Walker->Ancestor, ComponentNumber);316 *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Ancestor's Compont is " << ComponentNumber << "." << endl;317 mol->SetNextComponentNumber(Walker, ComponentNumber);318 *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Compont is " << ComponentNumber << "." << endl;370 mol->SetNextComponentNumber(Walker->Ancestor, DFS.ComponentNumber); 371 *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Ancestor's Compont is " << DFS.ComponentNumber << "." << endl; 372 mol->SetNextComponentNumber(Walker, DFS.ComponentNumber); 373 *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Compont is " << DFS.ComponentNumber << "." << endl; 319 374 do { 320 OtherAtom = AtomStack->PopLast();375 OtherAtom = DFS.AtomStack->PopLast(); 321 376 LeafWalker->Leaf->AddCopyAtom(OtherAtom); 322 mol->SetNextComponentNumber(OtherAtom, ComponentNumber);323 *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;377 mol->SetNextComponentNumber(OtherAtom, DFS.ComponentNumber); 378 *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << DFS.ComponentNumber << "." << endl; 324 379 } while (OtherAtom != Walker); 325 ComponentNumber++;380 DFS.ComponentNumber++; 326 381 } 327 382 // (8) Walker becomes its Ancestor, go to (3) 328 383 *out << Verbose(2) << "(8) Walker[" << Walker->Name << "] is now its Ancestor " << Walker->Ancestor->Name << ", backstepping. " << endl; 329 384 Walker = Walker->Ancestor; 330 BackStepping = true; 331 } 332 }; 333 334 void CleanRootStackDownTillWalker(ofstream *out, molecule *mol, bool &BackStepping, atom *&Root, atom *&Walker, bond *&Binder, int &ComponentNumber, class StackClass<atom *> *&AtomStack, MoleculeLeafClass *&LeafWalker) 385 DFS.BackStepping = true; 386 } 387 } 388 ; 389 390 /** Cleans the root stack when we have found a component. 391 * If we are not DFSAccounting::BackStepping, then we clear the root stack by putting everything into a 392 * component down till we meet DFSAccounting::Root. 393 * \param *out output stream for debugging 394 * \param *mol molecule with atoms and finding unused bonds 395 * \param *&Walker current node 396 * \param *&Binder current edge 397 * \param &DFS DFS accounting data 398 */ 399 void DepthFirstSearchAnalysis_CleanRootStackDownTillWalker(ofstream *out, molecule *mol, atom *&Walker, bond *&Binder, struct DFSAccounting &DFS, MoleculeLeafClass *&LeafWalker) 335 400 { 336 401 atom *OtherAtom = NULL; 337 402 338 if (! BackStepping) {// coming from (8) want to go to (3)403 if (!DFS.BackStepping) { // coming from (8) want to go to (3) 339 404 // (9) remove all from stack till Walker (including), these and Root form a component 340 AtomStack->Output(out);341 mol->SetNextComponentNumber( Root,ComponentNumber);342 *out << Verbose(3) << "(9) Root[" << Root->Name << "]'s Component is " <<ComponentNumber << "." << endl;343 mol->SetNextComponentNumber(Walker, ComponentNumber);344 *out << Verbose(3) << "(9) Walker[" << Walker->Name << "]'s Component is " << ComponentNumber << "." << endl;405 DFS.AtomStack->Output(out); 406 mol->SetNextComponentNumber(DFS.Root, DFS.ComponentNumber); 407 *out << Verbose(3) << "(9) Root[" << DFS.Root->Name << "]'s Component is " << DFS.ComponentNumber << "." << endl; 408 mol->SetNextComponentNumber(Walker, DFS.ComponentNumber); 409 *out << Verbose(3) << "(9) Walker[" << Walker->Name << "]'s Component is " << DFS.ComponentNumber << "." << endl; 345 410 do { 346 OtherAtom = AtomStack->PopLast();411 OtherAtom = DFS.AtomStack->PopLast(); 347 412 LeafWalker->Leaf->AddCopyAtom(OtherAtom); 348 mol->SetNextComponentNumber(OtherAtom, ComponentNumber);349 *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;413 mol->SetNextComponentNumber(OtherAtom, DFS.ComponentNumber); 414 *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << DFS.ComponentNumber << "." << endl; 350 415 } while (OtherAtom != Walker); 351 ComponentNumber++;416 DFS.ComponentNumber++; 352 417 353 418 // (11) Root is separation vertex, set Walker to Root and go to (4) 354 Walker = Root;419 Walker = DFS.Root; 355 420 Binder = mol->FindNextUnused(Walker); 356 *out << Verbose(1) << "(10) Walker is Root[" << Root->Name << "], next Unused Bond is " << Binder << "." << endl;421 *out << Verbose(1) << "(10) Walker is Root[" << DFS.Root->Name << "], next Unused Bond is " << Binder << "." << endl; 357 422 if (Binder != NULL) { // Root is separation vertex 358 423 *out << Verbose(1) << "(11) Root is a separation vertex." << endl; … … 360 425 } 361 426 } 362 }; 363 427 } 428 ; 429 430 /** Initializes DFSAccounting structure. 431 * \param *out output stream for debugging 432 * \param &DFS accounting structure to allocate 433 * \param AtomCount number of nodes in graph 434 * \param BondCount number of edges in graph 435 */ 436 void DepthFirstSearchAnalysis_Init(ofstream *out, struct DFSAccounting &DFS, int AtomCount, int BondCount) 437 { 438 DFS.AtomStack = new StackClass<atom *> (AtomCount); 439 DFS.CurrentGraphNr = 0; 440 DFS.ComponentNumber = 0; 441 DFS.BackStepping = false; 442 } 443 ; 444 445 /** Free's DFSAccounting structure. 446 * \param *out output stream for debugging 447 * \param &DFS accounting structure to free 448 */ 449 void DepthFirstSearchAnalysis_Finalize(ofstream *out, struct DFSAccounting &DFS) 450 { 451 delete (DFS.AtomStack); 452 } 453 ; 364 454 365 455 /** Performs a Depth-First search on this molecule. … … 373 463 MoleculeLeafClass * molecule::DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack) 374 464 { 375 class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);465 struct DFSAccounting DFS; 376 466 BackEdgeStack = new StackClass<bond *> (BondCount); 467 DFS.BackEdgeStack = BackEdgeStack; 377 468 MoleculeLeafClass *SubGraphs = new MoleculeLeafClass(NULL); 378 469 MoleculeLeafClass *LeafWalker = SubGraphs; 379 int CurrentGraphNr = 0, OldGraphNr; 380 int ComponentNumber = 0; 470 int OldGraphNr = 0; 381 471 atom *Walker = NULL; 382 atom *Root = start->next;383 472 bond *Binder = NULL; 384 bool BackStepping = false;385 473 386 474 *out << Verbose(0) << "Begin of DepthFirstSearchAnalysis" << endl; 475 DepthFirstSearchAnalysis_Init(out, DFS, AtomCount, BondCount); 476 DFS.Root = start->next; 387 477 388 478 ResetAllBondsToUnused(); 389 SetAtomValueToValue( -1, &atom::GraphNr);390 ActOnAllAtoms( &atom::InitComponentNr);391 BackEdgeStack->ClearStack();392 while ( Root != end) { // if there any atoms at all479 SetAtomValueToValue(-1, &atom::GraphNr); 480 ActOnAllAtoms(&atom::InitComponentNr); 481 DFS.BackEdgeStack->ClearStack(); 482 while (DFS.Root != end) { // if there any atoms at all 393 483 // (1) mark all edges unused, empty stack, set atom->GraphNr = 0 for all 394 AtomStack->ClearStack();484 DFS.AtomStack->ClearStack(); 395 485 396 486 // put into new subgraph molecule and add this to list of subgraphs 397 487 LeafWalker = new MoleculeLeafClass(LeafWalker); 398 488 LeafWalker->Leaf = new molecule(elemente); 399 LeafWalker->Leaf->AddCopyAtom( Root);400 401 OldGraphNr = CurrentGraphNr;402 Walker = Root;489 LeafWalker->Leaf->AddCopyAtom(DFS.Root); 490 491 OldGraphNr = DFS.CurrentGraphNr; 492 Walker = DFS.Root; 403 493 do { // (10) 404 494 do { // (2) set number and Lowpoint of Atom to i, increase i, push current atom 405 SetWalkersGraphNr(out, BackStepping, Walker, CurrentGraphNr, AtomStack);406 407 ProbeAlongUnusedBond(out, this, Binder, BackStepping, Walker, BackEdgeStack);495 DepthFirstSearchAnalysis_SetWalkersGraphNr(out, Walker, DFS); 496 497 DepthFirstSearchAnalysis_ProbeAlongUnusedBond(out, this, Walker, Binder, DFS); 408 498 409 499 if (Binder == NULL) { … … 412 502 } else 413 503 Binder = NULL; 414 } while (1); 504 } while (1); // (2) 415 505 416 506 // if we came from backstepping, yet there were no more unused bonds, we end up here with no Ancestor, because Walker is Root! Then we are finished! 417 if ((Walker == Root) && (Binder == NULL))507 if ((Walker == DFS.Root) && (Binder == NULL)) 418 508 break; 419 509 420 CheckForaNewComponent(out, this, BackStepping, Walker, Root,ComponentNumber, AtomStack, LeafWalker);421 422 CleanRootStackDownTillWalker(out, this, BackStepping, Root, Walker, Binder, ComponentNumber, AtomStack, LeafWalker);423 424 } while (( BackStepping) || (Binder != NULL)); // (10) halt only if Root has no unused edges510 DepthFirstSearchAnalysis_CheckForaNewComponent(out, this, Walker, DFS, LeafWalker); 511 512 DepthFirstSearchAnalysis_CleanRootStackDownTillWalker(out, this, Walker, Binder, DFS, LeafWalker); 513 514 } while ((DFS.BackStepping) || (Binder != NULL)); // (10) halt only if Root has no unused edges 425 515 426 516 // From OldGraphNr to CurrentGraphNr ranges an disconnected subgraph 427 *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;517 *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << DFS.CurrentGraphNr << "." << endl; 428 518 LeafWalker->Leaf->Output(out); 429 519 *out << endl; 430 520 431 521 // step on to next root 432 while (( Root != end) && (Root->GraphNr != -1)) {522 while ((DFS.Root != end) && (DFS.Root->GraphNr != -1)) { 433 523 //*out << Verbose(1) << "Current next subgraph root candidate is " << Root->Name << "." << endl; 434 if ( Root->GraphNr != -1) // if already discovered, step on435 Root =Root->next;524 if (DFS.Root->GraphNr != -1) // if already discovered, step on 525 DFS.Root = DFS.Root->next; 436 526 } 437 527 } … … 444 534 445 535 // free all and exit 446 delete(AtomStack);536 DepthFirstSearchAnalysis_Finalize(out, DFS); 447 537 *out << Verbose(0) << "End of DepthFirstSearchAnalysis" << endl; 448 538 return SubGraphs; 449 }; 539 } 540 ; 450 541 451 542 /** Scans through all bonds and set bond::Cyclic to true where atom::LowpointNr of both ends is equal: LP criterion. … … 455 546 NoCyclicBonds = 0; 456 547 bond *Binder = first; 457 while (Binder->next != last) {548 while (Binder->next != last) { 458 549 Binder = Binder->next; 459 550 if (Binder->rightatom->LowpointNr == Binder->leftatom->LowpointNr) { // cyclic ?? … … 462 553 } 463 554 } 464 }; 555 } 556 ; 465 557 466 558 /** Output graph information per atom. … … 470 562 { 471 563 *out << Verbose(1) << "Final graph info for each atom is:" << endl; 472 ActOnAllAtoms( &atom::OutputGraphInfo, out ); 473 }; 564 ActOnAllAtoms(&atom::OutputGraphInfo, out); 565 } 566 ; 474 567 475 568 /** Output graph information per bond. … … 480 573 *out << Verbose(1) << "Final graph info for each bond is:" << endl; 481 574 bond *Binder = first; 482 while (Binder->next != last) {575 while (Binder->next != last) { 483 576 Binder = Binder->next; 484 577 *out << Verbose(2) << ((Binder->Type == TreeEdge) ? "TreeEdge " : "BackEdge ") << *Binder << ": <"; … … 492 585 *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl; 493 586 } 587 } 588 ; 589 590 /** Initialise each vertex as white with no predecessor, empty queue, color Root lightgray. 591 * \param *out output stream for debugging 592 * \param &BFS accounting structure 593 * \param AtomCount number of entries in the array to allocate 594 */ 595 void InitializeBFSAccounting(ofstream *out, struct BFSAccounting &BFS, int AtomCount) 596 { 597 BFS.AtomCount = AtomCount; 598 BFS.PredecessorList = Malloc<atom*> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: **PredecessorList"); 599 BFS.ShortestPathList = Malloc<int> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: *ShortestPathList"); 600 BFS.ColorList = Malloc<enum Shading> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: *ColorList"); 601 BFS.BFSStack = new StackClass<atom *> (AtomCount); 602 603 for (int i = AtomCount; i--;) { 604 BFS.PredecessorList[i] = NULL; 605 BFS.ShortestPathList[i] = -1; 606 BFS.ColorList[i] = white; 607 } 494 608 }; 495 609 496 /** initialise each vertex as white with no predecessor, empty queue, color Root lightgray. 497 * 498 */ 499 void InitializeAccounting(atom **&PredecessorList, int *&ShortestPathList, enum Shading *&ColorList, int AtomCount) 500 { 501 for (int i=AtomCount;i--;) { 502 PredecessorList[i] = NULL; 503 ShortestPathList[i] = -1; 504 ColorList[i] = white; 505 } 610 /** Free's accounting structure. 611 * \param *out output stream for debugging 612 * \param &BFS accounting structure 613 */ 614 void FinalizeBFSAccounting(ofstream *out, struct BFSAccounting &BFS) 615 { 616 Free(&BFS.PredecessorList); 617 Free(&BFS.ShortestPathList); 618 Free(&BFS.ColorList); 619 delete (BFS.BFSStack); 620 BFS.AtomCount = 0; 506 621 }; 507 622 508 void ResetAccounting(atom *&Walker, class StackClass<atom *> *&TouchedStack, int *&ShortestPathList, class StackClass<atom *> *&BFSStack) 509 { 510 ShortestPathList[Walker->nr] = 0; 511 BFSStack->ClearStack(); // start with empty BFS stack 512 BFSStack->Push(Walker); 513 TouchedStack->Push(Walker); 623 /** Clean the accounting structure. 624 * \param *out output stream for debugging 625 * \param &BFS accounting structure 626 */ 627 void CleanBFSAccounting(ofstream *out, struct BFSAccounting &BFS) 628 { 629 atom *Walker = NULL; 630 while (!BFS.TouchedStack->IsEmpty()) { 631 Walker = BFS.TouchedStack->PopFirst(); 632 BFS.PredecessorList[Walker->nr] = NULL; 633 BFS.ShortestPathList[Walker->nr] = -1; 634 BFS.ColorList[Walker->nr] = white; 635 } 514 636 }; 515 637 516 void CyclicBFSFromRootToRoot(ofstream *out, atom *&Root, bond *&BackEdge, class StackClass<atom *> *&TouchedStack, int *&ShortestPathList, atom **&PredecessorList, class StackClass<atom *> *&BFSStack, enum Shading *&ColorList) 638 /** Resets shortest path list and BFSStack. 639 * \param *out output stream for debugging 640 * \param *&Walker current node, pushed onto BFSAccounting::BFSStack and BFSAccounting::TouchedStack 641 * \param &BFS accounting structure 642 */ 643 void ResetBFSAccounting(ofstream *out, atom *&Walker, struct BFSAccounting &BFS) 644 { 645 BFS.ShortestPathList[Walker->nr] = 0; 646 BFS.BFSStack->ClearStack(); // start with empty BFS stack 647 BFS.BFSStack->Push(Walker); 648 BFS.TouchedStack->Push(Walker); 649 }; 650 651 /** Performs a BFS from \a *Root, trying to find the same node and hence a cycle. 652 * \param *out output stream for debugging 653 * \param *&BackEdge the edge from root that we don't want to move along 654 * \param &BFS accounting structure 655 */ 656 void CyclicStructureAnalysis_CyclicBFSFromRootToRoot(ofstream *out, bond *&BackEdge, struct BFSAccounting &BFS) 517 657 { 518 658 atom *Walker = NULL; 519 659 atom *OtherAtom = NULL; 520 do { 521 Walker = BFS Stack->PopFirst();522 *out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << * Root << "." << endl;660 do { // look for Root 661 Walker = BFS.BFSStack->PopFirst(); 662 *out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *BFS.Root << "." << endl; 523 663 for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) { 524 664 if ((*Runner) != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder) 525 665 OtherAtom = (*Runner)->GetOtherAtom(Walker); 526 666 #ifdef ADDHYDROGEN 527 667 if (OtherAtom->type->Z != 1) { 528 #endif 529 *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *(*Runner) << "." << endl; 530 if (ColorList[OtherAtom->nr] == white) { 531 TouchedStack->Push(OtherAtom); 532 ColorList[OtherAtom->nr] = lightgray; 533 PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor 534 ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1; 535 *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 536 //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance 537 *out << Verbose(3) << "Putting OtherAtom into queue." << endl; 538 BFSStack->Push(OtherAtom); 539 //} 540 } else { 541 *out << Verbose(3) << "Not Adding, has already been visited." << endl; 542 } 543 if (OtherAtom == Root) 544 break; 545 #ifdef ADDHYDROGEN 668 #endif 669 *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *(*Runner) << "." << endl; 670 if (BFS.ColorList[OtherAtom->nr] == white) { 671 BFS.TouchedStack->Push(OtherAtom); 672 BFS.ColorList[OtherAtom->nr] = lightgray; 673 BFS.PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor 674 BFS.ShortestPathList[OtherAtom->nr] = BFS.ShortestPathList[Walker->nr] + 1; 675 *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << BFS.ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 676 //if (BFS.ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance 677 *out << Verbose(3) << "Putting OtherAtom into queue." << endl; 678 BFS.BFSStack->Push(OtherAtom); 679 //} 546 680 } else { 547 *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl; 548 ColorList[OtherAtom->nr] = black; 681 *out << Verbose(3) << "Not Adding, has already been visited." << endl; 549 682 } 550 #endif 683 if (OtherAtom == BFS.Root) 684 break; 685 #ifdef ADDHYDROGEN 686 } else { 687 *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl; 688 BFS.ColorList[OtherAtom->nr] = black; 689 } 690 #endif 551 691 } else { 552 692 *out << Verbose(2) << "Bond " << *(*Runner) << " not Visiting, is the back edge." << endl; 553 693 } 554 694 } 555 ColorList[Walker->nr] = black;695 BFS.ColorList[Walker->nr] = black; 556 696 *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 557 if (OtherAtom == Root) { // if we have found the root, check whether this cycle wasn't already found beforehand697 if (OtherAtom == BFS.Root) { // if we have found the root, check whether this cycle wasn't already found beforehand 558 698 // step through predecessor list 559 699 while (OtherAtom != BackEdge->rightatom) { 560 if (!OtherAtom->GetTrueFather()->IsCyclic) 700 if (!OtherAtom->GetTrueFather()->IsCyclic) // if one bond in the loop is not marked as cyclic, we haven't found this cycle yet 561 701 break; 562 702 else 563 OtherAtom = PredecessorList[OtherAtom->nr];703 OtherAtom = BFS.PredecessorList[OtherAtom->nr]; 564 704 } 565 705 if (OtherAtom == BackEdge->rightatom) { // if each atom in found cycle is cyclic, loop's been found before already 566 *out << Verbose(3) << "This cycle was already found before, skipping and removing seeker from search." << endl; \706 *out << Verbose(3) << "This cycle was already found before, skipping and removing seeker from search." << endl; 567 707 do { 568 OtherAtom = TouchedStack->PopLast();569 if ( PredecessorList[OtherAtom->nr] == Walker) {708 OtherAtom = BFS.TouchedStack->PopLast(); 709 if (BFS.PredecessorList[OtherAtom->nr] == Walker) { 570 710 *out << Verbose(4) << "Removing " << *OtherAtom << " from lists and stacks." << endl; 571 PredecessorList[OtherAtom->nr] = NULL;572 ShortestPathList[OtherAtom->nr] = -1;573 ColorList[OtherAtom->nr] = white;574 BFS Stack->RemoveItem(OtherAtom);711 BFS.PredecessorList[OtherAtom->nr] = NULL; 712 BFS.ShortestPathList[OtherAtom->nr] = -1; 713 BFS.ColorList[OtherAtom->nr] = white; 714 BFS.BFSStack->RemoveItem(OtherAtom); 575 715 } 576 } while ((! TouchedStack->IsEmpty()) && (PredecessorList[OtherAtom->nr] == NULL));577 TouchedStack->Push(OtherAtom);// last was wrongly popped716 } while ((!BFS.TouchedStack->IsEmpty()) && (BFS.PredecessorList[OtherAtom->nr] == NULL)); 717 BFS.TouchedStack->Push(OtherAtom); // last was wrongly popped 578 718 OtherAtom = BackEdge->rightatom; // set to not Root 579 719 } else 580 OtherAtom = Root;581 } 582 } while ((!BFS Stack->IsEmpty()) && (OtherAtom !=Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr])));720 OtherAtom = BFS.Root; 721 } 722 } while ((!BFS.BFSStack->IsEmpty()) && (OtherAtom != BFS.Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]))); 583 723 }; 584 724 585 void RetrieveCycleMembers(ofstream *out, atom *&Root, atom *&OtherAtom, bond *&BackEdge, atom **&PredecessorList, int *&MinimumRingSize, int &MinRingSize) 725 /** Climb back the BFSAccounting::PredecessorList and find cycle members. 726 * \param *out output stream for debugging 727 * \param *&OtherAtom 728 * \param *&BackEdge denotes the edge we did not want to travel along when doing CyclicBFSFromRootToRoot() 729 * \param &BFS accounting structure 730 * \param *&MinimumRingSize minimum distance from this node possible without encountering oneself, set on return for each atom 731 * \param &MinRingSize global minimum distance from one node without encountering oneself, set on return 732 */ 733 void CyclicStructureAnalysis_RetrieveCycleMembers(ofstream *out, atom *&OtherAtom, bond *&BackEdge, struct BFSAccounting &BFS, int *&MinimumRingSize, int &MinRingSize) 586 734 { 587 735 atom *Walker = NULL; … … 589 737 int RingSize = -1; 590 738 591 if (OtherAtom == Root) {739 if (OtherAtom == BFS.Root) { 592 740 // now climb back the predecessor list and thus find the cycle members 593 741 NumCycles++; 594 742 RingSize = 1; 595 Root->GetTrueFather()->IsCyclic = true;743 BFS.Root->GetTrueFather()->IsCyclic = true; 596 744 *out << Verbose(1) << "Found ring contains: "; 597 Walker = Root;745 Walker = BFS.Root; 598 746 while (Walker != BackEdge->rightatom) { 599 747 *out << Walker->Name << " <-> "; 600 Walker = PredecessorList[Walker->nr];748 Walker = BFS.PredecessorList[Walker->nr]; 601 749 Walker->GetTrueFather()->IsCyclic = true; 602 750 RingSize++; … … 604 752 *out << Walker->Name << " with a length of " << RingSize << "." << endl << endl; 605 753 // walk through all and set MinimumRingSize 606 Walker = Root;754 Walker = BFS.Root; 607 755 MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize; 608 756 while (Walker != BackEdge->rightatom) { 609 Walker = PredecessorList[Walker->nr];757 Walker = BFS.PredecessorList[Walker->nr]; 610 758 if (RingSize < MinimumRingSize[Walker->GetTrueFather()->nr]) 611 759 MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize; … … 614 762 MinRingSize = RingSize; 615 763 } else { 616 *out << Verbose(1) << "No ring containing " << * Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl;764 *out << Verbose(1) << "No ring containing " << *BFS.Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl; 617 765 } 618 766 }; 619 767 620 void CleanAccounting(class StackClass<atom *> *&TouchedStack, atom **&PredecessorList, int *&ShortestPathList, enum Shading *&ColorList) 621 { 622 atom *Walker = NULL; 623 while (!TouchedStack->IsEmpty()){ 624 Walker = TouchedStack->PopFirst(); 625 PredecessorList[Walker->nr] = NULL; 626 ShortestPathList[Walker->nr] = -1; 627 ColorList[Walker->nr] = white; 628 } 629 }; 630 631 632 void BFSToNextCycle(ofstream *out, atom *&Root, atom *&Walker, bond *&BackEdge, int *&MinimumRingSize, int AtomCount) 633 { 634 atom **PredecessorList = Malloc<atom*>(AtomCount, "molecule::CyclicStructureAnalysis: **PredecessorList"); 635 int *ShortestPathList = Malloc<int>(AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList"); 636 enum Shading *ColorList = Malloc<enum Shading>(AtomCount, "molecule::CyclicStructureAnalysis: *ColorList"); 637 class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount); // will hold the current ring 638 class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount); // contains all "touched" atoms (that need to be reset after BFS loop) 768 /** From a given node performs a BFS to touch the next cycle, for whose nodes \a *&MinimumRingSize is set and set it accordingly. 769 * \param *out output stream for debugging 770 * \param *&Root node to look for closest cycle from, i.e. \a *&MinimumRingSize is set for this node 771 * \param *&MinimumRingSize minimum distance from this node possible without encountering oneself, set on return for each atom 772 * \param AtomCount number of nodes in graph 773 */ 774 void CyclicStructureAnalysis_BFSToNextCycle(ofstream *out, atom *&Root, atom *&Walker, int *&MinimumRingSize, int AtomCount) 775 { 776 struct BFSAccounting BFS; 639 777 atom *OtherAtom = Walker; 640 778 641 Initialize Accounting(PredecessorList, ShortestPathList, ColorList, AtomCount);642 643 Reset Accounting(Walker, TouchedStack, ShortestPathList, BFSStack);644 while (OtherAtom != NULL) { 645 Walker = BFS Stack->PopFirst();779 InitializeBFSAccounting(out, BFS, AtomCount); 780 781 ResetBFSAccounting(out, Walker, BFS); 782 while (OtherAtom != NULL) { // look for Root 783 Walker = BFS.BFSStack->PopFirst(); 646 784 //*out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl; 647 785 for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) { 648 if (((*Runner) != BackEdge) || (Walker->ListOfBonds.size() == 1)) { // only walk along DFS spanning tree (otherwise we always find SP of 1 being backedge Binder), but terminal hydrogens may be connected via backedge, hence extra check 786 // "removed (*Runner) != BackEdge) || " from next if, is u 787 if ((Walker->ListOfBonds.size() == 1)) { // only walk along DFS spanning tree (otherwise we always find SP of 1 being backedge Binder), but terminal hydrogens may be connected via backedge, hence extra check 649 788 OtherAtom = (*Runner)->GetOtherAtom(Walker); 650 789 //*out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl; 651 if ( ColorList[OtherAtom->nr] == white) {652 TouchedStack->Push(OtherAtom);653 ColorList[OtherAtom->nr] = lightgray;654 PredecessorList[OtherAtom->nr] = Walker;// Walker is the predecessor655 ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;790 if (BFS.ColorList[OtherAtom->nr] == white) { 791 BFS.TouchedStack->Push(OtherAtom); 792 BFS.ColorList[OtherAtom->nr] = lightgray; 793 BFS.PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor 794 BFS.ShortestPathList[OtherAtom->nr] = BFS.ShortestPathList[Walker->nr] + 1; 656 795 //*out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 657 796 if (OtherAtom->GetTrueFather()->IsCyclic) { // if the other atom is connected to a ring 658 MinimumRingSize[Root->GetTrueFather()->nr] = ShortestPathList[OtherAtom->nr]+MinimumRingSize[OtherAtom->GetTrueFather()->nr];797 MinimumRingSize[Root->GetTrueFather()->nr] = BFS.ShortestPathList[OtherAtom->nr] + MinimumRingSize[OtherAtom->GetTrueFather()->nr]; 659 798 OtherAtom = NULL; //break; 660 799 break; 661 800 } else 662 BFS Stack->Push(OtherAtom);801 BFS.BFSStack->Push(OtherAtom); 663 802 } else { 664 803 //*out << Verbose(3) << "Not Adding, has already been visited." << endl; … … 668 807 } 669 808 } 670 ColorList[Walker->nr] = black;809 BFS.ColorList[Walker->nr] = black; 671 810 //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 672 811 } 673 812 //CleanAccountingLists(TouchedStack, PredecessorList, ShortestPathList, ColorList); 674 813 675 Free(&PredecessorList); 676 Free(&ShortestPathList); 677 Free(&ColorList); 678 delete(BFSStack); 679 }; 680 681 void AssignRingSizetoNonCycleMembers(ofstream *out, int *&MinimumRingSize, int &MinRingSize, int &NumCycles, molecule *mol, bond *&BackEdge) 682 { 683 atom *Root= NULL; 814 FinalizeBFSAccounting(out, BFS); 815 } 816 ; 817 818 /** All nodes that are not in cycles get assigned a \a *&MinimumRingSizeby BFS to next cycle. 819 * \param *out output stream for debugging 820 * \param *&MinimumRingSize array with minimum distance without encountering onself for each atom 821 * \param &MinRingSize global minium distance 822 * \param &NumCyles number of cycles in graph 823 * \param *mol molecule with atoms 824 */ 825 void CyclicStructureAnalysis_AssignRingSizetoNonCycleMembers(ofstream *out, int *&MinimumRingSize, int &MinRingSize, int &NumCycles, molecule *mol) 826 { 827 atom *Root = NULL; 684 828 atom *Walker = NULL; 685 829 if (MinRingSize != -1) { // if rings are present 686 830 // go over all atoms 687 831 Root = mol->start; 688 while (Root->next != mol->end) {832 while (Root->next != mol->end) { 689 833 Root = Root->next; 690 834 … … 693 837 694 838 //*out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl; 695 BFSToNextCycle(out, Root, Walker, BackEdge, MinimumRingSize, mol->AtomCount);839 CyclicStructureAnalysis_BFSToNextCycle(out, Root, Walker, MinimumRingSize, mol->AtomCount); 696 840 697 841 } … … 701 845 } else 702 846 *out << Verbose(1) << "No rings were detected in the molecular structure." << endl; 703 }; 847 } 848 ; 704 849 705 850 /** Analyses the cycles found and returns minimum of all cycle lengths. … … 713 858 * \todo BFS from the not-same-LP to find back to starting point of tributary cycle over more than one bond 714 859 */ 715 void molecule::CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> * BackEdgeStack, int *&MinimumRingSize) 716 { 717 atom **PredecessorList = Malloc<atom*>(AtomCount, "molecule::CyclicStructureAnalysis: **PredecessorList"); 718 int *ShortestPathList = Malloc<int>(AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList"); 719 enum Shading *ColorList = Malloc<enum Shading>(AtomCount, "molecule::CyclicStructureAnalysis: *ColorList"); 720 class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount); // will hold the current ring 721 class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount); // contains all "touched" atoms (that need to be reset after BFS loop) 860 void molecule::CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> * BackEdgeStack, int *&MinimumRingSize) 861 { 862 struct BFSAccounting BFS; 722 863 atom *Walker = NULL; 723 864 atom *OtherAtom = NULL; 724 atom *Root = NULL;725 865 bond *BackEdge = NULL; 726 866 int NumCycles = 0; 727 867 int MinRingSize = -1; 728 868 729 Initialize Accounting(PredecessorList, ShortestPathList, ColorList, AtomCount);869 InitializeBFSAccounting(out, BFS, AtomCount); 730 870 731 871 *out << Verbose(1) << "Back edge list - "; … … 737 877 BackEdge = BackEdgeStack->PopFirst(); 738 878 // this is the target 739 Root = BackEdge->leftatom;879 BFS.Root = BackEdge->leftatom; 740 880 // this is the source point 741 881 Walker = BackEdge->rightatom; 742 882 743 Reset Accounting(Walker, TouchedStack, ShortestPathList, BFSStack);883 ResetBFSAccounting(out, Walker, BFS); 744 884 745 885 *out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl; 746 886 OtherAtom = NULL; 747 CyclicBFSFromRootToRoot(out, Root, BackEdge, TouchedStack, ShortestPathList, PredecessorList, BFSStack, ColorList); 748 749 RetrieveCycleMembers(out, Root, OtherAtom, BackEdge, PredecessorList, MinimumRingSize, MinRingSize); 750 751 CleanAccounting(TouchedStack, PredecessorList, ShortestPathList, ColorList); 752 } 753 Free(&PredecessorList); 754 Free(&ShortestPathList); 755 Free(&ColorList); 756 delete(BFSStack); 757 758 AssignRingSizetoNonCycleMembers(out, MinimumRingSize, MinRingSize, NumCycles, this, BackEdge); 759 760 }; 887 CyclicStructureAnalysis_CyclicBFSFromRootToRoot(out, BackEdge, BFS); 888 889 CyclicStructureAnalysis_RetrieveCycleMembers(out, OtherAtom, BackEdge, BFS, MinimumRingSize, MinRingSize); 890 891 CleanBFSAccounting(out, BFS); 892 } 893 FinalizeBFSAccounting(out, BFS); 894 895 CyclicStructureAnalysis_AssignRingSizetoNonCycleMembers(out, MinimumRingSize, MinRingSize, NumCycles, this); 896 897 } 898 ; 761 899 762 900 /** Sets the next component number. … … 767 905 void molecule::SetNextComponentNumber(atom *vertex, int nr) 768 906 { 769 size_t i =0;907 size_t i = 0; 770 908 if (vertex != NULL) { 771 for (;i<vertex->ListOfBonds.size();i++) {772 if (vertex->ComponentNr[i] == -1) { 909 for (; i < vertex->ListOfBonds.size(); i++) { 910 if (vertex->ComponentNr[i] == -1) { // check if not yet used 773 911 vertex->ComponentNr[i] = nr; 774 912 break; 775 } 776 else if (vertex->ComponentNr[i] == nr) // if number is already present, don't add another time 777 break; // breaking here will not cause error! 913 } else if (vertex->ComponentNr[i] == nr) // if number is already present, don't add another time 914 break; // breaking here will not cause error! 778 915 } 779 916 if (i == vertex->ListOfBonds.size()) 780 917 cerr << "Error: All Component entries are already occupied!" << endl; 781 918 } else 782 cerr << "Error: Given vertex is NULL!" << endl; 783 }; 919 cerr << "Error: Given vertex is NULL!" << endl; 920 } 921 ; 784 922 785 923 /** Returns next unused bond for this atom \a *vertex or NULL of none exists. … … 791 929 for (BondList::const_iterator Runner = vertex->ListOfBonds.begin(); Runner != vertex->ListOfBonds.end(); (++Runner)) 792 930 if ((*Runner)->IsUsed() == white) 793 return ((*Runner));931 return ((*Runner)); 794 932 return NULL; 795 }; 933 } 934 ; 796 935 797 936 /** Resets bond::Used flag of all bonds in this molecule. … … 805 944 Binder->ResetUsed(); 806 945 } 807 }; 946 } 947 ; 808 948 809 949 /** Output a list of flags, stating whether the bond was visited or not. … … 814 954 { 815 955 *out << Verbose(4) << "Already Visited Bonds:\t"; 816 for(int i=1;i<=list[0];i++) *out << Verbose(0) << list[i] << " "; 956 for (int i = 1; i <= list[0]; i++) 957 *out << Verbose(0) << list[i] << " "; 817 958 *out << endl; 818 } ;819 959 } 960 ; 820 961 821 962 /** Storing the bond structure of a molecule to file. … … 835 976 *out << Verbose(1) << "Saving adjacency list ... "; 836 977 if (AdjacencyFile != NULL) { 837 ActOnAllAtoms( &atom::OutputAdjacency, &AdjacencyFile);978 ActOnAllAtoms(&atom::OutputAdjacency, &AdjacencyFile); 838 979 AdjacencyFile.close(); 839 980 *out << Verbose(1) << "done." << endl; … … 844 985 845 986 return status; 846 }; 987 } 988 ; 847 989 848 990 bool CheckAdjacencyFileAgainstMolecule_Init(ofstream *out, char *path, ifstream &File, int *&CurrentBonds) … … 856 998 857 999 // allocate storage structure 858 CurrentBonds = Malloc<int> (8, "molecule::CheckAdjacencyFileAgainstMolecule - CurrentBonds"); // contains parsed bonds of current atom1000 CurrentBonds = Malloc<int> (8, "molecule::CheckAdjacencyFileAgainstMolecule - CurrentBonds"); // contains parsed bonds of current atom 859 1001 return true; 860 }; 1002 } 1003 ; 861 1004 862 1005 void CheckAdjacencyFileAgainstMolecule_Finalize(ofstream *out, ifstream &File, int *&CurrentBonds) … … 865 1008 File.clear(); 866 1009 Free(&CurrentBonds); 867 }; 1010 } 1011 ; 868 1012 869 1013 void CheckAdjacencyFileAgainstMolecule_CompareBonds(ofstream *out, bool &status, int &NonMatchNumber, atom *&Walker, size_t &CurrentBondsOfAtom, int AtomNr, int *&CurrentBonds, atom **ListOfAtoms) … … 877 1021 id = (*Runner)->GetOtherAtom(Walker)->nr; 878 1022 j = 0; 879 for (; (j<CurrentBondsOfAtom) && (CurrentBonds[j++] != id);)1023 for (; (j < CurrentBondsOfAtom) && (CurrentBonds[j++] != id);) 880 1024 ; // check against all parsed bonds 881 if (CurrentBonds[j -1] != id) { // no match ? Then mark in ListOfAtoms1025 if (CurrentBonds[j - 1] != id) { // no match ? Then mark in ListOfAtoms 882 1026 ListOfAtoms[AtomNr] = NULL; 883 1027 NonMatchNumber++; … … 893 1037 status = false; 894 1038 } 895 }; 1039 } 1040 ; 896 1041 897 1042 /** Checks contents of adjacency file against bond structure in structure molecule. … … 908 1053 char *buffer = NULL; 909 1054 int *CurrentBonds = NULL; 910 int NonMatchNumber = 0; 1055 int NonMatchNumber = 0; // will number of atoms with differing bond structure 911 1056 size_t CurrentBondsOfAtom = -1; 912 1057 … … 916 1061 } 917 1062 918 buffer = Malloc<char> (MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");1063 buffer = Malloc<char> (MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer"); 919 1064 // Parse the file line by line and count the bonds 920 1065 while (!File.eof()) { … … 929 1074 Walker = ListOfAtoms[AtomNr]; 930 1075 while (!line.eof()) 931 line >> CurrentBonds[ ++CurrentBondsOfAtom];1076 line >> CurrentBonds[++CurrentBondsOfAtom]; 932 1077 // compare against present bonds 933 1078 CheckAdjacencyFileAgainstMolecule_CompareBonds(out, status, NonMatchNumber, Walker, CurrentBondsOfAtom, AtomNr, CurrentBonds, ListOfAtoms); … … 942 1087 *out << Verbose(1) << "done: Not equal by " << NonMatchNumber << " atoms." << endl; 943 1088 return status; 944 } ;945 1089 } 1090 ; 946 1091 947 1092 /** Picks from a global stack with all back edges the ones in the fragment. … … 960 1105 } 961 1106 bond *Binder = ReferenceStack->PopFirst(); 962 bond *FirstBond = Binder; 1107 bond *FirstBond = Binder; // mark the first bond, so that we don't loop through the stack indefinitely 963 1108 atom *Walker = NULL, *OtherAtom = NULL; 964 1109 ReferenceStack->Push(Binder); 965 1110 966 do { 967 Walker = ListOfLocalAtoms[Binder->leftatom->nr]; 1111 do { // go through all bonds and push local ones 1112 Walker = ListOfLocalAtoms[Binder->leftatom->nr]; // get one atom in the reference molecule 968 1113 if (Walker != NULL) // if this Walker exists in the subgraph ... 969 1114 for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) { … … 975 1120 } 976 1121 } 977 Binder = ReferenceStack->PopFirst(); 1122 Binder = ReferenceStack->PopFirst(); // loop the stack for next item 978 1123 *out << Verbose(3) << "Current candidate edge " << Binder << "." << endl; 979 1124 ReferenceStack->Push(Binder); … … 981 1126 982 1127 return status; 983 }; 984 985 struct BFSAccounting { 986 atom **PredecessorList; 987 int *ShortestPathList; 988 enum Shading *ColorList; 989 class StackClass<atom *> *AtomStack; 990 int AtomCount; 991 int BondOrder; 992 atom *Root; 993 }; 1128 } 1129 ; 994 1130 995 1131 void BreadthFirstSearchAdd_Init(struct BFSAccounting &BFS, atom *&Root, int AtomCount, int BondOrder, atom **AddedAtomList = NULL) … … 997 1133 BFS.AtomCount = AtomCount; 998 1134 BFS.BondOrder = BondOrder; 999 BFS.PredecessorList = Malloc<atom*> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: **PredecessorList");1000 BFS.ShortestPathList = Malloc<int> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: *ShortestPathList");1001 BFS.ColorList = Malloc<enum Shading> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: *ColorList");1002 BFS. AtomStack = new StackClass<atom *>(AtomCount);1135 BFS.PredecessorList = Malloc<atom*> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: **PredecessorList"); 1136 BFS.ShortestPathList = Malloc<int> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: *ShortestPathList"); 1137 BFS.ColorList = Malloc<enum Shading> (AtomCount, "molecule::BreadthFirstSearchAdd_Init: *ColorList"); 1138 BFS.BFSStack = new StackClass<atom *> (AtomCount); 1003 1139 1004 1140 BFS.Root = Root; 1005 BFS. AtomStack->ClearStack();1006 BFS. AtomStack->Push(Root);1141 BFS.BFSStack->ClearStack(); 1142 BFS.BFSStack->Push(Root); 1007 1143 1008 1144 // initialise each vertex as white with no predecessor, empty queue, color Root lightgray 1009 for (int i =AtomCount;i--;) {1145 for (int i = AtomCount; i--;) { 1010 1146 BFS.PredecessorList[i] = NULL; 1011 1147 BFS.ShortestPathList[i] = -1; … … 1016 1152 } 1017 1153 BFS.ShortestPathList[Root->nr] = 0; 1018 }; 1154 } 1155 ; 1019 1156 1020 1157 void BreadthFirstSearchAdd_Free(struct BFSAccounting &BFS) … … 1023 1160 Free(&BFS.ShortestPathList); 1024 1161 Free(&BFS.ColorList); 1025 delete (BFS.AtomStack);1162 delete (BFS.BFSStack); 1026 1163 BFS.AtomCount = 0; 1027 } ;1028 1164 } 1165 ; 1029 1166 1030 1167 void BreadthFirstSearchAdd_UnvisitedNode(ofstream *out, molecule *Mol, struct BFSAccounting &BFS, atom *&Walker, atom *&OtherAtom, bond *&Binder, bond *&Bond, atom **&AddedAtomList, bond **&AddedBondList, bool IsAngstroem) … … 1032 1169 if (Binder != Bond) // let other atom white if it's via Root bond. In case it's cyclic it has to be reached again (yet Root is from OtherAtom already black, thus no problem) 1033 1170 BFS.ColorList[OtherAtom->nr] = lightgray; 1034 BFS.PredecessorList[OtherAtom->nr] = Walker; 1035 BFS.ShortestPathList[OtherAtom->nr] = BFS.ShortestPathList[Walker->nr] +1;1171 BFS.PredecessorList[OtherAtom->nr] = Walker; // Walker is the predecessor 1172 BFS.ShortestPathList[OtherAtom->nr] = BFS.ShortestPathList[Walker->nr] + 1; 1036 1173 *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " " << ((BFS.ColorList[OtherAtom->nr] == white) ? "white" : "lightgray") << ", its predecessor is " << Walker->Name << " and its Shortest Path is " << BFS.ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl; 1037 if ((((BFS.ShortestPathList[OtherAtom->nr] < BFS.BondOrder) && (Binder != Bond))) 1174 if ((((BFS.ShortestPathList[OtherAtom->nr] < BFS.BondOrder) && (Binder != Bond)))) { // Check for maximum distance 1038 1175 *out << Verbose(3); 1039 1176 if (AddedAtomList[OtherAtom->nr] == NULL) { // add if it's not been so far … … 1042 1179 AddedBondList[Binder->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder); 1043 1180 *out << " and bond " << *(AddedBondList[Binder->nr]) << ", "; 1044 } else { 1181 } else { // this code should actually never come into play (all white atoms are not yet present in BondMolecule, that's why they are white in the first place) 1045 1182 *out << "Not adding OtherAtom " << OtherAtom->Name; 1046 1183 if (AddedBondList[Binder->nr] == NULL) { … … 1051 1188 } 1052 1189 *out << ", putting OtherAtom into queue." << endl; 1053 BFS. AtomStack->Push(OtherAtom);1190 BFS.BFSStack->Push(OtherAtom); 1054 1191 } else { // out of bond order, then replace 1055 1192 if ((AddedAtomList[OtherAtom->nr] == NULL) && (Binder->Cyclic)) … … 1065 1202 AddedBondList[Binder->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder); 1066 1203 } else { 1067 1204 #ifdef ADDHYDROGEN 1068 1205 if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, IsAngstroem)) 1069 1070 1206 exit(1); 1207 #endif 1071 1208 } 1072 1209 } 1073 1210 } 1074 }; 1211 } 1212 ; 1075 1213 1076 1214 void BreadthFirstSearchAdd_VisitedNode(ofstream *out, molecule *Mol, struct BFSAccounting &BFS, atom *&Walker, atom *&OtherAtom, bond *&Binder, bond *&Bond, atom **&AddedAtomList, bond **&AddedBondList, bool IsAngstroem) … … 1079 1217 // This has to be a cyclic bond, check whether it's present ... 1080 1218 if (AddedBondList[Binder->nr] == NULL) { 1081 if ((Binder != Bond) && (Binder->Cyclic) && (((BFS.ShortestPathList[Walker->nr] +1) < BFS.BondOrder))) {1219 if ((Binder != Bond) && (Binder->Cyclic) && (((BFS.ShortestPathList[Walker->nr] + 1) < BFS.BondOrder))) { 1082 1220 AddedBondList[Binder->nr] = Mol->CopyBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder); 1083 1221 } else { // if it's root bond it has to broken (otherwise we would not create the fragments) 1084 1222 #ifdef ADDHYDROGEN 1085 1223 if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, IsAngstroem)) 1086 exit(1); 1087 #endif 1088 } 1089 } 1090 }; 1224 exit(1); 1225 #endif 1226 } 1227 } 1228 } 1229 ; 1091 1230 1092 1231 /** Adds atoms up to \a BondCount distance from \a *Root and notes them down in \a **AddedAtomList. … … 1109 1248 1110 1249 // add Root if not done yet 1111 if (AddedAtomList[Root->nr] == NULL) 1250 if (AddedAtomList[Root->nr] == NULL) // add Root if not yet present 1112 1251 AddedAtomList[Root->nr] = Mol->AddCopyAtom(Root); 1113 1252 … … 1115 1254 1116 1255 // and go on ... Queue always contains all lightgray vertices 1117 while (!BFS. AtomStack->IsEmpty()) {1256 while (!BFS.BFSStack->IsEmpty()) { 1118 1257 // we have to pop the oldest atom from stack. This keeps the atoms on the stack always of the same ShortestPath distance. 1119 1258 // e.g. if current atom is 2, push to end of stack are of length 3, but first all of length 2 would be popped. They again 1120 1259 // append length of 3 (their neighbours). Thus on stack we have always atoms of a certain length n at bottom of stack and 1121 1260 // followed by n+1 till top of stack. 1122 Walker = BFS. AtomStack->PopFirst(); // pop oldest added1261 Walker = BFS.BFSStack->PopFirst(); // pop oldest added 1123 1262 *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << Walker->ListOfBonds.size() << " bonds." << endl; 1124 1263 for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) { … … 1138 1277 } 1139 1278 BreadthFirstSearchAdd_Free(BFS); 1140 }; 1279 } 1280 ; 1141 1281 1142 1282 /** Adds a bond as a copy to a given one … … 1152 1292 Binder->Type = CopyBond->Type; 1153 1293 return Binder; 1154 }; 1294 } 1295 ; 1155 1296 1156 1297 void BuildInducedSubgraph_Init(ofstream *out, atom **&ParentList, int AtomCount) 1157 1298 { 1158 1299 // reset parent list 1159 ParentList = Malloc<atom*> (AtomCount, "molecule::BuildInducedSubgraph_Init: **ParentList");1300 ParentList = Malloc<atom*> (AtomCount, "molecule::BuildInducedSubgraph_Init: **ParentList"); 1160 1301 *out << Verbose(3) << "Resetting ParentList." << endl; 1161 for (int i =AtomCount;i--;)1302 for (int i = AtomCount; i--;) 1162 1303 ParentList[i] = NULL; 1163 }; 1304 } 1305 ; 1164 1306 1165 1307 void BuildInducedSubgraph_FillParentList(ofstream *out, const molecule *mol, const molecule *Father, atom **&ParentList) … … 1172 1314 ParentList[Walker->father->nr] = Walker; 1173 1315 // Outputting List for debugging 1174 *out << Verbose(4) << "Son["<< Walker->father->nr <<"] of " << Walker->father << " is " << ParentList[Walker->father->nr] << "." << endl; 1175 } 1176 1177 }; 1316 *out << Verbose(4) << "Son[" << Walker->father->nr << "] of " << Walker->father << " is " << ParentList[Walker->father->nr] << "." << endl; 1317 } 1318 1319 } 1320 ; 1178 1321 1179 1322 void BuildInducedSubgraph_Finalize(ofstream *out, atom **&ParentList) 1180 1323 { 1181 1324 Free(&ParentList); 1182 }; 1325 } 1326 ; 1183 1327 1184 1328 bool BuildInducedSubgraph_CreateBondsFromParent(ofstream *out, molecule *mol, const molecule *Father, atom **&ParentList) … … 1207 1351 } 1208 1352 return status; 1209 }; 1353 } 1354 ; 1210 1355 1211 1356 /** Adds bond structure to this molecule from \a Father molecule. … … 1230 1375 *out << Verbose(2) << "End of BuildInducedSubgraph." << endl; 1231 1376 return status; 1232 } ;1233 1377 } 1378 ; 1234 1379 1235 1380 /** For a given keyset \a *Fragment, checks whether it is connected in the current molecule. … … 1250 1395 // count number of atoms in graph 1251 1396 size = 0; 1252 for (KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++)1397 for (KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) 1253 1398 size++; 1254 1399 if (size > 1) 1255 for (KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) {1400 for (KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) { 1256 1401 Walker = FindAtom(*runner); 1257 1402 BondStatus = false; 1258 for (KeySet::iterator runners = Fragment->begin(); runners != Fragment->end(); runners++) {1403 for (KeySet::iterator runners = Fragment->begin(); runners != Fragment->end(); runners++) { 1259 1404 Walker2 = FindAtom(*runners); 1260 1405 for (BondList::const_iterator Runner = Walker->ListOfBonds.begin(); Runner != Walker->ListOfBonds.end(); (++Runner)) {
Note:
See TracChangeset
for help on using the changeset viewer.