Ejemplo n.º 1
0
static int
do_search(struct saucy *s)
{
	int min;

	unprepare_permutation(s);

	/* Backtrack to the ancestor with zeta */
	if (s->lev > s->anc) s->lev = s->anc + 1;

	/* Perform additional backtracking */
	min = backtrack(s);

	/* Keep going while there are tree nodes to expand */
	while (s->lev) {

		/* Descend to a new leaf node */	
		if (descend(s, &s->right, s->start[s->lev], min)
				&& descend_left(s)) {

			/* Prepare permutation */
			prepare_permutation(s);

			/* If we found an automorphism, return it */
			if (s->is_automorphism(s)) {
				++s->stats->gens;
				s->stats->support += s->ndiffs;
				update_theta(s);
				return s->consumer(s->n, s->gamma,
					s->ndiffs, s->unsupp, s->arg);
			}
			else {
				unprepare_permutation(s);
			}
		}

		/* If we get here, something went wrong; backtrack */
		++s->stats->bads;
		min = backtrack_bad(s);
	}

	/* Normalize group size */
	while (s->stats->grpsize_base >= 10.0) {
		s->stats->grpsize_base /= 10;
		++s->stats->grpsize_exp;
	}
	return 0;
}
Ejemplo n.º 2
0
int *
saucy_search(void)
{
	int i;

	/* Do initialization steps if necessary */
	if (!init) {
		init = 1;

		/* Initialize stats */
		stats->grpsize_base = 1.0;
		stats->grpsize_exp = stats->nodes = stats->bads = stats->gens = 0;

		/* Preprocessing after initial coloring */
		refine();
	}

	/* Keep going while there are tree nodes to expand */
	while (lev) {
		if (desc) { desc = 0; descend(); }

		/* Find a target cell */
		++stats->nodes; target_cell();
		if (target != n+1) { descend_left(); continue; }

		/* We don't have a target, so we're discrete */
		if (!have_zeta) {
			have_zeta = 1;
			for (i = 0; i < n; ++i) zeta[lab[i]] = i;
			if (canon != NULL) memcpy(canon, lab, n * sizeof(int));
		}
		else {
			/* Prepare permutation and check */
			for (i = 0; i < n; ++i) gamma[i] = lab[zeta[i]];
			is_automorphism();

			/* Do some stuff if we actually got an automorphism */
			if (flag) {
				++stats->gens;
				update_theta();
			}
			/* Keep track of leaf nodes that are not automorphisms */
			else {
				++stats->bads;
			}
		}

		/* Since we're discrete, we need to backtrack */
		backtrack(stats); desc = 1;
		if (flag) return gamma;
	}

	/* Normalize group size */
	while (stats->grpsize_base >= 10.0) {
		stats->grpsize_base /= 10;
		++stats->grpsize_exp;
	}

	/* All done */
	return NULL;
}