From 5a8a5983b2c0ad45a2ae252a78e2d118cdbf43b2 Mon Sep 17 00:00:00 2001 From: josch Date: Tue, 3 Jul 2012 20:23:25 +0200 Subject: [PATCH] initial commit --- Makefile | 5 + circuits_hawick.d | 264 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 Makefile create mode 100644 circuits_hawick.d diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..283b268 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +all: + gdc circuits_hawick.d -o circuits_hawick + +clean: + rm -f circuits_hawick diff --git a/circuits_hawick.d b/circuits_hawick.d new file mode 100644 index 0000000..487c8d5 --- /dev/null +++ b/circuits_hawick.d @@ -0,0 +1,264 @@ +/* + * Enumerating Circuits and Loops in Graphs with Self-Arcs and Multiple-Arcs + * K.A. Hawick and H.A. James + * Computer Science, Institute for Information and Mathematical Sciences, + * Massey University, North Shore 102-904, Auckland, New Zealand + * k.a.hawick@massey.ac.nz; heath.james@sapac.edu.au + * Tel: +64 9 414 0800 + * Fax: +64 9 441 8181 + * Technical Report CSTN-013 + */ + +import std.stdio; + +int nVertices = 16; // number of vertices +int start = 0; // starting vertex index +int [][] Ak; // integer array size n of lists + // ie the arcs from the vertex +int [][] B; // integer array size n of lists +bool [] blocked; // logical array indexed by vertex +ulong nCircuits = 0; // total number of circuits found; +ulong [] lengthHistogram; // histogram of circuit lengths +ulong [][] vertexPopularity; // adjacency table of occurrences of + // vertices in circuits of each length +int [] longestCircuit; // the (first) longest circuit found +int lenLongest = 0; // its length +bool enumeration = true; // explicitly enumerate circuits +int [] stack = null; // stack of integers +static int stackTop = 0; // the number of elements on the stack + // also the index "to put the next one" + +// return a pointer to a list of fixed max size +int [] newList(int max) { + int[] retval; + retval.length = max + 1; + retval[0] = 0; + return retval; +} + +// return TRUE if value is NOT in the list +bool notInList (int [] list, int val) { + assert(list != null); + assert(list [0] < list.length); + for (int i = 1; i <= list[0]; i++) { + if (list[i] == val) + return false; + } + return true; +} + +// return TRUE if value is in the list +bool inList (int [] list, int val) { + assert(list != null); + assert(list[0] < list.length); + for (int i = 1; i <= list[0]; i++) { + if (list[i] == val) + return true; + } + return false; +} + +// empties a list by simply zeroing its size +void emptyList (int [] list) { + assert(list != null); + assert(list[0] < list.length); + list[0] = 0; +} + +// adds on to the end (making extra space if needed) +void addToList (ref int [] list, int val) { + assert(list != null); + assert(list[0] < list.length); + int newPos = list[0] + 1; + if (newPos >= list.length) + list.length = list.length + 1; + list[newPos] = val; + list[0] = newPos; +} + +// removes all occurences of val in the list +int removeFromList(int [] list, int val) { + assert(list != null); + assert(list[0] < list.length); + int nOccurrences = 0; + for (int i = 1; i <= list[0]; i++) { + if (list[i] == val) { + nOccurrences++; + for (int j = i; j= stack.length) + stack.length = stack.length + 1; + stack[stackTop++] = val; +} + +int stackSize() { + return stackTop; +} + +int stackPop () { + // pop an int off the stack + assert(stackTop > 0); + return stack[--stackTop]; +} + +void stackClear () { + // clear the stack + stackTop = 0; +} + +bool circuit(int v) { // based on Johnson ’s logical procedure CIRCUIT + bool f = false; + stackPush(v); + blocked[v] = true; + for (int wPos = 1; wPos <= Ak[v][0]; wPos++) { // for each w in list Ak[v]: + int w = Ak[v][wPos]; + if (w < start) continue; // ignore relevant parts of Ak + if (w == start) { // we have a circuit, + if (enumeration) { + stackPrint3d(); // print out the stack to record the circuit + } + assert (stackTop <= nVertices); + ++lengthHistogram[stackTop]; // add this circuit ’s length to the length histogram + nCircuits++; // and increment count of circuits found + if (stackTop > lenLongest) { // keep a copy of the longest circuit found + lenLongest = stackTop; + longestCircuit = stack.dup; + } + for (int i = 0; i < stackTop; i ++) // increment [circuit-length][vertex] for all vertices in this circuit + ++vertexPopularity[stackTop][stack[i]]; + f = true; + } else if (!blocked[w]) { + if (circuit(w)) f = true; + } + } + if (f) { + unblock (v); + } else { + for (int wPos = 1; wPos <= Ak[v][0]; wPos++) { // for each w in list Ak[v]: + int w = Ak[v][wPos]; + if (w < start) continue; // ignore relevant parts of Ak + if (notInList(B[w], v)) addToList(B[w], v); + } + } + v = stackPop(); + return f; +} + +void setupGlobals() { // presupposes nVertices is set up + Ak.length = nVertices; // Ak[i][0] is the number of members, Ak[i][1]..Ak[i][n] ARE the members, i>0 + B.length = nVertices; // B[i][0] is the number of members, B[i][1]..B[i][n] ARE the members , i>0 + blocked.length = nVertices; // we use blocked [0]..blocked[n-1], i> = 0 + for (int i = 0; i < nVertices; i++) { + Ak[i] = newList(nVertices); + B[i] = newList(nVertices); + blocked[i] = false; + } + + addToList(Ak[0], 2); + addToList(Ak[0], 10); + addToList(Ak[0], 14); + addToList(Ak[1], 5); + addToList(Ak[1], 8); + addToList(Ak[2], 7); + addToList(Ak[2], 9); + addToList(Ak[3], 3); + addToList(Ak[3], 4); + addToList(Ak[3], 6); + addToList(Ak[4], 5); + addToList(Ak[4], 13); + addToList(Ak[4], 15); + addToList(Ak[6], 13); + addToList(Ak[8], 0); + addToList(Ak[8], 4); + addToList(Ak[8], 8); + addToList(Ak[9], 9); + addToList(Ak[10], 7); + addToList(Ak[10], 11); + addToList(Ak[11], 6); + addToList(Ak[12], 1); + addToList(Ak[12], 1); + addToList(Ak[12], 2); + addToList(Ak[12], 10); + addToList(Ak[12], 12); + addToList(Ak[12], 14); + addToList(Ak[13], 3); + addToList(Ak[13], 12); + addToList(Ak[13], 15); + addToList(Ak[14], 11); + addToList(Ak[15], 0); + + lengthHistogram.length = nVertices+1; // will use as [1]...[n] to histogram circuits by length + // [0] for zero length circuits, which are impossible + for (int len = 0; len < lengthHistogram.length; len++) // initialise histogram bins to empty + lengthHistogram[len] = 0; + stackInit(nVertices); + vertexPopularity.length = nVertices+1; // max elementary circuit length is exactly nVertices + for (int len = 0; len <= nVertices; len++) { + vertexPopularity[len].length = nVertices; + for (int j = 0; j < nVertices; j++) { + vertexPopularity[len][j] = 0; + } + } +} + +int main() { + setupGlobals(); + stackClear(); + start = 0; + bool verbose = false; + while (start < nVertices) { + if (verbose && enumeration) std.stdio.writefln("Starting s = %d\n", start); + for (int i = 0; i < nVertices; i++) { // for all i in Vk + blocked[i] = false; + emptyList(B[i]); + } + circuit(start); + start = start + 1; + } + return 0; +}