101 absl::MutexLock mutex_lock(mutex_);
108 if (clauses_table_.empty()) {
109 clauses_table_.push_back({
"SAT stats",
"ClassicMinim",
"LitRemoved",
110 "LitRemovedBinary",
"LitLearned",
"LitForgotten",
121 if (vivify_table_.empty()) {
122 vivify_table_.push_back({
"Vivification",
"Clauses",
"Decisions",
"LitTrue",
123 "Subsumed",
"LitRemoved",
"DecisionReused",
136 if (bool_var_table_.empty()) {
137 bool_var_table_.push_back({
"SAT formula",
"Fixed",
"Equiv",
"Total",
138 "VarLeft",
"BinaryClauses",
"PermanentClauses",
139 "TemporaryClauses"});
142 const int64_t num_fixed = sat_solver->NumFixedVariables();
143 const int64_t num_equiv = binary->num_current_equivalences() / 2;
145 bool_var_table_.push_back(
151 clause_manager->num_removable_clauses()),
158 if (clauses_deletion_table_.empty()) {
159 clauses_deletion_table_.push_back(
160 {
"Clause deletion",
"at_true",
"l_and_not(l)",
"to_binary",
161 "sub_conflict",
"sub_extra",
"sub_decisions",
"sub_eager",
162 "sub_vivify",
"sub_probing",
"sub_inpro",
"blocked",
"eliminated",
163 "forgotten",
"promoted",
"conflicts"});
165 absl::Span<const int64_t> deletion_by_source =
167 clauses_deletion_table_.push_back(
200 absl::MutexLock mutex_lock(mutex_);
203 int64_t num_compo = 0;
204 int64_t num_iter = 0;
206 int64_t num_optimal = 0;
207 int64_t num_dual_feasible = 0;
208 int64_t num_dual_unbounded = 0;
211 std::string dimension;
214 int64_t num_constraints = 0;
215 int64_t num_constraint_updates = 0;
216 int64_t num_simplifications = 0;
217 int64_t num_merged_constraints = 0;
218 int64_t num_shortened_constraints = 0;
219 int64_t num_split_constraints = 0;
220 int64_t num_coeff_strengthening = 0;
221 int64_t num_cuts = 0;
222 int64_t num_add_cut_calls = 0;
225 absl::btree_map<std::string, int> type_to_num_cuts;
228 int64_t total_num_cut_propagations = 0;
229 int64_t total_num_eq_propagations = 0;
230 int64_t num_adjusts = 0;
231 int64_t num_cut_overflows = 0;
232 int64_t num_bad_cuts = 0;
233 int64_t num_scaling_issues = 0;
236 for (
const auto* lp : *lps) {
237 const auto& manager = lp->constraint_manager();
239 num_iter += lp->total_num_simplex_iterations();
240 num_cut += manager.num_cuts();
241 const auto& num_solve_by_status = lp->num_solves_by_status();
244 if (optimal_as_int < num_solve_by_status.size()) {
245 num_optimal += num_solve_by_status[optimal_as_int];
248 const int dual_feasible_as_int =
250 if (dual_feasible_as_int < num_solve_by_status.size()) {
251 num_dual_feasible += num_solve_by_status[dual_feasible_as_int];
254 const int dual_unbounded_as_int =
256 if (dual_unbounded_as_int < num_solve_by_status.size()) {
257 num_dual_unbounded += num_solve_by_status[dual_unbounded_as_int];
261 if (dimension.empty()) dimension = lp->DimensionString();
264 total_num_cut_propagations += lp->total_num_cut_propagations();
265 total_num_eq_propagations += lp->total_num_eq_propagations();
266 num_adjusts += lp->num_adjusts();
267 num_cut_overflows += lp->num_cut_overflows();
268 num_bad_cuts += lp->num_bad_cuts();
269 num_scaling_issues += lp->num_scaling_issues();
272 num_constraints += manager.num_constraints();
273 num_constraint_updates += manager.num_constraint_updates();
274 num_simplifications += manager.num_simplifications();
275 num_merged_constraints += manager.num_merged_constraints();
276 num_shortened_constraints += manager.num_shortened_constraints();
277 num_split_constraints += manager.num_split_constraints();
278 num_coeff_strengthening += manager.num_coeff_strenghtening();
279 num_cuts += manager.num_cuts();
280 num_add_cut_calls += manager.num_add_cut_calls();
282 for (
const auto& [cut_name, num] : manager.type_to_num_cuts()) {
283 type_to_num_cuts[cut_name] += num;
286 if (num_compo == 0)
return;
293 if (!dimension.empty()) {
294 lp_dim_table_.push_back({
FormatName(name), dimension});
297 if (!type_to_num_cuts.empty()) {
298 lp_cut_table_.push_back({std::string(name), std::move(type_to_num_cuts)});
301 lp_debug_table_.push_back(
319 int64_t num_fully_solved_calls,
321 int64_t num_improving_calls,
323 double deterministic_limit) {
324 absl::MutexLock mutex_lock(mutex_);
325 const double fully_solved_proportion =
326 static_cast<double>(num_fully_solved_calls) /
327 static_cast<double>(std::max(int64_t{1}, num_calls));
328 lns_table_.push_back(
329 {
FormatName(name), absl::StrCat(num_improving_calls,
"/", num_calls),
330 absl::StrFormat(
"%2.0f%%", 100 * fully_solved_proportion),
331 absl::StrFormat(
"%0.2e", difficulty),
332 absl::StrFormat(
"%0.2f", deterministic_limit)});
354 absl::MutexLock mutex_lock(mutex_);
358 if (bool_var_table_.size() > 1) {
361 if (clauses_table_.size() > 1) {
364 if (vivify_table_.size() > 1) {
367 if (clauses_deletion_table_.size() > 1) {
373 if (lp_debug_table_.size() > 1) {
376 if (lp_manager_table_.size() > 1) {
382 if (!lp_cut_table_.empty()) {
384 absl::btree_map<std::string, int> lines;
385 for (
const auto& [_, map] : lp_cut_table_) {
386 for (
const auto& [type_name, _] : map) {
387 lines[type_name] = 0;
392 std::vector<std::vector<std::string>> table;
394 const int num_cols = lp_cut_table_.size() + 1;
395 table.push_back({
"Lp Cut"});
396 table[0].resize(num_cols,
"");
397 for (
const auto& [type_name, _] : lines) {
398 lines[type_name] = line_index++;
399 table.push_back({absl::StrCat(type_name,
":")});
400 table.back().resize(num_cols,
"-");
405 for (
const auto& [name, map] : lp_cut_table_) {
406 table[0][col_index] =
407 num_cols > 10 && name.size() > 6 ? name.substr(0, 6) : name;
408 for (
const auto& [type_name, count] : map) {