carl  24.04
Computer ARithmetic Library
exact.cpp
Go to the documentation of this file.
1 #include "exact.h"
2 
3 #include "remove_duplicates.h"
4 #include "select_essential.h"
5 
8 
9 #include <optional>
10 
12 
13 std::optional<Bitset> exact_of_size(const SetCover& sc, const Bitset& uncovered, const std::vector<std::size_t>& id_map, std::size_t size) {
14  std::vector<bool> selection(id_map.size() - size, false);
15  selection.resize(id_map.size(), true);
16 
17  do {
18  Bitset covered;
19  for (std::size_t id = 0; id < selection.size(); ++id) {
20  if (selection[id]) {
21  covered |= sc.get_set(id_map[id]);
22  }
23  }
24  if (uncovered.is_subset_of(covered)) {
25  Bitset result;
26  for (std::size_t id = 0; id < selection.size(); ++id) {
27  result.set(id_map[id], selection[id]);
28  }
29  return result;
30  }
31  } while (std::next_permutation(selection.begin(), selection.end()));
32  return std::nullopt;
33 }
34 
36  Bitset pre;
38  CARL_LOG_DEBUG("carl.covering", "Removed duplicates: " << pre << std::endl << sc);
40  CARL_LOG_DEBUG("carl.covering", "Selected essential: " << pre << std::endl << sc);
41 
42  const auto uncovered = sc.get_uncovered();
43  if (uncovered.none()) {
44  CARL_LOG_DEBUG("carl.covering", "trivially solved by preprocessing");
45  return pre;
46  }
47  CARL_LOG_DEBUG("carl.covering", "Remaining: " << uncovered);
48 
49  // Maps local ids to ids in sc. We only consider active sets for local ids.
50  std::vector<std::size_t> id_map;
51  for (std::size_t sid = 0; sid < sc.set_count(); ++sid) {
52  if (sc.get_set(sid).any()) id_map.emplace_back(sid);
53  }
54 
55  for (std::size_t size = 0; size < sc.active_set_count(); ++size) {
56  auto res = exact_of_size(sc, uncovered, id_map, size);
57  if (res) {
58  for (auto bit: *res) {
59  sc.select_set(bit);
60  }
61  CARL_LOG_DEBUG("carl.covering", "Got exact covering of size " << size << " -> " << *res);
62  return pre | *res;
63  }
64  }
65 
66  CARL_LOG_ERROR("carl.covering", "Did not find an exact set cover.")
67  return Bitset();
68 }
69 
70 }
A small wrapper that configures logging for carl.
#define CARL_LOG_ERROR(channel, msg)
Definition: carl-logging.h:40
#define CARL_LOG_DEBUG(channel, msg)
Definition: carl-logging.h:43
Bitset exact(SetCover &sc)
Exact "heuristic": Computes a minimum set cover.
Definition: exact.cpp:35
std::optional< Bitset > exact_of_size(const SetCover &sc, const Bitset &uncovered, const std::vector< std::size_t > &id_map, std::size_t size)
Definition: exact.cpp:13
Bitset remove_duplicates(SetCover &sc)
Preprocessing heuristic: Compresses the matrix by removing duplicate columns.
Bitset select_essential(SetCover &sc)
Preprocessing heuristic: Selects essential sets which are the only once covering some element.
This class is a simple wrapper around boost::dynamic_bitset.
Definition: Bitset.h:20
auto is_subset_of(const Bitset &rhs) const
Checks wether the bits set is a subset of the bits set in rhs.
Definition: Bitset.h:192
Bitset & set(std::size_t n, bool value=true)
Sets the given bit to a value, true by default.
Definition: Bitset.h:140
Represents a set cover problem.
Definition: SetCover.h:15
std::size_t active_set_count() const
Returns the number of active sets (that still cover uncovered elements).
Definition: SetCover.cpp:44
const auto & get_set(std::size_t set) const
Returns the given set.
Definition: SetCover.h:27
void select_set(std::size_t s)
Selects the given set and purges the covered elements from all other sets.
Definition: SetCover.cpp:86
Bitset get_uncovered() const
Returns the uncovered elements.
Definition: SetCover.cpp:78
std::size_t set_count() const
Returns the number of sets.
Definition: SetCover.cpp:40