| 1713 | } |
| 1714 | |
| 1715 | void HighsMipSolverData::printDisplayLine(const int solution_source) { |
| 1716 | // MIP logging method |
| 1717 | // |
| 1718 | // Note that if the original problem is a maximization, the cost |
| 1719 | // coefficients are negated so that the MIP solver only solves a |
| 1720 | // minimization. Hence, in preparing to print the display line, the |
| 1721 | // dual bound (lb) is always less than the primal bound (ub). When |
| 1722 | // printed, the sense of the optimization is applied so that the |
| 1723 | // values printed correspond to the original objective. |
| 1724 | |
| 1725 | // No point in computing all the logging values if logging is off |
| 1726 | bool output_flag = *mipsolver.options_mip_->log_options.output_flag; |
| 1727 | if (!output_flag) return; |
| 1728 | |
| 1729 | bool timeless_log = mipsolver.options_mip_->timeless_log; |
| 1730 | disptime = timeless_log ? disptime + 1 : mipsolver.timer_.read(); |
| 1731 | if (solution_source == kSolutionSourceNone && |
| 1732 | disptime - last_disptime < |
| 1733 | mipsolver.options_mip_->mip_min_logging_interval) |
| 1734 | return; |
| 1735 | last_disptime = disptime; |
| 1736 | std::string time_string = |
| 1737 | timeless_log ? "" : highsFormatToString(" %7.1fs", disptime); |
| 1738 | |
| 1739 | if (num_disp_lines % 20 == 0) { |
| 1740 | if (num_disp_lines == 0) printSolutionSourceKey(); |
| 1741 | std::string work_string0 = timeless_log ? " Work" : " Work "; |
| 1742 | std::string work_string1 = timeless_log ? "LpIters" : "LpIters Time"; |
| 1743 | highsLogUser(mipsolver.options_mip_->log_options, HighsLogType::kInfo, |
| 1744 | // clang-format off |
| 1745 | "\n Nodes | B&B Tree | Objective Bounds | Dynamic Constraints | %s\n" |
| 1746 | "Src Proc. InQueue | Leaves Expl. | BestBound BestSol Gap | Cuts InLp Confl. | %s\n\n", |
| 1747 | // clang-format on |
| 1748 | work_string0.c_str(), work_string1.c_str()); |
| 1749 | |
| 1750 | //" %7s | %10s | %10s | %10s | %10s | %-15s | %-15s | %7s | %7s " |
| 1751 | //"| %8s | %8s\n", |
| 1752 | //"time", "open nodes", "nodes", "leaves", "lpiters", "dual bound", |
| 1753 | //"primal bound", "cutpool", "confl.", "gap", "explored"); |
| 1754 | } |
| 1755 | |
| 1756 | ++num_disp_lines; |
| 1757 | |
| 1758 | auto print_nodes = convertToPrintString(num_nodes); |
| 1759 | auto queue_nodes = convertToPrintString(nodequeue.numActiveNodes()); |
| 1760 | auto print_leaves = convertToPrintString(num_leaves - num_leaves_before_run); |
| 1761 | |
| 1762 | double explored = 100 * double(pruned_treeweight); |
| 1763 | |
| 1764 | double lb; |
| 1765 | double ub; |
| 1766 | double gap = limitsToGap(lower_bound, upper_bound, lb, ub); |
| 1767 | gap *= 1e2; |
| 1768 | if (mipsolver.options_mip_->objective_bound < ub) |
| 1769 | ub = mipsolver.options_mip_->objective_bound; |
| 1770 | |
| 1771 | auto print_lp_iters = convertToPrintString(total_lp_iterations); |
| 1772 | HighsInt dynamic_constraints_in_lp = |
no test coverage detected