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); }
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); }
/* 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); }