mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 17:15:31 +00:00
fixing model-based-opt
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
22507281cf
commit
67e49b4adc
3 changed files with 130 additions and 16 deletions
|
@ -1,20 +1,121 @@
|
|||
#include "model_based_opt.h"
|
||||
#include "util.h"
|
||||
#include "uint_set.h"
|
||||
|
||||
typedef opt::model_based_opt::var var;
|
||||
|
||||
static void add_ineq(opt::model_based_opt& mbo, unsigned x, int a, unsigned y, int b, int k, opt::ineq_type rel) {
|
||||
static void add_ineq(opt::model_based_opt& mbo, unsigned x, int a, int k, opt::ineq_type rel) {
|
||||
vector<var> vars;
|
||||
vars.push_back(var(x, rational(a)));
|
||||
mbo.add_constraint(vars, rational(k), rel);
|
||||
}
|
||||
|
||||
static void add_ineq(opt::model_based_opt& mbo,
|
||||
unsigned x, int a,
|
||||
unsigned y, int b, int k,
|
||||
opt::ineq_type rel) {
|
||||
vector<var> vars;
|
||||
vars.push_back(var(x, rational(a)));
|
||||
vars.push_back(var(y, rational(b)));
|
||||
mbo.add_constraint(vars, rational(k), rel);
|
||||
}
|
||||
|
||||
static void add_ineq(opt::model_based_opt& mbo, unsigned x, int a, int k, opt::ineq_type rel) {
|
||||
static void add_ineq(opt::model_based_opt& mbo,
|
||||
unsigned x, int a,
|
||||
unsigned y, int b,
|
||||
unsigned z, int c, int k,
|
||||
opt::ineq_type rel) {
|
||||
vector<var> vars;
|
||||
vars.push_back(var(x, rational(a)));
|
||||
vars.push_back(var(y, rational(b)));
|
||||
vars.push_back(var(z, rational(c)));
|
||||
mbo.add_constraint(vars, rational(k), rel);
|
||||
}
|
||||
|
||||
static void add_random_ineq(opt::model_based_opt& mbo,
|
||||
random_gen& r,
|
||||
svector<int> const& values,
|
||||
unsigned max_vars,
|
||||
unsigned max_coeff) {
|
||||
unsigned num_vars = values.size();
|
||||
uint_set used_vars;
|
||||
vector<var> vars;
|
||||
int value = 0;
|
||||
for (unsigned i = 0; i < max_vars; ++i) {
|
||||
unsigned x = r(num_vars);
|
||||
if (used_vars.contains(x)) {
|
||||
continue;
|
||||
}
|
||||
used_vars.insert(x);
|
||||
int coeff = r(max_coeff + 1);
|
||||
if (coeff == 0) {
|
||||
continue;
|
||||
}
|
||||
unsigned sign = r(2);
|
||||
coeff = sign == 0 ? coeff : -coeff;
|
||||
vars.push_back(var(x, rational(coeff)));
|
||||
value += coeff*values[x];
|
||||
}
|
||||
unsigned abs_value = value < 0 ? - value : value;
|
||||
// value + k <= 0
|
||||
// k <= - value
|
||||
// range for k is 2*|value|
|
||||
// k <= - value - range
|
||||
opt::ineq_type rel = opt::t_le;
|
||||
|
||||
int coeff = 0;
|
||||
if (r(4) == 0) {
|
||||
rel = opt::t_eq;
|
||||
coeff = -value;
|
||||
}
|
||||
else {
|
||||
if (abs_value > 0) {
|
||||
coeff = -value - r(2*abs_value);
|
||||
}
|
||||
else {
|
||||
coeff = 0;
|
||||
}
|
||||
if (coeff != -value && r(3) == 0) {
|
||||
rel = opt::t_lt;
|
||||
}
|
||||
}
|
||||
mbo.add_constraint(vars, rational(coeff), rel);
|
||||
}
|
||||
|
||||
static void check_random_ineqs(random_gen& r, unsigned num_vars, unsigned max_value, unsigned num_ineqs, unsigned max_vars, unsigned max_coeff) {
|
||||
opt::model_based_opt mbo;
|
||||
svector<int> values;
|
||||
for (unsigned i = 0; i < num_vars; ++i) {
|
||||
values.push_back(r(max_value + 1));
|
||||
mbo.add_var(rational(values.back()));
|
||||
}
|
||||
for (unsigned i = 0; i < num_ineqs; ++i) {
|
||||
add_random_ineq(mbo, r, values, max_vars, max_coeff);
|
||||
}
|
||||
|
||||
vector<var> vars;
|
||||
vars.reset();
|
||||
vars.push_back(var(0, rational(2)));
|
||||
vars.push_back(var(1, rational(-2)));
|
||||
mbo.set_objective(vars, rational(0));
|
||||
|
||||
mbo.display(std::cout);
|
||||
opt::inf_eps value = mbo.maximize();
|
||||
std::cout << "optimal: " << value << "\n";
|
||||
mbo.display(std::cout);
|
||||
for (unsigned i = 0; i < values.size(); ++i) {
|
||||
std::cout << i << ": " << values[i] << " -> " << mbo.get_value(i) << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
static void check_random_ineqs() {
|
||||
random_gen r(1);
|
||||
|
||||
for (unsigned i = 0; i < 1009; ++i) {
|
||||
check_random_ineqs(r, 4, 5, 5, 3, 6);
|
||||
}
|
||||
}
|
||||
|
||||
// test with upper bounds
|
||||
static void test1() {
|
||||
opt::model_based_opt mbo;
|
||||
|
@ -118,6 +219,7 @@ static void test4() {
|
|||
// test with mix of upper and lower bounds
|
||||
|
||||
void tst_model_based_opt() {
|
||||
check_random_ineqs();
|
||||
test1();
|
||||
test2();
|
||||
test3();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue