Exemplo n.º 1
0
        void Main()
        {
            {
                #region
                IAtomContainer benzene = TestMoleculeFactory.MakeBenzene();

                IAtom c1 = benzene.Atoms[0];
                IAtom c4 = benzene.Atoms[3];

                // shortest paths from C1
                ShortestPaths sp = new ShortestPaths(benzene, c1);

                // number of paths from C1 to C4
                int nPaths = sp.GetNPathsTo(c4);

                // distance between C1 to C4
                int distance = sp.GetDistanceTo(c4);

                // reconstruct a path to the C4 - determined by storage order
                int[] path = sp.GetPathTo(c4);

                // reconstruct all paths
                int[][] paths = sp.GetPathsTo(c4);
                int[]   org   = paths[0]; // paths[0] == path
                int[]   alt   = paths[1];
                #endregion
            }
            {
                IAtomContainer benzene = TestMoleculeFactory.MakeBenzene();
                IAtom          c1      = benzene.Atoms[0];

                #region GetPathTo_int
                ShortestPaths sp = new ShortestPaths(benzene, c1);

                // reconstruct first path
                int[] path = sp.GetPathTo(5);

                // check there is only one path
                if (sp.GetNPathsTo(5) == 1)
                {
                    path = sp.GetPathTo(5); // reconstruct the path
                }
                #endregion
            }
            {
                IAtomContainer benzene = TestMoleculeFactory.MakeBenzene();
                IAtom          c1      = benzene.Atoms[0];

                #region GetPathTo_IAtom
                ShortestPaths sp  = new ShortestPaths(benzene, c1);
                IAtom         end = benzene.Atoms[3];

                // reconstruct first path
                int[] path = sp.GetPathTo(end);

                // check there is only one path
                if (sp.GetNPathsTo(end) == 1)
                {
                    path = sp.GetPathTo(end); // reconstruct the path
                }
                #endregion
            }
            {
                IAtomContainer benzene = TestMoleculeFactory.MakeBenzene();
                IAtom          c1      = benzene.Atoms[0];

                #region GetPathsTo_int
                int           threshold = 20;
                ShortestPaths sp        = new ShortestPaths(benzene, c1);

                // reconstruct shortest paths
                int[][] paths = sp.GetPathsTo(5);

                // only reconstruct shortest paths below a threshold
                if (sp.GetNPathsTo(5) < threshold)
                {
                    int[][] path = sp.GetPathsTo(5); // reconstruct shortest paths
                }
                #endregion
            }
            {
                IAtomContainer benzene = TestMoleculeFactory.MakeBenzene();
                IAtom          c1      = benzene.Atoms[0];

                #region GetPathsTo_IAtom
                int           threshold = 20;
                ShortestPaths sp        = new ShortestPaths(benzene, c1);
                IAtom         end       = benzene.Atoms[3];

                // reconstruct all shortest paths
                int[][] paths = sp.GetPathsTo(end);

                // only reconstruct shortest paths below a threshold
                if (sp.GetNPathsTo(end) < threshold)
                {
                    paths = sp.GetPathsTo(end); // reconstruct shortest paths
                }
                #endregion
            }
            {
                IAtomContainer benzene = TestMoleculeFactory.MakeBenzene();
                IAtom          c1      = benzene.Atoms[0];

                #region GetAtomsTo_int
                ShortestPaths sp = new ShortestPaths(benzene, c1);

                // reconstruct a shortest path
                IAtom[] path = sp.GetAtomsTo(5);

                // ensure single shortest path
                if (sp.GetNPathsTo(5) == 1)
                {
                    path = sp.GetAtomsTo(5); // reconstruct shortest path
                }
                #endregion
            }
            {
                IAtomContainer benzene = TestMoleculeFactory.MakeBenzene();
                IAtom          c1      = benzene.Atoms[0];

                #region GetAtomsTo_IAtom
                ShortestPaths sp  = new ShortestPaths(benzene, c1);
                IAtom         end = benzene.Atoms[3];

                // reconstruct a shortest path
                IAtom[] path = sp.GetAtomsTo(end);

                // ensure single shortest path
                if (sp.GetNPathsTo(end) == 1)
                {
                    path = sp.GetAtomsTo(end); // reconstruct shortest path
                }
                #endregion
            }
            {
                IAtomContainer benzene = TestMoleculeFactory.MakeBenzene();
                IAtom          c1      = benzene.Atoms[0];

                #region GetNPathsTo_int
                ShortestPaths sp = new ShortestPaths(benzene, c1);

                sp.GetNPathsTo(5);  // number of paths

                sp.GetNPathsTo(-1); // returns 0 - there are no paths
                #endregion
            }
            {
                IAtomContainer benzene = TestMoleculeFactory.MakeBenzene();
                IAtom          c1      = benzene.Atoms[0];

                #region GetNPathsTo_IAtom
                ShortestPaths sp  = new ShortestPaths(benzene, c1);
                IAtom         end = benzene.Atoms[3];

                sp.GetNPathsTo(end);           // number of paths

                sp.GetNPathsTo(null);          // returns 0 - there are no paths
                sp.GetNPathsTo(new Atom("C")); // returns 0 - there are no paths
                #endregion
            }
            {
                #region GetDistanceTo_int_1
                IAtomContainer container = TestMoleculeFactory.MakeBenzene();
                IAtom          c1        = container.Atoms[0];
                ShortestPaths  sp        = new ShortestPaths(container, c1); // start = 0

                int n = container.Atoms.Count;

                if (sp.GetDistanceTo(5) < n)
                {
                    // these is a path from 0 to 5
                }
                #endregion
            }
            {
                #region GetDistanceTo_int_2
                IAtomContainer container = TestMoleculeFactory.MakeBenzene();
                IAtom          c1        = container.Atoms[0];
                ShortestPaths  sp        = new ShortestPaths(container, c1); // start = 0

                int[] path = sp.GetPathTo(5);

                int start = path[0];
                int end   = path[sp.GetDistanceTo(5)];
                #endregion
            }
            {
                #region GetDistanceTo_IAtom_1
                IAtomContainer container = TestMoleculeFactory.MakeBenzene();
                IAtom          c1        = container.Atoms[0];
                ShortestPaths  sp        = new ShortestPaths(container, c1); // start atom
                IAtom          end       = container.Atoms[3];

                int n = container.Atoms.Count;

                if (sp.GetDistanceTo(end) < n)
                {
                    // these is a path from start to end
                }
                #endregion
            }
            {
                #region GetDistanceTo_IAtom_2
                IAtomContainer container = TestMoleculeFactory.MakeBenzene();
                IAtom          c1        = container.Atoms[0];
                ShortestPaths  sp        = new ShortestPaths(container, c1); // start atom
                IAtom          end       = container.Atoms[3];

                IAtom[] atoms = sp.GetAtomsTo(end);
                Console.WriteLine(end == atoms[sp.GetDistanceTo(end)]); // true
                #endregion
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Compute the initial cycles. The code corresponds to algorithm 1 from
        /// <token>cdk-cite-Vismara97</token>, where possible the variable names have been kept
        /// the same.
        /// </summary>
        private void Compute()
        {
            int n = graph.Length;

            // the set 'S' contains the pairs of vertices adjacent to 'y'
            int[] s = new int[n];
            int   sizeOfS;

            // order the vertices by degree
            int[] vertices = new int[n];
            for (int v = 0; v < n; v++)
            {
                vertices[ordering[v]] = v;
            }

            // if the graph is known to be a biconnected component (prepossessing)
            // and there is at least one vertex with a degree > 2 we can skip all
            // vertices of degree 2.
            //
            // otherwise the smallest possible cycle is {0,1,2} (no parallel edges
            // or loops) we can therefore don't need to do the first two shortest
            // paths calculations
            int first = biconnected && nDeg2Vertices < n ? nDeg2Vertices : 2;

            for (int i = first; i < n; i++)
            {
                int r = vertices[i];

                ShortestPaths pathsFromR = new ShortestPaths(graph, null, r, limit / 2, ordering);

                // we only check the vertices which belong to the set Vr. this
                // set is vertices reachable from 'r' by only travelling though
                // vertices smaller then r. In the ShortestPaths API this is
                // name 'IsPrecedingPathTo'.
                //
                // using Vr allows us to prune the number of vertices to check and
                // discover each cycle exactly once. This is possible as for each
                // simple cycle there is only one vertex with a maximum ordering.
                for (int j = 0; j < i; j++)
                {
                    int y = vertices[j];
                    if (!pathsFromR.IsPrecedingPathTo(y))
                    {
                        continue;
                    }

                    // start refilling set 's' by resetting it's size
                    sizeOfS = 0;

                    // z is adjacent to y and belong to Vr
                    foreach (var z in graph[y])
                    {
                        if (!pathsFromR.IsPrecedingPathTo(z))
                        {
                            continue;
                        }

                        int distToZ = pathsFromR.GetDistanceTo(z);
                        int distToY = pathsFromR.GetDistanceTo(y);

                        // the distance of the path to z is one less then the
                        // path to y. the vertices are adjacent, therefore z must
                        // also belong to the shortest path from r to y.
                        //
                        // we queue up (in 's') all the vertices adjacent to y for
                        // which this holds and then check these once we've processed
                        // all adjacent vertices
                        //
                        //  / ¯ ¯ z1 \          z1 and z2 are added to 's' and
                        // r          y - z3    checked later as p and q (see below)
                        //  \ _ _ z2 /
                        //
                        if (distToZ + 1 == distToY)
                        {
                            s[sizeOfS++] = z;
                        }

                        // if the distances are equal we could have an odd cycle
                        // but we need to check the paths only intersect at 'r'.
                        //
                        // we check the intersect for cases like this, shortest
                        // cycle here is {p .. y, z .. p} not {r .. y, z .. r}
                        //
                        //           / ¯ ¯ y         / ¯ ¯ \ / ¯ ¯ y
                        //  r - - - p      |    or  r       p      |
                        //           \ _ _ z         \ _ _ / \ _ _ z
                        //
                        // if it's the shortest cycle then the intersect is just {r}
                        //
                        //  / ¯ ¯ y
                        // r      |
                        //  \ _ _ z
                        //
                        else if (distToZ == distToY && ordering[z] < ordering[y])
                        {
                            int[] pathToY = pathsFromR.GetPathTo(y);
                            int[] pathToZ = pathsFromR.GetPathTo(z);
                            if (GetSingletonIntersect(pathToZ, pathToY))
                            {
                                Cycle cycle = new Cycle.OddCycle(this, pathsFromR, pathToY, pathToZ);
                                Add(cycle);
                            }
                        }
                    }

                    // check each pair vertices adjacent to 'y' for an
                    // even cycle, as with the odd cycle we ensure the intersect
                    // of the paths {r .. p} and {r .. q} is {r}.
                    //
                    //  / ¯ ¯ p \
                    // r         y
                    //  \ _ _ q /
                    //
                    for (int k = 0; k < sizeOfS; k++)
                    {
                        for (int l = k + 1; l < sizeOfS; l++)
                        {
                            int[] pathToP = pathsFromR.GetPathTo(s[k]);
                            int[] pathToQ = pathsFromR.GetPathTo(s[l]);
                            if (GetSingletonIntersect(pathToP, pathToQ))
                            {
                                Cycle cycle = new Cycle.EvenCycle(this, pathsFromR, pathToP, y, pathToQ);
                                Add(cycle);
                            }
                        }
                    }
                }
            }
        }