static void no4path(graph *g, int m, int n, int v, int *dist) /* For each i, set dist[i]=0 if there is a 4-path from v to i */ { set *gv,*gv1,*gv2,*gv3; int v1,v2,v3,v4; gv = GRAPHROW(g,v,m); for (v1 = -1; (v1 = nextelement(gv,m,v1)) >= 0; ) { gv1 = GRAPHROW(g,v1,m); for (v2 = -1; (v2 = nextelement(gv1,m,v2)) >= 0; ) { if (v2 == v) continue; gv2 = GRAPHROW(g,v2,m); for (v3 = -1; (v3 = nextelement(gv2,m,v3)) >= 0; ) { if (v3 == v || v3 == v1) continue; gv3 = GRAPHROW(g,v3,m); for (v4 = -1; (v4 = nextelement(gv3,m,v4)) >= 0; ) if (v4 != v && v4 != v1 && v4 != v2) dist[v4] = 0; } } } }
boolean issubconnected(graph *g, set *sub, int m, int n) /* Test if the subset of g induced by sub is connected. Empty is connected. */ { int i,head,tail,w,subsize; set *gw; #if MAXN int queue[MAXN],visited[MAXN]; setword subw[MAXM]; #else DYNALLSTAT(int,queue,queue_sz); DYNALLSTAT(int,visited,visited_sz); DYNALLSTAT(set,subw,subw_sz); DYNALLOC1(int,queue,queue_sz,n,"issubconnected"); DYNALLOC1(int,visited,visited_sz,n,"issubconnected"); DYNALLOC1(set,subw,subw_sz,m,"issubconnected"); #endif subsize = 0; for (i = 0; i < m; ++i) subsize += (sub[i] ? POPCOUNT(sub[i]) : 0); if (subsize <= 1) return TRUE; for (i = 0; i < n; ++i) visited[i] = 0; i = nextelement(sub,m,-1); queue[0] = i; visited[i] = 1; head = 0; tail = 1; while (head < tail) { w = queue[head++]; gw = GRAPHROW(g,w,m); for (i = 0; i < m; ++i) subw[i] = gw[i] & sub[i]; for (i = -1; (i = nextelement(subw,m,i)) >= 0;) { if (!visited[i]) { visited[i] = 1; queue[tail++] = i; } } } return tail == subsize; }
static void na_newedge(graph *g1, int m1, int n1, boolean dolabel) /* Make all graphs by non-adjacent edge addition. */ { int n2,m2; int v1,v2,w1,w2; set *sv1,*sw1; graph *gq; #if MAXN graph h[MAXN*MAXM]; grapg g2[MAXN*MAXM]; #else DYNALLSTAT(graph,h,h_sz); DYNALLSTAT(graph,g2,g2_sz); #endif n2 = n1 + 2; m2 = (n2 + WORDSIZE - 1) / WORDSIZE; if (m2 < m1) m2 = m1; #if !MAXN DYNALLOC2(graph,g2,g2_sz,m2,n2,"newedgeg"); if (dolabel) DYNALLOC2(graph,h,h_sz,m2,n2,"newedgeg"); #endif for (v1 = 0, sv1 = g1; v1 < n1-3; ++v1, sv1 += m1) for (w1 = v1+1, sw1 = sv1 + m1; w1 < n1-1; ++w1, sw1 += m1) { for (v2 = v1; (v2 = nextelement(sv1,m1,v2)) >= 0; ) for (w2 = w1; (w2 = nextelement(sw1,m1,w2)) >= 0; ) { if (v2 == w1 || v2 == w2) continue; newedge(g1,m1,n1,v1,v2,w1,w2,g2,m2); gq = g2; if (dolabel) { fcanonise(g2,m2,n2,h,NULL,FALSE); /* FIXME (loops) */ gq = h; } if (outcode == SPARSE6) writes6(outfile,gq,m2,n2); else writeg6(outfile,gq,m2,n2); ++nout; } } }
boolean isautom(graph *g, permutation *perm, boolean digraph, int m, int n) { boolean autom=TRUE; #ifdef _OPENMP #pragma omp parallel #endif { int stride=1, offs=0; register set *pg; register int pos; set *pgp; int posp,i; #ifdef _OPENMP offs=omp_get_thread_num(); stride=omp_get_num_threads(); #endif for (i = offs; autom && i < n; i+=stride) { pg=g+M*i; pgp = GRAPHROW(g,perm[i],M); pos = (digraph ? -1 : i); while ((pos = nextelement(pg,M,pos)) >= 0) { posp = perm[pos]; if (!ISELEMENT(pgp,posp)) autom=FALSE; } } } return autom; }
boolean isbiconnected(graph *g, int m, int n) /* test if g is biconnected */ { int sp,v,vc; int numvis; set *gv; #if MAXN int num[MAXN],lp[MAXN],stack[MAXN]; #else DYNALLSTAT(int,num,num_sz); DYNALLSTAT(int,lp,lp_sz); DYNALLSTAT(int,stack,stack_sz); #endif if (n <= 2) return FALSE; if (m == 1) return isbiconnected1(g,n); #if !MAXN DYNALLOC1(int,num,num_sz,n,"isbiconnected"); DYNALLOC1(int,lp,lp_sz,n,"isbiconnected"); DYNALLOC1(int,stack,stack_sz,n,"isbiconnected"); #endif num[0] = 0; for (v = 1; v < n; ++v) num[v] = -1; lp[0] = 0; numvis = 1; sp = 0; v = 0; vc = -1; gv = (set*)g; for (;;) { vc = nextelement(gv,m,vc); if (vc < 0) { if (sp <= 1) return numvis == n; vc = v; v = stack[--sp]; gv = GRAPHROW(g,v,m); if (lp[vc] >= num[v]) return FALSE; if (lp[vc] < lp[v]) lp[v] = lp[vc]; } else if (num[vc] < 0) { stack[++sp] = vc; v = vc; gv = GRAPHROW(g,v,m); vc = -1; lp[v] = num[v] = numvis++; } else if (vc != v) { if (num[vc] < lp[v]) lp[v] = num[vc]; } } }
static int trythisone(grouprec *group, int ne, int n) { int i,k; boolean accept; first = TRUE; ADDBIG(ngen,1); nix = ne; newgroupsize = 1; if (!group || groupsize == 1) accept = TRUE; else if (lastrejok && !ismax(lastreject,n)) accept = FALSE; else if (lastrejok && groupsize == 2) accept = TRUE; else { newgroupsize = 1; if (allgroup2(group,testmax) == 0) accept = TRUE; else accept = FALSE; } if (accept) { #ifdef GROUPTEST if (groupsize % newgroupsize != 0) gt_abort("group size error\n"); totallab += groupsize/newgroupsize; #endif ADDBIG(nout,1); if (outfile) { fprintf(outfile,"%d %ld",n,ne); if (Gswitch) fprintf(outfile," %lu",newgroupsize); for (i = -1; (i = nextelement(x,me,i)) >= 0; ) { k = i >> 1; if (i & 1) fprintf(outfile," %d %d",v1[k],v0[k]); else fprintf(outfile," %d %d",v0[k],v1[k]); } fprintf(outfile,"\n"); } return MAXNE+1; } else return rejectlevel;
static void no3path(graph *g, int m, int n, int v, int *dist) /* For each i, set dist[i]=0 if there is a 3-path from v to i */ { set *gv,*gv1,*gv2; int v1,v2,v3; gv = GRAPHROW(g,v,m); for (v1 = -1; (v1 = nextelement(gv,m,v1)) >= 0; ) { gv1 = GRAPHROW(g,v1,m); for (v2 = -1; (v2 = nextelement(gv1,m,v2)) >= 0; ) { if (v2 == v) continue; gv2 = GRAPHROW(g,v2,m); for (v3 = -1; (v3 = nextelement(gv2,m,v3)) >= 0; ) if (v3 != v && v3 != v1) dist[v3] = 0; } } }
int girth(graph *g, int m, int n) /* Find the girth of graph g. 0 means acyclic. */ { int i,head,tail,v,w; int best,c,dw1; set *gw; #if MAXN int dist[MAXN],queue[MAXN]; #else DYNALLSTAT(int,queue,queue_sz); DYNALLSTAT(int,dist,dist_sz); DYNALLOC1(int,queue,queue_sz,n,"girth"); DYNALLOC1(int,dist,dist_sz,n,"girth"); #endif best = n+1; for (v = 0; v < n; ++v) { for (i = 0; i < n; ++i) dist[i] = -1; queue[0] = v; dist[v] = 0; head = 0; tail = 1; while (head < tail) { w = queue[head++]; gw = GRAPHROW(g,w,m); dw1 = dist[w] + 1; for (i = -1; (i = nextelement(gw,m,i)) >= 0;) { if (dist[i] < 0) { dist[i] = dw1; queue[tail++] = i; } else if (dist[i] >= dist[w]) { c = dw1 + dist[i]; if (c < best) best = c; if ((c & 1) != 0 || c > best) break; } } if (i >= 0) break; } if (best == 3) return 3; } return (best > n ? 0 : best); }
boolean twocolouring(graph *g, int *colour, int m, int n) /* If g is bipartite, set colour[*] to 0 or 1 to indicate an example of 2-colouring and return TRUE. Otherwise return FALSE. Colour 0 is assigned to the first vertex of each component. */ { int i,head,tail,v,w,need; set *gw; #if MAXN int queue[MAXN]; #else DYNALLSTAT(int,queue,queue_sz); #endif #if !MAXN DYNALLOC1(int,queue,queue_sz,n,"twocolouring"); #endif for (i = 0; i < n; ++i) colour[i] = -1; for (v = 0; v < n; ++v) if (colour[v] < 0) { queue[0] = v; colour[v] = 0; head = 0; tail = 1; while (head < tail) { w = queue[head++]; need = 1 - colour[w]; gw = GRAPHROW(g,w,m); for (i = -1; (i = nextelement(gw,m,i)) >= 0;) { if (colour[i] < 0) { colour[i] = need; queue[tail++] = i; } else if (colour[i] != need) return FALSE; } } } return TRUE; }
void findEdgeOrbits(GRAPH graph, ADJACENCY adj){ VERTEXPAIR edges[MAXN * (MAXN - 1)/2]; n = graph[0][0]; initNautyRelatedVariables(); translateGraphToNautyDenseGraph(graph, adj); int i, v, edgeCount = 0, edgeOrbitCount; setword *gv; //call Nauty so we have the automorphism group callNauty(); //build a list of all edges for(v = 0; v < n; v++){ gv = GRAPHROW(ng, v, m); for (i = -1; (i = nextelement(gv,m,i)) >= 0;){ if(v < i){ edges[edgeCount][0] = v; edges[edgeCount][1] = i; edgeCount++; } } } //using malloc to dynamically allocate the arrays on the heap //otherwise we might run out of stack space for large, dense graphs int *edgeOrbits = (int *) malloc(sizeof(int) * edgeCount); int *edgeOrbitSizes = (int *) malloc(sizeof(int) * edgeCount); //partition the edges into orbits determineEdgeOrbits(edges, edgeCount, edgeOrbits, edgeOrbitSizes, &edgeOrbitCount); fprintf(stderr, "Graph %d has %d edge orbit%s.\n", graphCount, edgeOrbitCount, edgeOrbitCount == 1 ? "" : "s"); int orbitCount = 0; for(i = 0; i < edgeCount; i++){ if(edgeOrbits[i] == i){ fprintf(stderr, "Orbit %d (representative %d - %d) contains %d edge%s.\n", ++orbitCount, edges[i][0] + 1, edges[i][1] + 1, edgeOrbitSizes[i], edgeOrbitSizes[i] == 1 ? "" : "s"); } } }
boolean isconnected(graph *g, int m, int n) /* Test if g is connected */ { int i,head,tail,w; set *gw; #if MAXN int queue[MAXN],visited[MAXN]; #else DYNALLSTAT(int,queue,queue_sz); DYNALLSTAT(int,visited,visited_sz); #endif if (m == 1) return isconnected1(g,n); #if !MAXN DYNALLOC1(int,queue,queue_sz,n,"isconnected"); DYNALLOC1(int,visited,visited_sz,n,"isconnected"); #endif for (i = 0; i < n; ++i) visited[i] = 0; queue[0] = 0; visited[0] = 1; head = 0; tail = 1; while (head < tail) { w = queue[head++]; gw = GRAPHROW(g,w,m); for (i = -1; (i = nextelement(gw,m,i)) >= 0;) { if (!visited[i]) { visited[i] = 1; queue[tail++] = i; } } } return tail == n; }
boolean isautom(graphnau *g, permutation *perm, boolean digraph, int m, int n) { set *pg; int pos; set *pgp; int posp,i; for (pg = g, i = 0; i < n; pg += M, ++i) { pgp = GRAPHROW(g,perm[i],M); pos = (digraph ? -1 : i); while ((pos = nextelement(pg,M,pos)) >= 0) { posp = perm[pos]; if (!ISELEMENT(pgp,posp)) return FALSE; } } return TRUE; }
void find_dist2(graph *g, int m, int n, int v, int w, int *dist) /* Put in dist[0..n-1] the distance of each vertex from {v,w}. Vertices in a different component are given the distance n. */ { int i,head,tail,x; set *gx; #if MAXN int queue[MAXN]; #else DYNALLSTAT(int,queue,queue_sz); #endif #if !MAXN DYNALLOC1(int,queue,queue_sz,n,"isconnected"); #endif for (i = 0; i < n; ++i) dist[i] = n; queue[0] = v; queue[1] = w; dist[v] = dist[w] = 0; head = 0; tail = 2; while (tail < n && head < tail) { x = queue[head++]; gx = GRAPHROW(g,x,m); for (i = -1; (i = nextelement(gx,m,i)) >= 0;) { if (dist[i] == n) { dist[i] = dist[x] + 1; queue[tail++] = i; } } } }
static void refinex(graph *g, int *lab, int *ptn, int level, int *numcells, int *count, set *active, boolean goodret, int *code, int m, int n) { int i,c1,c2,labc1; setword x; int split1,split2,cell1,cell2; int cnt,bmin,bmax; set *gptr; setword workset; int workperm[MAXN]; int bucket[MAXN+2]; if (n == 1) { *code = 1; return; } *code = 0; split1 = -1; while (*numcells < n && ((split1 = nextelement(active,1,split1)) >= 0 || (split1 = nextelement(active,1,-1)) >= 0)) { DELELEMENT1(active,split1); for (split2 = split1; ptn[split2] > 0; ++split2) {} if (split1 == split2) /* trivial splitting cell */ { gptr = GRAPHROW(g,lab[split1],1); for (cell1 = 0; cell1 < n; cell1 = cell2 + 1) { for (cell2 = cell1; ptn[cell2] > 0; ++cell2) {} if (cell1 == cell2) continue; c1 = cell1; c2 = cell2; while (c1 <= c2) { labc1 = lab[c1]; if (ISELEMENT1(gptr,labc1)) ++c1; else { lab[c1] = lab[c2]; lab[c2] = labc1; --c2; } } if (c2 >= cell1 && c1 <= cell2) { ptn[c2] = 0; ++*numcells; ADDELEMENT1(active,c1); } } } else /* nontrivial splitting cell */ { workset = 0; for (i = split1; i <= split2; ++i) workset |= bit[lab[i]]; for (cell1 = 0; cell1 < n; cell1 = cell2 + 1) { for (cell2 = cell1; ptn[cell2] > 0; ++cell2) {} if (cell1 == cell2) continue; i = cell1; if ((x = workset & g[lab[i]])) /* not == */ cnt = POPCOUNT(x); else cnt = 0; count[i] = bmin = bmax = cnt; bucket[cnt] = 1; while (++i <= cell2) { if ((x = workset & g[lab[i]])) /* not == */ cnt = POPCOUNT(x); else cnt = 0; while (bmin > cnt) bucket[--bmin] = 0; while (bmax < cnt) bucket[++bmax] = 0; ++bucket[cnt]; count[i] = cnt; } if (bmin == bmax) continue; c1 = cell1; for (i = bmin; i <= bmax; ++i) if (bucket[i]) { c2 = c1 + bucket[i]; bucket[i] = c1; if (c1 != cell1) { ADDELEMENT1(active,c1); ++*numcells; } if (c2 <= cell2) ptn[c2-1] = 0; c1 = c2; } for (i = cell1; i <= cell2; ++i) workperm[bucket[count[i]]++] = lab[i]; for (i = cell1; i <= cell2; ++i) lab[i] = workperm[i]; } } if (ptn[n-2] == 0) { if (lab[n-1] == n-1) { *code = 1; if (goodret) return; } else { *code = -1; return; } } else { i = n - 1; while (1) { if (lab[i] == n-1) break; --i; if (ptn[i] == 0) { *code = -1; return; } } } } }
/* * Make duplicate object index. * * If referred tag is only one, direct link which points the tag is generated. * Else if two or more tag exists, indirect link which points the tag list * is generated. */ int makedupindex(void) { STRBUF *sb = strbuf_open(0); STRBUF *tmp = strbuf_open(0); STRBUF *command = strbuf_open(0); int definition_count = 0; char srcdir[MAXPATHLEN]; int db; FILEOP *fileop = NULL; FILE *op = NULL; FILE *ip = NULL; snprintf(srcdir, sizeof(srcdir), "../%s", SRCS); for (db = GTAGS; db < GTAGLIM; db++) { const char *kind = kinds[db]; const char *option = options[db]; int writing = 0; int count = 0; int entry_count = 0; const char *ctags_xid, *ctags_x; char tag[IDENTLEN], prev[IDENTLEN], first_line[MAXBUFLEN]; if (gtags_exist[db] == 0) continue; prev[0] = 0; first_line[0] = 0; /* * construct command line. */ strbuf_reset(command); strbuf_sprintf(command, "%s -x%s --result=ctags-xid --encode-path=\" \t\" --nofilter=path", quote_shell(global_path), option); /* * Optimization when the --dynamic option is specified. */ if (dynamic) { strbuf_puts(command, " --nosource"); if (db != GSYMS) strbuf_puts(command, " --nofilter=sort"); } strbuf_puts(command, " \".*\""); if ((ip = popen(strbuf_value(command), "r")) == NULL) die("cannot execute command '%s'.", strbuf_value(command)); while ((ctags_xid = strbuf_fgets(sb, ip, STRBUF_NOCRLF)) != NULL) { char fid[MAXFIDLEN]; ctags_x = parse_xid(ctags_xid, fid, NULL); /* tag name */ (void)strcpy_withterm(tag, ctags_x, sizeof(tag), ' '); if (strcmp(prev, tag)) { count++; if (vflag) fprintf(stderr, " [%d] adding %s %s\n", count, kind, tag); if (writing) { if (!dynamic) { fputs_nl(gen_list_end(), op); fputs_nl(body_end, op); fputs_nl(gen_page_end(), op); close_file(fileop); html_count++; } writing = 0; /* * cache record: " <fid>\0<entry number>\0" */ strbuf_reset(tmp); strbuf_putc(tmp, ' '); strbuf_putn(tmp, count - 1); strbuf_putc(tmp, '\0'); strbuf_putn(tmp, entry_count); cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1); } /* single entry */ if (first_line[0]) { char fid[MAXFIDLEN]; const char *ctags_x = parse_xid(first_line, fid, NULL); const char *lno = nextelement(ctags_x); strbuf_reset(tmp); strbuf_puts_withterm(tmp, lno, ' '); strbuf_putc(tmp, '\0'); strbuf_puts(tmp, fid); cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1); } /* * Chop the tail of the line. It is not important. * strlimcpy(first_line, ctags_x, sizeof(first_line)); */ strncpy(first_line, ctags_xid, sizeof(first_line)); first_line[sizeof(first_line) - 1] = '\0'; strlimcpy(prev, tag, sizeof(prev)); entry_count = 0; } else { /* duplicate entry */ if (first_line[0]) { char fid[MAXFIDLEN]; const char *ctags_x = parse_xid(first_line, fid, NULL); if (!dynamic) { char path[MAXPATHLEN]; snprintf(path, sizeof(path), "%s/%s/%d.%s", distpath, dirs[db], count, HTML); fileop = open_output_file(path, cflag); op = get_descripter(fileop); fputs_nl(gen_page_begin(tag, SUBDIR), op); fputs_nl(body_begin, op); fputs_nl(gen_list_begin(), op); fputs_nl(gen_list_body(srcdir, ctags_x, fid), op); } writing = 1; entry_count++; first_line[0] = 0; } if (!dynamic) { fputs_nl(gen_list_body(srcdir, ctags_x, fid), op); } entry_count++; } } if (db == GTAGS) definition_count = count; if (pclose(ip) != 0) die("'%s' failed.", strbuf_value(command)); if (writing) { if (!dynamic) { fputs_nl(gen_list_end(), op); fputs_nl(body_end, op); fputs_nl(gen_page_end(), op); close_file(fileop); html_count++; } /* * cache record: " <fid>\0<entry number>\0" */ strbuf_reset(tmp); strbuf_putc(tmp, ' '); strbuf_putn(tmp, count); strbuf_putc(tmp, '\0'); strbuf_putn(tmp, entry_count); cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1); } if (first_line[0]) { char fid[MAXFIDLEN]; const char *ctags_x = parse_xid(first_line, fid, NULL); const char *lno = nextelement(ctags_x); strbuf_reset(tmp); strbuf_puts_withterm(tmp, lno, ' '); strbuf_putc(tmp, '\0'); strbuf_puts(tmp, fid); cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1); } } strbuf_close(sb); strbuf_close(tmp); strbuf_close(command); return definition_count; }
void diamstats(graph *g, int m, int n, int *radius, int *diameter) /* Find the radius and diameter. Both -1 if g is disconnected. We use an O(mn) algorithm, which is pretty disgraceful. */ { int v,i,head,tail,w; int ecc,diam,rad; set *gw; #if MAXN int queue[MAXN],dist[MAXN]; #else DYNALLSTAT(int,queue,queue_sz); DYNALLSTAT(int,dist,dist_sz); #endif /* if (m == 1) {diamstats1(g,n,radius,diameter); return; } */ #if !MAXN DYNALLOC1(int,queue,queue_sz,n,"isconnected"); DYNALLOC1(int,dist,dist_sz,n,"isconnected"); #endif diam = -1; rad = n; for (v = 0; v < n; ++v) { for (i = 0; i < n; ++i) dist[i] = -1; queue[0] = v; dist[v] = 0; head = 0; tail = 1; while (tail < n && head < tail) { w = queue[head++]; gw = GRAPHROW(g,w,m); for (i = -1; (i = nextelement(gw,m,i)) >= 0;) { if (dist[i] < 0) { dist[i] = dist[w] + 1; queue[tail++] = i; } } } if (tail < n) { *diameter = *radius = -1; return; } ecc = dist[queue[n-1]]; if (ecc > diam) diam = ecc; if (ecc < rad) rad = ecc; } *diameter = diam; *radius = rad; }
void doref(graph *g, int *lab, int *ptn, int level, int *numcells, int *qinvar, permutation *invar, set *active, int *code, void (*refproc)(graph*,int*,int*,int,int*,permutation*,set*,int*,int,int), void (*invarproc)(graph*,int*,int*,int,int,int,permutation*, int,boolean,int,int), int mininvarlev, int maxinvarlev, int invararg, boolean digraph, int m, int n) { register int j,h; register permutation pw; int iw; int i,cell1,cell2,nc,tvpos,minlev,maxlev; long longcode; boolean same; #if !MAXN DYNALLOC1(permutation,workperm,workperm_sz,n,"doref"); #endif if ((tvpos = nextelement(active,M,-1)) < 0) tvpos = 0; (*refproc)(g,lab,ptn,level,numcells,invar,active,code,M,n); minlev = (mininvarlev < 0 ? -mininvarlev : mininvarlev); maxlev = (maxinvarlev < 0 ? -maxinvarlev : maxinvarlev); if (invarproc != NULL && *numcells < n && level >= minlev && level <= maxlev) { (*invarproc)(g,lab,ptn,level,*numcells,tvpos,invar,invararg, digraph,M,n); EMPTYSET(active,m); for (i = n; --i >= 0;) workperm[i] = invar[lab[i]]; nc = *numcells; for (cell1 = 0; cell1 < n; cell1 = cell2 + 1) { pw = workperm[cell1]; same = TRUE; for (cell2 = cell1; ptn[cell2] > level; ++cell2) if (workperm[cell2+1] != pw) same = FALSE; if (same) continue; j = (cell2 - cell1 + 1) / 3; h = 1; do h = 3 * h + 1; while (h < j); do /* shell sort */ { for (i = cell1 + h; i <= cell2; ++i) { iw = lab[i]; pw = workperm[i]; for (j = i; workperm[j-h] > pw; ) { workperm[j] = workperm[j-h]; lab[j] = lab[j-h]; if ((j -= h) < cell1 + h) break; } workperm[j] = pw; lab[j] = iw; } h /= 3; } while (h > 0); for (i = cell1 + 1; i <= cell2; ++i) if (workperm[i] != workperm[i-1]) { ptn[i-1] = level; ++*numcells; ADDELEMENT(active,i); } } if (*numcells > nc) { *qinvar = 2; longcode = *code; (*refproc)(g,lab,ptn,level,numcells,invar,active,code,M,n); longcode = MASH(longcode,*code); *code = CLEANUP(longcode); } else *qinvar = 1; } else *qinvar = 0; }
static void multi(graph *g, int nfixed, long minedges, long maxedges, long maxmult, int maxdeg, boolean lswitch, int m, int n) { static DEFAULTOPTIONS_GRAPH(options); statsblk stats; setword workspace[100]; grouprec *group; int ne; int i,j,k,j0,j1,thisdeg,maxd,x0,x1; set *gi; int lab[MAXNV],ptn[MAXNV],orbits[MAXNV],deg[MAXNV]; int delta[MAXNV],def[MAXNV]; set active[(MAXNV+WORDSIZE-1)/WORDSIZE]; boolean isreg; #ifdef PATHCOUNTS ++count0; #endif j0 = -1; /* last vertex with degree 0 */ j1 = n; /* first vertex with degree > 0 */ ne = 0; maxd = 0; for (i = 0, gi = g; i < n; ++i, gi += m) { thisdeg = 0; for (j = 0; j < m; ++j) thisdeg += POPCOUNT(gi[j]); deg[i] = thisdeg; if (thisdeg > maxd) maxd = thisdeg; if (thisdeg == 0) lab[++j0] = i; else lab[--j1] = i; ne += thisdeg; } ne /= 2; if (maxdeg >= 0 && maxd > maxdeg) return; #ifdef PATHCOUNTS ++count1; #endif if (Aswitch || Bswitch) for (i = 0; i < n; ++i) for (j = 0; j < n; ++j) edgeno[i][j] = -1; if (ne == 0 && minedges <= 0 && (!lswitch || (lswitch && (maxdeg&1) == 0))) { trythisone(NULL,lswitch,deg,maxdeg,0,n); return; } #ifdef PATHCOUNTS ++count2; #endif k = 0; for (i = 0, gi = g; i < n; ++i, gi += m) { for (j = i; (j = nextelement(gi,m,j)) >= 0; ) { v0[k] = i; v1[k] = j; edgeno[i][j] = edgeno[j][i] = k; lastlev[i] = lastlev[j] = k; ++k; } } isreg = !lswitch && (maxdeg >= 0 && 2*minedges == n*(long)maxdeg); /* Case of regular multigraphs */ if (isreg) /* regular case */ /* Condition: def(v) <= total def of neighbours */ { for (i = 0; i < n; ++i) { def[i] = maxdeg - deg[i]; delta[i] = -def[i]; } for (i = 0; i < k; ++i) { x0 = v0[i]; x1 = v1[i]; delta[x0] += def[x1]; delta[x1] += def[x0]; } for (i = 0; i < n; ++i) if (delta[i] < 0) return; } if ((isreg || lswitch) && (maxdeg & n & 1) == 1) return; if (isreg && j0 >= 0 && maxdeg > 0) return; if (lswitch && j0 >= 0 && (maxdeg&1) == 1) return; #ifdef PATHCOUNTS ++count3; #endif if (maxedges == NOLIMIT) { if (maxmult == NOLIMIT) maxedges = maxdeg*n/2; else maxedges = ne*maxmult; } if (maxmult == NOLIMIT) maxmult = maxedges - ne + 1; if (maxdeg >= 0 && maxmult > maxdeg) maxmult = maxdeg; if (maxedges < ne || ne*maxmult < minedges) return; #ifdef PATHCOUNTS ++count4; #endif if (n > MAXNV || ne > MAXNE) { fprintf(stderr,">E multig: MAXNV or MAXNE exceeded\n"); exit(1); } nauty_check(WORDSIZE,m,n,NAUTYVERSIONID); for (i = 0; i < n; ++i) ptn[i] = 1; ptn[n-1] = 0; EMPTYSET(active,m); if (j0 != n-1) ADDELEMENT(active,j0+1); for (i = 0; i <= j0; ++i) ptn[i] = 0; for (i = j0+1; i < n; ++i) if (lab[i] < nfixed) break; if (i != j0+1 && i != n) { ptn[i-1] = 0; ADDELEMENT(active,i); } options.defaultptn = FALSE; options.userautomproc = groupautomproc; options.userlevelproc = grouplevelproc; nauty(g,lab,ptn,active,orbits,&options,&stats,workspace,100,m,n,NULL); if (stats.grpsize2 == 0) groupsize = stats.grpsize1 + 0.1; else groupsize = 0; group = groupptr(FALSE); makecosetreps(group); lastrejok = FALSE; if (isreg) scan_reg(0,ne,minedges,maxedges,0,maxmult,group,n,delta,def,maxdeg); else if (lswitch) scan_lp(0,ne,minedges,maxedges,0,maxmult,group,n,deg,maxdeg); else if (maxdeg >= 0) scan_md(0,ne,minedges,maxedges,0,maxmult,group,n,deg,maxdeg); else scan(0,ne,minedges,maxedges,0,maxmult,group,n); }
//Builder function void AntiVirusLogic::BuildFromXML(ticpp::Element* xmlelement) { ///CREATION HACKS: Half hardcoded element for antivirus scan. /*ANTIVIRUSSCANNER ELEMENT: Attributes: ScanTime (number) MinSeparation(number) MaxSeparation(number) Element(x4): Sprite (with animation or image) Element(x1): Sprite (with font) */ xmlelement->GetAttribute("ScanTime",&mScanTime); mCounter = mScanTime; xmlelement->GetAttribute("MinSeparation",&mMinSeparation); xmlelement->GetAttribute("MaxSeparation",&mMaxSeparation); xmlelement->GetAttribute("TrackConstant",&mTrackK); //Correctness checking if(mScanTime < 0.5f || mMinSeparation < 1.0f || mMaxSeparation < mMinSeparation || mTrackK <= 0.0f) throw GenericException("Error while loading AntiVirus element in level config file, out of bound values",GenericException::FILE_CONFIG_INCORRECT); //Get all 5 sprite elements (ugly...) ticpp::Element* nextelement(xmlelement->FirstChildElement("Sprite")); SpriteBuilder spbuilder; //First line spbuilder.ReadSpriteParams(nextelement); spbuilder.CreateNewSprite(); mScanLineGFX1 = spbuilder.GetCreatedSprite(); //Second line nextelement = nextelement->NextSiblingElement("Sprite"); spbuilder.ReadSpriteParams(nextelement); spbuilder.CreateNewSprite(); mScanLineGFX2 = spbuilder.GetCreatedSprite(); //Third line nextelement = nextelement->NextSiblingElement("Sprite"); spbuilder.ReadSpriteParams(nextelement); spbuilder.CreateNewSprite(); mScanLineGFX3 = spbuilder.GetCreatedSprite(); //Fourth line nextelement = nextelement->NextSiblingElement("Sprite"); spbuilder.ReadSpriteParams(nextelement); spbuilder.CreateNewSprite(); mScanLineGFX4 = spbuilder.GetCreatedSprite(); //Text nextelement = nextelement->NextSiblingElement("Sprite"); spbuilder.ReadSpriteParams(nextelement); spbuilder.CreateNewSprite(); mScanText = spbuilder.GetCreatedSprite(); //Check correctness if( (!mScanLineGFX1.gfxentity->GetSurface() && !mScanLineGFX1.gfxentity->GetAnimation()) || (!mScanLineGFX2.gfxentity->GetSurface() && !mScanLineGFX2.gfxentity->GetAnimation()) || (!mScanLineGFX3.gfxentity->GetSurface() && !mScanLineGFX3.gfxentity->GetAnimation()) || (!mScanLineGFX4.gfxentity->GetSurface() && !mScanLineGFX4.gfxentity->GetAnimation()) || (mScanText.gfxentity->GetSurface() || mScanText.gfxentity->GetAnimation()) ) throw GenericException("Error while loading AntiVirus element in level config file, Element needs 4 sprites with animation or image and 1 sprite with font!",GenericException::FILE_CONFIG_INCORRECT); _resetVariables(); }
static int trythisone(grouprec *group, int ne, int n) { int i,k; boolean accept; #ifdef PROCESS graph g[WORDSIZE]; #endif first = TRUE; ++gd_ngen; nix = ne; newgroupsize = 1; ntgroup = FALSE; if (!group || groupsize == 1) accept = TRUE; else if (lastrejok && !ismax(lastreject,n)) accept = FALSE; else if (lastrejok && groupsize == 2) accept = TRUE; else { newgroupsize = 1; ntgroup = FALSE; if (allgroup2(group,testmax) == 0) accept = TRUE; else accept = FALSE; } if (accept) { #ifdef GROUPTEST if (groupsize % newgroupsize != 0) gt_abort("group size error\n"); totallab += groupsize/newgroupsize; #endif if (Vswitch && !ntisol && !ntgroup) return MAXNE+1; ++dg_nout; #ifdef PROCESS EMPTYSET(g,n); for (i = -1; (i = nextelement(x,me,i)) >= 0; ) { k = i >> 1; if (i & 1) g[v1[k]] |= bit[v0[k]]; else g[v0[k]] |= bit[v1[k]]; } PROCESS(outfile,g,n); #endif if (outfile) { fprintf(outfile,"%d %d",n,ne); if (Gswitch) fprintf(outfile," %lu",newgroupsize); for (i = -1; (i = nextelement(x,me,i)) >= 0; ) { k = i >> 1; if (i & 1) fprintf(outfile," %d %d",v1[k],v0[k]); else fprintf(outfile," %d %d",v0[k],v1[k]); } fprintf(outfile,"\n"); } return MAXNE+1; } else return rejectlevel;