Outputs relevant information every few seconds. The output contains information about the (penalised) cost and feasibility of the current, candidate, and best solutions, as well as the search duration.
(self, stats: Statistics)
| 59 | self._best_cost = float("inf") |
| 60 | |
| 61 | def iteration(self, stats: Statistics): |
| 62 | """ |
| 63 | Outputs relevant information every few seconds. The output contains |
| 64 | information about the (penalised) cost and feasibility of the current, |
| 65 | candidate, and best solutions, as well as the search duration. |
| 66 | """ |
| 67 | curr_time = perf_counter() |
| 68 | interval = curr_time - self._last_print_time |
| 69 | should_print = ( |
| 70 | self._print |
| 71 | and stats.is_collecting() |
| 72 | and interval >= self._display_interval |
| 73 | ) |
| 74 | |
| 75 | if not should_print: |
| 76 | return |
| 77 | |
| 78 | datum = stats.data[-1] |
| 79 | new_best = datum.best_feas and datum.best_cost < self._best_cost |
| 80 | msg = _ITERATION.format( |
| 81 | special="H" if new_best else " ", |
| 82 | iters=stats.num_iterations, |
| 83 | elapsed=round(sum(stats.runtimes)), |
| 84 | curr=datum.current_cost, |
| 85 | curr_feas="Y" if datum.current_feas else "N", |
| 86 | cand=datum.candidate_cost, |
| 87 | cand_feas="Y" if datum.candidate_feas else "N", |
| 88 | best=datum.best_cost, |
| 89 | best_feas="Y" if datum.best_feas else "N", |
| 90 | ) |
| 91 | |
| 92 | logger.info(msg) |
| 93 | |
| 94 | self._last_print_time = curr_time |
| 95 | if new_best: |
| 96 | self._best_cost = datum.best_cost |
| 97 | |
| 98 | def start(self, data: ProblemData): |
| 99 | """ |