Beispiel #1
0
        public void map(PatternCollector collector)
        {
            m_collector = collector;
            Debug.Assert(null != collector);
            int    i, j, c;
            ushort f1, f2;
            bool   cycle;

            byte[] keys;

            c = 0;
            var rnd = new Random();

            do
            {
                initGraph();
                cycle = false;

                /* Randomly generate T1 and T2 */
                for (i = 0; i < SetSize * EntryLen; i++)
                {
                    T1base[i] = (ushort)rnd.Next(NumVert);
                    T2base[i] = (ushort)rnd.Next(NumVert);
                }

                for (i = 0; i < NumEntry; i++)
                {
                    f1   = 0; f2 = 0;
                    keys = m_collector.getKey(i);
                    for (j = 0; j < EntryLen; j++)
                    {
                        f1 += T1base[j * SetSize + (keys[j] - SetMin)];
                        f2 += T2base[j * SetSize + (keys[j] - SetMin)];
                    }
                    f1 %= (ushort)NumVert;
                    f2 %= (ushort)NumVert;
                    if (f1 == f2)
                    {
                        /* A self loop. Reject! */
                        Debug.Print("Self loop on vertex %d!\n", f1);
                        cycle = true;
                        break;
                    }
                    addToGraph(numEdges++, f1, f2);
                }
                if (cycle || (cycle = isCycle()))   /* OK - is there a cycle? */
                {
                    Debug.Print("Iteration {0}", ++c);
                }
                else
                {
                    break;
                }
            }while (/* there is a cycle */ true);
        }
Beispiel #2
0
        bool DFS(int parentE, int v)
        {
            int e, w;

            // Depth first search of the graph, starting at vertex v, looking for
            // cycles. parent and v are origin 1. Note parent is an EDGE,
            // not a vertex

            visited[v] = true;

            // For each e incident with v ..
            for (e = graphFirst[v]; e != 0; e = graphNext[NumEntry + e])
            {
                byte[] key1;

                if (deleted[Math.Abs(e)])
                {
                    /* A deleted key. Just ignore it */
                    continue;
                }
                key1 = m_collector.getKey(Math.Abs(e) - 1);
                w    = graphNode[NumEntry + e];
                if (visited[w])
                {
                    /* Did we just come through this edge? If so, ignore it. */
                    if (Math.Abs(e) != Math.Abs(parentE))
                    {
                        /* There is a cycle in the graph. There is some subtle code here
                         *  to work around the distinct possibility that there may be
                         *  duplicate keys. Duplicate keys will always cause unit
                         *  cycles, since f1 and f2 (used to select v and w) will be the
                         *  same for both. The edges (representing an index into the
                         *  array of keys) are distinct, but the key values are not.
                         *  The logic is as follows: for the candidate edge e, check to
                         *  see if it terminates in the parent vertex. If so, we test
                         *  the keys associated with e and the parent, and if they are
                         *  the same, we can safely ignore e for the purposes of cycle
                         *  detection, since edge e adds nothing to the cycle. Cycles
                         *  involving v, w, and e0 will still be found. The parent
                         *  edge was not similarly eliminated because at the time when
                         *  it was a candidate, v was not yet visited.
                         *  We still have to remove the key from further consideration,
                         *  since each edge is visited twice, but with a different
                         *  parent edge each time.
                         */
                        /* We save some stack space by calculating the parent vertex
                         *  for these relatively few cases where it is needed */
                        int parentV = graphNode[NumEntry - parentE];

                        if (w == parentV)
                        {
                            byte[] key2;

                            key2 = m_collector.getKey(Math.Abs(parentE) - 1);
                            if (ByteMemoryArea.CompareArrays(key1, 0, key2, EntryLen))
                            {
                                Debug.Print("Duplicate keys with edges {0} and {1} (",
                                            e, parentE);
                                m_collector.dispKey(Math.Abs(e) - 1);
                                Debug.Print(" & ");
                                m_collector.dispKey(Math.Abs(parentE) - 1);
                                Debug.Print(")\n");
                                deleted[Math.Abs(e)] = true;      /* Wipe the key */
                            }
                            else
                            {
                                /* A genuine (unit) cycle. */
                                Debug.Print("There is a unit cycle involving vertex %d and edge %d\n", v, e);
                                return(true);
                            }
                        }
                        else
                        {
                            // We have reached a previously visited vertex not the
                            // parent. Therefore, we have uncovered a genuine cycle
                            Debug.Print("There is a cycle involving vertex {0} and edge {1}", v, e);
                            return(true);
                        }
                    }
                }
                else                                // Not yet seen. Traverse it
                {
                    if (DFS(e, w))
                    {
                        // Cycle found deeper down. Exit
                        return(true);
                    }
                }
            }
            return(false);
        }
Beispiel #3
0
        /* Part 1 of creating the tables */
        public void map(PatternCollector collector)
        {
            m_collector = collector;
            Debug.Assert(null != collector);
            int i, j, c;
            ushort f1, f2;
            bool cycle;
            byte[] keys;

            c = 0;
            var rnd = new Random();
            do
            {
                initGraph();
                cycle = false;

                /* Randomly generate T1 and T2 */
                for (i = 0; i < SetSize * EntryLen; i++)
                {
                    T1base[i] = (ushort)rnd.Next(NumVert);
                    T2base[i] = (ushort)rnd.Next(NumVert);
                }

                for (i = 0; i < NumEntry; i++)
                {
                    f1 = 0; f2 = 0;
                    keys = m_collector.getKey(i);
                    for (j = 0; j < EntryLen; j++)
                    {
                        f1 += T1base[ j * SetSize +(keys[j] - SetMin)];
                        f2 += T2base[ j * SetSize + (keys[j] - SetMin)];
                    }
                    f1 %= (ushort)NumVert;
                    f2 %= (ushort)NumVert;
                    if (f1 == f2)
                    {
                        /* A self loop. Reject! */
                        Debug.Print("Self loop on vertex %d!\n", f1);
                        cycle = true;
                        break;
                    }
                    addToGraph(numEdges++, f1, f2);
                }
                if (cycle || (cycle = isCycle()))   /* OK - is there a cycle? */
                {
                    Debug.Print("Iteration {0}", ++c);
                }
                else
                {
                    break;
                }
            }
            while (/* there is a cycle */ true);

        }