22
22
#include " math/lp/lar_solver.h"
23
23
#include " math/lp/lp_utils.h"
24
24
25
- #define SMALL_CUTS 1
26
25
namespace lp {
27
26
28
27
struct create_cut {
@@ -36,9 +35,7 @@ struct create_cut {
36
35
mpq m_one_minus_f;
37
36
mpq m_fj;
38
37
mpq m_one_minus_fj;
39
- #if SMALL_CUTS
40
38
mpq m_abs_max, m_big_number;
41
- #endif
42
39
int m_polarity;
43
40
bool m_found_big;
44
41
u_dependency* m_dep;
@@ -84,11 +81,8 @@ struct create_cut {
84
81
}
85
82
m_t .add_monomial (new_a, j);
86
83
TRACE (" gomory_cut_detail" , tout << " new_a = " << new_a << " , k = " << m_k << " \n " ;);
87
- #if SMALL_CUTS
88
- // if (numerator(new_a).is_big()) throw found_big();
89
84
if (numerator (new_a) > m_big_number)
90
85
m_found_big = true ;
91
- #endif
92
86
}
93
87
94
88
void set_polarity (int p) {
@@ -134,11 +128,8 @@ struct create_cut {
134
128
TRACE (" gomory_cut_detail_real" , tout << " add " << new_a << " *v" << j << " , k: " << m_k << " \n " ;
135
129
tout << " m_t = " ; lia.lra .print_term (m_t , tout) << " \n k: " << m_k << " \n " ;);
136
130
137
- #if SMALL_CUTS
138
- // if (numerator(new_a).is_big()) throw found_big();
139
131
if (numerator (new_a) > m_big_number)
140
132
m_found_big = true ;
141
- #endif
142
133
}
143
134
144
135
lia_move report_conflict_from_gomory_cut () {
@@ -265,16 +256,14 @@ struct create_cut {
265
256
tout << " 1 - m_f: " << 1 - m_f << " , get_value(m_inf_col).x - m_f = " << get_value (m_inf_col).x - m_f << " \n " ;);
266
257
lp_assert (m_f.is_pos () && (get_value (m_inf_col).x - m_f).is_int ());
267
258
268
- bool some_int_columns = false ;
269
- #if SMALL_CUTS
270
259
m_abs_max = 0 ;
271
260
for (const auto & p : m_row) {
272
261
mpq t = abs (ceil (p.coeff ()));
273
262
if (t > m_abs_max)
274
263
m_abs_max = t;
275
264
}
276
265
m_big_number = m_abs_max.expt (2 );
277
- # endif
266
+
278
267
for (const auto & p : m_row) {
279
268
unsigned j = p.var ();
280
269
if (j == m_inf_col) continue ;
@@ -288,7 +277,6 @@ struct create_cut {
288
277
if (is_real (j))
289
278
real_case_in_gomory_cut (- p.coeff (), j);
290
279
else if (!p.coeff ().is_int ()) {
291
- some_int_columns = true ;
292
280
m_fj = fractional_part (-p.coeff ());
293
281
m_one_minus_fj = 1 - m_fj;
294
282
int_case_in_gomory_cut (j);
@@ -315,8 +303,6 @@ struct create_cut {
315
303
return report_conflict_from_gomory_cut ();
316
304
}
317
305
TRACE (" gomory_cut" , print_linear_combination_of_column_indices_only (m_t .coeffs_as_vector (), tout << " gomory cut: " ); tout << " >= " << m_k << std::endl;);
318
- if (lia.lra .settings ().m_gomory_simplify && some_int_columns)
319
- simplify_inequality ();
320
306
321
307
m_dep = nullptr ;
322
308
for (auto c : *m_ex)
@@ -330,99 +316,6 @@ struct create_cut {
330
316
return lia_move::cut;
331
317
}
332
318
333
- // TODO: use this also for HNF cuts?
334
- mpq m_lcm_den = { mpq (1 ) };
335
-
336
- void simplify_inequality () {
337
-
338
- auto divd = [](mpq& r, mpq const & d) {
339
- r /= d;
340
- if (!r.is_int ())
341
- r = ceil (r);
342
- };
343
- SASSERT (!lia.m_upper );
344
- lp_assert (!m_t .is_empty ());
345
- // k = 1 + sum of m_t at bounds
346
- lar_term t = lia.lra .unfold_nested_subterms (m_t );
347
- auto pol = t.coeffs_as_vector ();
348
- m_t .clear ();
349
- if (pol.size () == 1 && is_int (pol[0 ].second )) {
350
- TRACE (" gomory_cut_detail" , tout << " pol.size() is 1" << std::endl;);
351
- auto const & [a, v] = pol[0 ];
352
- lp_assert (is_int (v));
353
- if (a.is_pos ()) { // we have av >= k
354
- divd (m_k, a);
355
- m_t .add_monomial (mpq (1 ), v);
356
- }
357
- else {
358
- // av >= k
359
- // a/-a*v >= k / - a
360
- // -v >= k / - a
361
- // -v >= ceil(k / -a)
362
- divd (m_k, -a);
363
- m_t .add_monomial (-mpq (1 ), v);
364
- }
365
- }
366
- else {
367
- m_lcm_den = denominator (m_k);
368
- for (auto const & [c, v] : pol)
369
- m_lcm_den = lcm (m_lcm_den, denominator (c));
370
- lp_assert (m_lcm_den.is_pos ());
371
- bool int_row = all_of (pol, [&](auto const & kv) { return is_int (kv.second ); });
372
- TRACE (" gomory_cut_detail" , tout << " pol.size() > 1 den: " << m_lcm_den << std::endl;);
373
-
374
- if (!m_lcm_den.is_one ()) {
375
- // normalize coefficients of integer parameters to be integers.
376
- for (auto & [c,v]: pol) {
377
- c *= m_lcm_den;
378
- SASSERT (!is_int (v) || c.is_int ());
379
- }
380
- m_k *= m_lcm_den;
381
- }
382
- // ax + by >= k
383
- // b > 0, c1 <= y <= c2
384
- // ax + b*c2 >= ax + by >= k
385
- // =>
386
- // ax >= k - by >= k - b*c1
387
- // b < 0
388
- // ax + b*c1 >= ax + by >= k
389
- //
390
- unsigned j = 0 , i = 0 ;
391
- for (auto & [c, v] : pol) {
392
- if (lia.is_fixed (v)) {
393
- push_explanation (column_lower_bound_constraint (v));
394
- push_explanation (column_upper_bound_constraint (v));
395
- m_k -= c * lower_bound (v).x ;
396
- }
397
- else
398
- pol[j++] = pol[i];
399
- ++i;
400
- }
401
- pol.shrink (j);
402
-
403
- // gcd reduction is loss-less:
404
- mpq g (1 );
405
- for (const auto & [c, v] : pol)
406
- g = gcd (g, c);
407
- if (!int_row)
408
- g = gcd (g, m_k);
409
-
410
- if (g != 1 ) {
411
- for (auto & [c, v] : pol)
412
- c /= g;
413
- divd (m_k, g);
414
- }
415
-
416
- for (const auto & [c, v]: pol)
417
- m_t .add_monomial (c, v);
418
- VERIFY (m_t .size () > 0 );
419
- }
420
-
421
- TRACE (" gomory_cut_detail" , tout << " k = " << m_k << std::endl;);
422
- lp_assert (m_k.is_int ());
423
- }
424
-
425
-
426
319
create_cut (lar_term & t, mpq & k, explanation* ex, unsigned basic_inf_int_j, const row_strip<mpq>& row, int_solver& lia) :
427
320
m_t (t),
428
321
m_k (k),
@@ -570,7 +463,7 @@ struct create_cut {
570
463
571
464
}
572
465
573
- // this way we create bounds for the variables in polar cases even where the terms had big numbers
466
+ // this way we create bounds for the variables in polar cases even where the terms have big numbers
574
467
for (auto const & p : polar_vars) {
575
468
if (p.polarity == 1 ) {
576
469
lra.update_column_type_and_bound (p.j , lp::lconstraint_kind::LE, floor (lra.get_column_value (p.j ).x ), p.dep );
0 commit comments