13 #ifndef QBPP_EXHAUSTIVE_SOLVER_HPP
14 #define QBPP_EXHAUSTIVE_SOLVER_HPP
16 #include <tbb/blocked_range.h>
17 #include <tbb/parallel_for.h>
19 #include <boost/circular_buffer.hpp>
20 #include <forward_list>
28 namespace exhaustive_solver {
73 std::string
str()
const {
75 std::ostringstream oss;
78 oss << count++ <<
":" << sol;
86 std::list<qbpp::Sol>::const_iterator
begin()
const {
90 std::list<qbpp::Sol>::const_iterator
end()
const {
115 static std::optional<energy_t> prev_energy = std::nullopt;
118 if (!prev_energy.has_value() ||
119 sol_holder.
get_energy() < prev_energy.value()) {
121 std::cout <<
"TTS = " << std::fixed << std::setprecision(3)
122 << std::setfill(
'0') << sol_holder.
get_tts()
123 <<
"s Energy = " << sol_holder.
get_energy() << std::endl;
164 std::vector<std::pair<vindex_t, vindex_t>> degree_var;
165 degree_var.resize(quad_model.
var_count());
167 degree_var[i] = std::make_pair(quad_model.
get_degree(i), i);
169 std::sort(degree_var.begin(), degree_var.end(), std::greater<>());
170 std::vector<vindex_t> var_order;
171 var_order.resize(quad_model.
var_count());
173 var_order[i] = degree_var[i].second;
232 :
Sol(search_algorithm.get_quad_model()),
248 throw std::out_of_range(
249 THROW_MESSAGE(
"Sol: flip_index (", flip_index,
") out of range"));
254 delta_[k] += (2 *
get(flip_index) - 1) * (2 *
get(k) - 1) * coeff;
264 if (index >= 1)
search(index - 1);
267 if (index >= 1)
search(index - 1);
279 search_algorithm.
search();
306 sol_delta.
flip(index);
312 const int parallel_param = 8;
327 tbb::blocked_range<size_t>(0,
sol_deltas.size()),
328 [&](
const tbb::blocked_range<size_t> &range) {
329 for (size_t i = range.begin(); i < range.end(); ++i) {
330 register_new_sol(sol_deltas[i]);
331 sol_deltas[i].search(var_count() - (parallel_param + 1));
336 inline void SearchAlgorithm::search_optimal_solutions() {
337 is_optimal_solutions_ =
true;
339 all_solutions_.sort();
342 inline void SearchAlgorithm::search_all_solutions() {
343 is_all_solutions_ =
true;
345 all_solutions_.sort();
energy_t get_constant() const
vindex_t var_count() const
size_t term_count(vindex_t deg) const
const std::vector< std::vector< std::pair< vindex_t, coeff_t > > > & get_quadratic() const
const std::vector< coeff_t > & get_linear() const
const std::vector< vindex_t > & get_degree() const
energy_t get_energy() const
virtual std::optional< double > set_if_better(const qbpp::Sol &new_sol, const std::string &solver="")
const Sol & get_sol() const
const QuadModel quad_model_
energy_t get_energy() const
Sol & operator=(const Sol &sol)
std::optional< energy_t > energy_
energy_t comp_energy() const
impl::BitVector bit_vector_
var_val_t get(vindex_t index) const
vindex_t var_count() const
Sol search_optimal_solutions()
const QuadModel & get_quad_model() const
ExhaustiveSolver(const QuadModel &quad_model)
void enable_default_callback(bool enable=true)
Sol search_all_solutions()
virtual ~ExhaustiveSolver()=default
const QuadModel quad_model_
std::mutex callback_mutex_
bool enable_default_callback_
virtual void callback(const SolHolder &sol_holder) const
std::list< qbpp::Sol > all_solutions_
qbpp::SolHolder & get_sol_holder()
std::list< qbpp::Sol > & get_all_solutions()
const std::vector< vindex_t > & get_var_order() const
vindex_t var_count() const
std::vector< vindex_t > init_var_order(const QuadModel &quad_model)
bool is_optimal_solutions_
const std::vector< vindex_t > var_order_
const QuadModel & quad_model_
void search_all_solutions()
void register_new_sol(const qbpp::Sol &sol)
std::mutex all_solutions_mutex_
const QuadModel & get_quad_model() const
SearchAlgorithm(const ExhaustiveSolver &exhaustive_solver)
qbpp::SolHolder sol_holder_
void gen_sol_deltas(SolDelta &sol_delta, vindex_t index)
std::vector< SolDelta > sol_deltas
void search_optimal_solutions()
const ExhaustiveSolver & exhaustive_solver_
std::vector< energy_t > delta_
SearchAlgorithm & search_algorithm_
SolDelta(const SolDelta &)=default
vindex_t var_count() const
const std::vector< vindex_t > & var_order_
SolDelta(SearchAlgorithm &search_algorithm)
void search(vindex_t index)
void flip(vindex_t index) override
std::list< qbpp::Sol >::const_iterator begin() const
bool is_optimal_solutions_
std::list< qbpp::Sol > all_solutions_
std::list< qbpp::Sol > & get_all_solutions()
void set_all_solutions(std::list< qbpp::Sol > &&all_solutions)
Sol & operator=(Sol &&)=default
Sol & operator=(const Sol &)=default
qbpp::Sol get_sol() const
Sol(const QuadModel &quad_model)
std::list< qbpp::Sol >::const_iterator end() const
void optimal_solution_mode()
void flip(vindex_t index)
std::ostream & operator<<(std::ostream &os, const Sol &sol)
Generates a QUBO Expression for the Graph Coloring Problem using QUBO++ library.
QUBO++, a C++ library for generating expressions for binary and spin variables.
#define THROW_MESSAGE(...)