Improve ezsat onehot encoding scheme

Signed-off-by: Claire Wolf <claire@symbioticeda.com>
This commit is contained in:
Claire Wolf 2020-04-02 12:22:28 +02:00
parent f72b65b2a5
commit 65a3ff69bd
1 changed files with 27 additions and 13 deletions

View File

@ -1371,20 +1371,34 @@ int ezSAT::onehot(const std::vector<int> &vec, bool max_only)
if (max_only == false) if (max_only == false)
formula.push_back(expression(OpOr, vec)); formula.push_back(expression(OpOr, vec));
// create binary vector if (vec.size() < 8)
int num_bits = clog2(vec.size()); {
std::vector<int> bits; // fall-back to simple O(n^2) solution for small cases
for (int k = 0; k < num_bits; k++) for (size_t i = 0; i < vec.size(); i++)
bits.push_back(literal()); for (size_t j = i+1; j < vec.size(); j++) {
std::vector<int> clause;
clause.push_back(NOT(vec[i]));
clause.push_back(NOT(vec[j]));
formula.push_back(expression(OpOr, clause));
}
}
else
{
// create binary vector
int num_bits = clog2(vec.size());
std::vector<int> bits;
for (int k = 0; k < num_bits; k++)
bits.push_back(literal());
// add at-most-one clauses using binary encoding // add at-most-one clauses using binary encoding
for (size_t i = 0; i < vec.size(); i++) for (size_t i = 0; i < vec.size(); i++)
for (int k = 0; k < num_bits; k++) { for (int k = 0; k < num_bits; k++) {
std::vector<int> clause; std::vector<int> clause;
clause.push_back(NOT(vec[i])); clause.push_back(NOT(vec[i]));
clause.push_back((i & (1 << k)) != 0 ? bits[k] : NOT(bits[k])); clause.push_back((i & (1 << k)) != 0 ? bits[k] : NOT(bits[k]));
formula.push_back(expression(OpOr, clause)); formula.push_back(expression(OpOr, clause));
} }
}
return expression(OpAnd, formula); return expression(OpAnd, formula);
} }