Skip to content

Commit 5d16246

Browse files
committed
tests if threre are any complements of a variable in the extended clique
1 parent 12c8fcf commit 5d16246

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

cpp/src/mip/presolve/conflict_graph/clique_table.cu

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ i_t clique_table_t<i_t, f_t>::get_degree_of_var(i_t var_idx)
297297
template <typename i_t, typename f_t>
298298
bool clique_table_t<i_t, f_t>::check_adjacency(i_t var_idx1, i_t var_idx2)
299299
{
300+
// if passed same variable
301+
if (var_idx1 == var_idx2) { return false; }
302+
// in case they are complements of each other
303+
if (var_idx1 % n_variables == var_idx2 % n_variables) { return true; }
300304
if (adj_list_small_cliques[var_idx1].count(var_idx2) > 0) { return true; }
301305
// Check first cliques: var_clique_map_first stores clique indices
302306
for (const auto& clique_idx : var_clique_map_first[var_idx1]) {
@@ -396,6 +400,29 @@ bool extend_clique(const std::vector<i_t>& clique,
396400
}
397401
// if we found a larger cliqe, insert it into the formulation
398402
if (new_clique.size() > clique.size()) {
403+
// Before inserting the new clique, check if a variable and its complement are both present
404+
// Assuming complement of variable x is x + n_variables (as typical in these encodings)
405+
bool has_var_and_complement = false;
406+
for (size_t i = 0; i < new_clique.size(); ++i) {
407+
i_t var = new_clique[i];
408+
i_t complement = -1;
409+
// determine complement only if var is in the range of variables
410+
if (var < clique_table.n_variables) {
411+
complement = var + clique_table.n_variables;
412+
} else if (var < 2 * clique_table.n_variables) {
413+
complement = var - clique_table.n_variables;
414+
}
415+
// check if complement exists in the clique
416+
if (complement != -1 &&
417+
std::find(new_clique.begin(), new_clique.end(), complement) != new_clique.end()) {
418+
has_var_and_complement = true;
419+
break;
420+
}
421+
}
422+
if (has_var_and_complement) {
423+
CUOPT_LOG_DEBUG("Not adding clique: contains variable and its complement in the same clique");
424+
exit(0);
425+
}
399426
clique_table.first.push_back(new_clique);
400427
CUOPT_LOG_DEBUG("Extended clique: %lu from %lu", new_clique.size(), clique.size());
401428
// insert the new clique into the problem as a new constraint

cpp/src/mip/presolve/conflict_graph/clique_table.cuh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ struct clique_table_t {
6262
var_clique_map_first(n_vertices),
6363
var_clique_map_addtl(n_vertices),
6464
adj_list_small_cliques(n_vertices),
65-
var_degrees(n_vertices, -1)
65+
var_degrees(n_vertices, -1),
66+
n_variables(n_vertices / 2)
6667
{
6768
}
6869

@@ -84,7 +85,8 @@ struct clique_table_t {
8485
std::unordered_map<i_t, std::unordered_set<i_t>> adj_list_small_cliques;
8586
// degrees of each vertex
8687
std::vector<i_t> var_degrees;
87-
88+
// number of variables in the original problem
89+
const i_t n_variables;
8890
const i_t min_clique_size;
8991
const i_t max_clique_size_for_extension;
9092
typename mip_solver_settings_t<i_t, f_t>::tolerances_t tolerances;

0 commit comments

Comments
 (0)