Пример #1
0
int32_t choose_unfixed_variable(atom_table_t *atom_table) {
	samp_truth_value_t *assignment = atom_table->assignment;
	int32_t num_vars = atom_table->num_vars;
	int32_t num_unfixed_vars = atom_table->num_unfixed_vars;

	uint32_t var, d, y;

	if (num_unfixed_vars == 0)
		return -1;

	// var = random_uint(num_vars);
	var = genrand_uint(num_vars);
	if (unfixed_tval(assignment[var]))
		return var;
	// d = 1 + random_uint(num_vars - 1);
	d = 1 + genrand_uint(num_vars - 1);
	while (gcd32(d, num_vars) != 1)
		d--;

	y = var;
	do {
		y += d;
		if (y >= num_vars)
			y -= num_vars;
		assert(var != y);
	} while (!unfixed_tval(assignment[y]));
	return y;
}
Пример #2
0
samp_clause_t *choose_random_clause(samp_clause_list_t *list) {
	//int32_t clsidx = random_uint(list->length);
	int32_t clsidx = genrand_uint(list->length);
	samp_clause_t *ptr = list->head;
	for (; clsidx > 0; clsidx--) {
		ptr = next_clause_ptr(ptr);
	}
	return ptr->link;
}
Пример #3
0
int32_t choose_clause_var(samp_table_t *table, samp_clause_t *clause,
		double rvar_probability) {
	rule_inst_table_t *rule_inst_table = &table->rule_inst_table;
	atom_table_t *atom_table = &table->atom_table;
	integer_stack_t *clause_var_stack = &table->clause_var_stack;
	uint32_t i, sidx, vidx;

	if (clause_var_stack->size == 0) {
		init_integer_stack(clause_var_stack, 0);
	} else {
		clear_integer_stack(clause_var_stack);
	}

	double choice = choose();
	if (choice < rvar_probability) { /* flip a random unfixed variable */
		for (i = 0; i < clause->num_lits; i++) {
			if (unfixed_tval(atom_table->assignment[var_of(clause->disjunct[i])]))
				push_integer_stack(i, clause_var_stack);
		} 
		if (unfixed_tval(rule_inst_table->assignment[clause->rule_index]))
			push_integer_stack(clause->num_lits, clause_var_stack);
		/* all unfixed vars are now in clause_var_stack */
	} else {
		int32_t dcost = INT32_MAX, vcost = 0;
		for (i = 0; i < clause->num_lits; i++) {
			if (unfixed_tval(atom_table->assignment[var_of(clause->disjunct[i])])) {
				cost_flip_unfixed_variable(table, var_of(clause->disjunct[i]), &vcost);
				if (dcost >= vcost) {
					if (dcost > vcost) {
						dcost = vcost;
						clear_integer_stack(clause_var_stack);
					}
					push_integer_stack(i, clause_var_stack);
				}
			}
		}
		if (unfixed_tval(rule_inst_table->assignment[clause->rule_index])) {
			cost_flip_unfixed_rule(table, clause->rule_index, &vcost);
			if (dcost > vcost) {
				dcost = vcost;
				clear_integer_stack(clause_var_stack);
				push_integer_stack(clause->num_lits, clause_var_stack);
			}
		}
	}
	//sidx = random_uint(length_integer_stack(clause_var_stack));
	sidx = genrand_uint(length_integer_stack(clause_var_stack));
	vidx = nth_integer_stack(sidx, clause_var_stack);

	return vidx;
}
Пример #4
0
/* MaxWalkSAT */
void mw_sat(samp_table_t *table, int32_t num_trials, double rvar_probability,
		int32_t max_flips, uint32_t timeout) {
	rule_inst_table_t *rule_inst_table = &table->rule_inst_table;
	atom_table_t *atom_table = &table->atom_table;
	int32_t i, j;
	time_t fintime;

	if (timeout != 0) {
		fintime = time(NULL) + timeout;
	}

	double best_cost = DBL_MAX;
	for (i = 0; i < num_trials; i++) {
		init_random_assignment(table);
		//scan_rule_instances(table);
		for (j = 0; j < rule_inst_table->num_rule_insts; j++) {
			if (rule_inst_table->rule_insts[j]->weight == DBL_MAX) 
				rule_inst_table->assignment[j] = v_up_true;
			else
				rule_inst_table->assignment[j] = v_true;
		}
		init_live_clauses(table);
		scan_live_clauses(table);

		if (get_verbosity_level() >= 3) {
			printf("\n[mw_sat] Trial %d: \n", i);
			print_live_clauses(table);
		}

		for (j = 0; j < max_flips; j++) {

			if (timeout != 0 && time(NULL) >= fintime) {
				printf("Timeout after %"PRIu32" samples\n", i);
				break;
			}

			if (rule_inst_table->unsat_clauses.length == 0 
					&& rule_inst_table->unsat_soft_rules.nelems == 0) {
				return;
			}
			int32_t c = genrand_uint(rule_inst_table->unsat_clauses.length
					+ rule_inst_table->unsat_soft_rules.nelems);

			if (c < rule_inst_table->unsat_clauses.length) { /* picked a hard clause */
				samp_clause_t *clause = choose_random_clause(&rule_inst_table->unsat_clauses);
				int32_t litidx = choose_clause_var(table, clause, rvar_probability);
				
				if (litidx == clause->num_lits) {
					if (get_verbosity_level() >= 3) {
						printf("[flip_rule_to_unsat] Rule %d: ", clause->rule_index);
						print_rule_instance(rule_inst_table->rule_insts[clause->rule_index], table);
						printf("\n");
					}
					/* picked the rule auxiliary variable, i.e., rinst T -> F */
					hmap_get(&rule_inst_table->unsat_soft_rules, clause->rule_index);
					rule_inst_table->assignment[clause->rule_index] = v_false;
					rule_inst_t *rinst = rule_inst_table->rule_insts[clause->rule_index];
					rule_inst_table->unsat_weight += rinst->weight;
                                        /* Is this really going to do the right thing?? */
					rule_inst_table->sat_weight   -= rinst->weight;
					/* move unsat_clauses to live_clause_list and rescan */
					clause_list_concat(&rule_inst_table->unsat_clauses, 
							&rule_inst_table->live_clauses);
					scan_live_clauses(table);
				} else { 
					flip_unfixed_variable(table, var_of(clause->disjunct[litidx]));
				}
			} else {
				/* picked a soft rule auxiliary variable, i.e., rinst F -> T */
				int32_t rule_index = hmap_remove_random(&rule_inst_table->unsat_soft_rules);
				rule_inst_table->assignment[rule_index] = v_true;
				rule_inst_t *rinst = rule_inst_table->rule_insts[rule_index];
				rule_inst_table->unsat_weight -= rinst->weight;
				rule_inst_table->sat_weight   += rinst->weight;
				if (get_verbosity_level() >= 3) {
					printf("[flip_rule_to_sat] Rule %d: ", rule_index);
					print_rule_instance(rinst, table);
					printf("\n");
				}
				/* move watch[~r] to live_clause_list and rescan */
				clause_list_concat(&rule_inst_table->rule_watched[rule_index],
						&rule_inst_table->live_clauses);
				scan_live_clauses(table);
			}

			if (get_verbosity_level() >= 1) {
				printf("[mw_sat] Flip %d: # unsat hard = %d, # unsat soft = %d, " 
						"weight of unsat soft = %f; weight of sat soft = %f\n", j,
						rule_inst_table->unsat_clauses.length,
						rule_inst_table->unsat_soft_rules.nelems,
                                                rule_inst_table->unsat_weight,
                                                rule_inst_table->sat_weight
                                       );
			}
			if (get_verbosity_level() >= 3) {
				print_live_clauses(table);
			}

			if (best_cost > rule_inst_table->unsat_weight) {
				best_cost = rule_inst_table->unsat_weight;
				copy_assignment_array(atom_table);
			}
		}
	}
	restore_assignment_array(atom_table);
}
Пример #5
0
/*
 * [lazy only] Choose a random atom for simulated annealing step in sample SAT.
 * The lazy version of choose_unfixed_variable. First choose a random atom,
 * regardless whether its value is fixed or not (because we can calculate the
 * total number of atoms and it is convenient to randomly choose one from
 * them). If its value is fixed, we skip this flip using the following
 * statement (return 0).
 */
int32_t choose_random_atom(samp_table_t *table) {
	uint32_t i, atom_num, anum;
	int32_t card, all_card, acard, pcard, predicate;
	pred_tbl_t *pred_tbl = &table->pred_table.pred_tbl; // Indirect preds
	atom_table_t *atom_table = &table->atom_table;
	sort_table_t *sort_table = &table->sort_table;
	pred_entry_t *pred_entry;

	assert(valid_table(table));

	/* Get the number of possible indirect atoms */
	all_card = all_atoms_cardinality(pred_tbl, sort_table);

	//atom_num = random_uint(all_card);
	atom_num = genrand_uint(all_card);

	predicate = 1; /* Skip past true */
	acard = 0;
	while (true) { /* determine the predicate */
		assert(predicate <= pred_tbl->num_preds);
		pcard = pred_cardinality(pred_tbl, sort_table, predicate);
		if (acard + pcard > atom_num) {
			break;
		}
		acard += pcard;
		predicate++;
	}
	assert(pred_cardinality(pred_tbl, sort_table, predicate) != 0);

	/* gives the position of atom within predicate */
	anum = atom_num - acard; 	

	/*
	 * Now calculate the arguments. We represent the arguments in
	 * little-endian form
	 */
	pred_entry = &pred_tbl->entries[predicate];
	int32_t *signature = pred_entry->signature;
	int32_t arity = pred_entry->arity;
	atom_buffer_resize(arity);
	int32_t constant;
	samp_atom_t *atom = (samp_atom_t *) atom_buffer.data;
	/* Build atom from atom_num by successive division */
	atom->pred = predicate;
	for (i = 0; i < arity; i++) {
		card = sort_table->entries[signature[i]].cardinality;
		constant = anum % card;
		anum = anum / card;
		sort_entry_t *sort_entry = &sort_table->entries[signature[i]];
		if (sort_entry->constants == NULL) {
			/* Must be an integer */
			if (sort_entry->ints == NULL) {
				atom->args[i] = sort_entry->lower_bound + constant;
			} else {
				atom->args[i] = sort_entry->ints[constant];
			}
		} else {
			atom->args[i] = sort_entry->constants[constant];
			/* Quick typecheck */
			assert(const_sort_index(atom->args[i], &table->const_table) == signature[i]);
		}
	}
	assert(valid_table(table));

	array_hmap_pair_t *atom_map;
	atom_map = array_size_hmap_find(&atom_table->atom_var_hash, arity + 1,
			(int32_t *) atom);

	int32_t atom_index;

	if (atom_map == NULL) {
		/* need to activate atom */
		atom_index = add_internal_atom(table, atom, false);
		atom_map = array_size_hmap_find(&atom_table->atom_var_hash, arity + 1,
				(int32_t *) atom);
		assert(atom_map != NULL);
		activate_atom(table, atom_index);
	}
	else {
		atom_index = atom_map->val;
	}

	return atom_index;
}