initial commit
This commit is contained in:
commit
5a8a5983b2
2 changed files with 269 additions and 0 deletions
5
Makefile
Normal file
5
Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
all:
|
||||
gdc circuits_hawick.d -o circuits_hawick
|
||||
|
||||
clean:
|
||||
rm -f circuits_hawick
|
264
circuits_hawick.d
Normal file
264
circuits_hawick.d
Normal file
|
@ -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<list[0]; j++) {
|
||||
list[j] = list[j+1];
|
||||
}
|
||||
--list[0]; // should be safe as list[0] is
|
||||
// re-evaluated each time around the i-loop
|
||||
--i;
|
||||
}
|
||||
}
|
||||
return nOccurrences;
|
||||
}
|
||||
|
||||
void stackPrint3d() {
|
||||
int i;
|
||||
for (i = 0; i < stackTop-1; i++) {
|
||||
std.stdio.writef("%d ", stack[i]);
|
||||
}
|
||||
std.stdio.writefln("%d", stack[i]);
|
||||
}
|
||||
|
||||
int countAkArcs () { // return number of Arcs in graph
|
||||
int nArcs = 0;
|
||||
for (int i =0; i<nVertices; i ++) {
|
||||
nArcs += Ak[i][0]; // zero’th element gives nArcs for i
|
||||
}
|
||||
return nArcs;
|
||||
}
|
||||
|
||||
void unblock (int u) {
|
||||
blocked [u] = false;
|
||||
for (int wPos = 1; wPos <= B[u][0]; wPos++) {
|
||||
// for each w in B[u]
|
||||
int w = B[u][wPos];
|
||||
wPos -= removeFromList(B[u], w);
|
||||
if (blocked[w])
|
||||
unblock(w);
|
||||
}
|
||||
}
|
||||
|
||||
// initialise the stack to some size max
|
||||
void stackInit(int max) {
|
||||
stack.length = max;
|
||||
assert(stack != null);
|
||||
stackTop = 0;
|
||||
}
|
||||
|
||||
// push an int onto the stack, extending if necessary
|
||||
void stackPush (int val) {
|
||||
if (stackTop >= 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;
|
||||
}
|
Loading…
Reference in a new issue