Пример #1
0
        /// <summary>
        /// Recursively performs a depth first search in a molecular graphs contained in
        /// the AtomContainer molecule, starting at the root atom and returning when it
        /// hits the target atom.
        /// <para>
        /// CAUTION: This recursive method sets the VISITED flag of each atom
        /// does not reset it after finishing the search. If you want to do the
        /// operation on the same collection of atoms more than once, you have
        /// to set all the VISITED flags to false before each operation
        /// by looping of the atoms and doing a
        /// "atom.Flag = (CDKConstants.VISITED, false);"
        /// </para>
        /// <para>
        /// Note that the path generated by the search will not contain the root atom,
        /// but will contain the target atom
        /// </para>
        /// </summary>
        /// <param name="molecule">The AtomContainer to be searched</param>
        /// <param name="root">The root atom to start the search at</param>
        /// <param name="target">The target</param>
        /// <param name="path">An AtomContainer to be filled with the path</param>
        /// <returns><see langword="true"/> if the target atom was found during this function call</returns>
        public static bool DepthFirstTargetSearch(IAtomContainer molecule, IAtom root, IAtom target, IAtomContainer path)
        {
            var   bonds = molecule.GetConnectedBonds(root);
            IAtom nextAtom;

            root.IsVisited = true;
            bool first = path.IsEmpty();

            if (first)
            {
                path.Atoms.Add(root);
            }
            foreach (var bond in bonds)
            {
                nextAtom = bond.GetOther(root);
                if (!nextAtom.IsVisited)
                {
                    path.Atoms.Add(nextAtom);
                    path.Bonds.Add(bond);
                    if (nextAtom.Equals(target))
                    {
                        if (first)
                        {
                            path.Atoms.Remove(root);
                        }
                        return(true);
                    }
                    else
                    {
                        if (!DepthFirstTargetSearch(molecule, nextAtom, target, path))
                        {
                            // we did not find the target
                            path.Atoms.Remove(nextAtom);
                            path.Bonds.Remove(bond);
                        }
                        else
                        {
                            if (first)
                            {
                                path.Atoms.Remove(root);
                            }
                            return(true);
                        }
                    }
                }
            }
            if (first)
            {
                path.Atoms.Remove(root);
            }
            return(false);
        }
Пример #2
0
 private static int[] DetermineComponents(IAtomContainer target, bool auto)
 {
     int[] components = null;
     // no atoms -> no components
     if (target.IsEmpty())
     {
         components = new int[0];
     }
     // defined by reaction grouping
     if (components == null && target.Atoms[0].GetProperty <int?>(CDKPropertyName.ReactionGroup) != null)
     {
         int max = 0;
         components = new int[target.Atoms.Count + 1];
         for (int i = 0; i < target.Atoms.Count; i++)
         {
             var grp = target.Atoms[i].GetProperty <int?>(CDKPropertyName.ReactionGroup);
             if (grp == null)
             {
                 grp = 0;
             }
             components[i] = grp.Value;
             if (grp > max)
             {
                 max = grp.Value;
             }
         }
         components[target.Atoms.Count] = max;
     }
     // calculate from connection table
     if (components == null && auto)
     {
         int max = 0;
         components = new int[target.Atoms.Count + 1];
         int i = 0;
         foreach (int grp in new ConnectedComponents(GraphUtil.ToAdjList(target)).GetComponents())
         {
             components[i++] = grp;
             if (grp > max)
             {
                 max = grp;
             }
         }
         components[target.Atoms.Count] = max;
     }
     return(components);
 }