/*--------------------- Findoptimal, Version 1.1 Program for finding optimal representative in LC orbit (in terms of number of edges and chromatic index) and give LC-sequence(s) producing the input graph from the optimal graph(s). Uses nauty (http://cs.anu.edu.au/~bdm/nauty/) and very_nauty (http://keithbriggs.info/very_nauty.html). Compiles with the following command. (Replace $(NAUDIR) and $(VERYNAUTYDIR) with the actual locations of nauty and very_nauty.) gcc -o findoptimal -I$(NAUDIR) -I$(VERYNAUTYDIR) -DMAXN=WORDSIZE -O4 findoptimal.c $(NAUDIR)/nauty.o $(NAUDIR)/nautil.o $(NAUDIR)/naugraph.o $(NAUDIR)/gtools.o $(NAUDIR)/naututil.o $(NAUDIR)/rng.o $(NAUDIR)/gutil1.o $(NAUDIR)/gutil2.o $(VERYNAUTYDIR)vn_graph.o -lm -- L. E. Danielsen Version 1.0, 28 Sep. 2010: - First version Version 1.1, 13 Jan. 2011: - Program now outputs much shorter LC sequences ---------------------*/ #include #include #include #include #include "vn_graph.h" #include "gtools.h" #include "naututil.h" #include "gutils.h" #define MAXVERTICES 20 // Works for graphs with up to n=20 vertices #define BYTES 24 // (n choose 2)/8 bytes needed to store graph with up to n vertices typedef struct treenode { char value[BYTES]; struct treenode *left; struct treenode *right; } node; typedef struct queuenode { graph g[MAXN]; char lcstring[512]; struct queuenode *next; } qnode; node *root = NULL; int nx = 0; unsigned char gvalue[BYTES]; graph gx[MAXN]; graph gxcanon[MAXN]; graph gxedge[MAXN]; graph gxchrom[MAXN]; char lcedge[512]; char lcchrom[512]; int orbitsize; int minedge; int minedgechrom; int minchrom; int minchromedge; char *s; const set onemask = 0x1L << (WORDSIZE-1); void getValue(const graph *g) { int i, j; set row; int byte = 0; int bytecount = 0; memset(gvalue, 0, BYTES); for(i=1; ileft)); freeTree(&((*root)->right)); free(*root); } } int addNode(node **root) { node *curNode, *prevNode, *newNode; int different; different = 3; curNode = *root; while (curNode != NULL) { different = 0; if(memcmp(gvalue, curNode->value, BYTES) < 0) { different = 1; prevNode = curNode; curNode = curNode->left; } else if(memcmp(gvalue, curNode->value, BYTES) > 0) { different = 2; prevNode = curNode; curNode = curNode->right; } else { return 0; } } newNode = malloc(sizeof(node)); memcpy(newNode->value, gvalue, BYTES); newNode->left = NULL; newNode->right = NULL; switch (different) { case 1: curNode = newNode; prevNode->left = curNode; return(1); break; case 2: curNode = newNode; prevNode->right = curNode; return(1); break; case 3: *root = newNode; return(1); break; } } void makecanon(graph *g, graph *gcan) { statsblk nauty_stats; int lab[MAXN],ptn[MAXN],orbits[MAXN]; static DEFAULTOPTIONS(options); setword workspace[50]; options.getcanon = TRUE; nauty(g,lab,ptn,NULL,orbits,&options,&nauty_stats,workspace,50,1,nx,gcan); } void lc(const int v) { unsigned char w; const set rowv = gx[v]; set *roww; set mask = onemask; for(w=0; w>= 1; } } int edges(graph *gx) { int i,j; int count = 0; set *row; for(i=0; ig[i] = gx[i]; sprintf(qnew->lcstring, ""); qnew->next = NULL; qfirst = qnew; qlast = qnew; while(qfirst != NULL) { for(i=0; ig[i]; oldstring = qfirst->lcstring; for(v=0; vg[i] = gx[i]; strcpy(qnew->lcstring, newstring); qnew->next = NULL; qlast->next = qnew; qlast = qnew; } lc(v); } qfirst = qfirst->next; } } void printedges(graph *g) { int first = 1; int i, j; set *row; for(i=0; i<(nx-1); i++) { row = GRAPHROW(g,i,1); for(j=i+1; j= MAXVERTICES) { printf("Error: Max number of vertices is %d!\n", MAXVERTICES); exit(-1); } if(u >= nx) nx = u+1; term = strtok(0, ",- "); if(!term) { printf("Error in input!\n"); exit(-1); } v = strtol(term, &endptr, 10); if(*endptr != '\0') { printf("Error in input!\n"); exit(-1); } if(v >= MAXVERTICES) { printf("Error: Max number of vertices is %d!\n", MAXVERTICES); exit(-1); } if(v >= nx) nx = v+1; if(u == v) { printf("Error: No edges from a vertex to itself allowed!\n"); exit(-1); } row = GRAPHROW(g, u, 1); ADDELEMENT(row, v); row = GRAPHROW(g, v, 1); ADDELEMENT(row, u); term = strtok(0, ",- "); } } int graphequals(graph* g1, graph* g2) { int i; int equals = 1; for(i=0; i"); fgets(line, 2048, stdin); line[strlen(line)-1] = '\0'; edgestog6(line, gx); for(i=0; i