Google OR-Tools: ortools/util/tuple_set.h Source File
33#ifndef ORTOOLS_UTIL_TUPLE_SET_H_
34#define ORTOOLS_UTIL_TUPLE_SET_H_
40#include "absl/container/flat_hash_map.h"
41#include "absl/container/flat_hash_set.h"
62 int Insert(const std::vector<int>& tuple);
63 int Insert(const std::vector<int64_t>& tuple);
65 int Insert2(int64_t v0, int64_t v1);
66 int Insert3(int64_t v0, int64_t v1, int64_t v2);
67 int Insert4(int64_t v0, int64_t v1, int64_t v2, int64_t v3);
69 void InsertAll(const std::vector<std::vector<int64_t> >& tuples);
70 void InsertAll(const std::vector<std::vector<int> >& tuples);
73 bool Contains(const std::vector<int>& tuple) const;
74 bool Contains(const std::vector<int64_t>& tuple) const;
81 int64_t Value(int tuple_index, int pos_in_tuple) const;
83 int Arity() const;
85 const int64_t* RawData() const;
103 bool RemovedSharedOwner();
106 int Insert(const std::vector<T>& tuple);
108 bool Contains(const std::vector<T>& candidate) const;
110 int64_t Fingerprint(const std::vector<T>& tuple) const;
112 int64_t Value(int index, int pos) const;
113 int Arity() const;
114 const int64_t* RawData() const;
121 std::vector<int64_t> flat_tuples_;
125 absl::flat_hash_map<int64_t, std::vector<int> > tuple_fprint_to_index_;
132 IndexData(int i, IntTupleSet::Data* const d) : index(i), data(d) {}
133 static bool Compare(const IndexData& a, const IndexData& b);
139 IndexValue(int i, int64_t v) : index(i), value(v) {}
140 static bool Compare(const IndexValue& a, const IndexValue& b);
147inline IntTupleSet::Data::Data(int arity) : arity_(arity), num_owners_(0) {}
149inline IntTupleSet::Data::Data(const Data& data)
152 flat_tuples_(data.flat_tuples_),
153 tuple_fprint_to_index_(data.tuple_fprint_to_index_) {}
155inline IntTupleSet::Data::~Data() {}
157inline void IntTupleSet::Data::AddSharedOwner() { num_owners_++; }
159inline bool IntTupleSet::Data::RemovedSharedOwner() {
160 return (--num_owners_ == 0);
163inline IntTupleSet::Data* IntTupleSet::Data::CopyIfShared() {
165 Data* const new_data = new Data(*this);
167 new_data->AddSharedOwner();
174int IntTupleSet::Data::Insert(const std::vector<T>& tuple) {
175 DCHECK(arity_ == 0 || flat_tuples_.size() % arity_ == 0);
176 CHECK_EQ(arity_, tuple.size());
177 DCHECK_EQ(1, num_owners_);
180 const int offset = flat_tuples_.size();
181 flat_tuples_.resize(offset + arity_);
183 for (int i = 0; i < arity_; ++i) {
184 flat_tuples_[offset + i] = tuple[i];
186 const int64_t fingerprint = Fingerprint(tuple);
187 tuple_fprint_to_index_[fingerprint].push_back(index);
195bool IntTupleSet::Data::Contains(const std::vector<T>& candidate) const {
196 if (candidate.size() != arity_) {
199 const int64_t fingerprint = Fingerprint(candidate);
200 if (tuple_fprint_to_index_.contains(fingerprint)) {
201 const std::vector<int>& indices = tuple_fprint_to_index_.at(fingerprint);
202 for (int i = 0; i < indices.size(); ++i) {
203 const int tuple_index = indices[i];
204 for (int j = 0; j < arity_; ++j) {
205 if (candidate[j] != flat_tuples_[tuple_index * arity_ + j]) {
216int64_t IntTupleSet::Data::Fingerprint(const std::vector<T>& tuple) const {
223 uint64_t x = tuple[0];
224 uint64_t y = uint64_t{0xe08c1d668b756f82};
226 mix(x, y, z);
230 uint64_t x = tuple[0];
231 uint64_t y = uint64_t{0xe08c1d668b756f82};
232 for (int i = 1; i < tuple.size(); ++i) {
233 uint64_t z = tuple[i];
234 mix(x, y, z);
235 x = z;
237 return x;
242inline int IntTupleSet::Data::NumTuples() const {
243 return tuple_fprint_to_index_.size();
246inline int64_t IntTupleSet::Data::Value(int index, int pos) const {
248 DCHECK_LT(index, flat_tuples_.size() / arity_);
251 return flat_tuples_[index * arity_ + pos];
254inline int IntTupleSet::Data::Arity() const { return arity_; }
256inline const int64_t* IntTupleSet::Data::RawData() const {
257 return flat_tuples_.data();
260inline void IntTupleSet::Data::Clear() {
262 tuple_fprint_to_index_.clear();
297 std::vector<int64_t> tuple(2);
300 return Insert(tuple);
304 std::vector<int64_t> tuple(3);
308 return Insert(tuple);
313 std::vector<int64_t> tuple(4);
318 return Insert(tuple);
330 const std::vector<std::vector<int> >& tuples) {
331 data_ = data_->CopyIfShared();
338 const std::vector<std::vector<int64_t> >& tuples) {
339 data_ = data_->CopyIfShared();
356 if (col < 0 || col >= data_->Arity()) {
359 absl::flat_hash_set<int64_t> values;
360 for (int i = 0; i < data_->NumTuples(); ++i) {
366inline bool IntTupleSet::IndexValue::Compare(const IndexValue& a,
368 return a.value < b.value || (a.value == b.value && a.index < b.index);
372 std::vector<IndexValue> keys;
373 keys.reserve(data_->NumTuples());
374 for (int index = 0; index < data_->NumTuples(); ++index) {
375 keys.push_back(IndexValue(index, data_->Value(index, col)));
377 std::sort(keys.begin(), keys.end(), IntTupleSet::IndexValue::Compare);
378 const int arity = data_->Arity();
380 for (int i = 0; i < keys.size(); ++i) {
381 const int64_t* tuple_ptr = data_->RawData() + keys[i].index * arity;
382 sorted.Insert(std::vector<int64_t>(tuple_ptr, tuple_ptr + arity));
387inline bool IntTupleSet::IndexData::Compare(const IndexData& a,
389 const IntTupleSet::Data* const data = a.data;
390 const int arity = data->Arity();
391 for (int i = 0; i < arity; ++i) {
392 const int64_t value1 = data->Value(a.index, i);
393 const int64_t value2 = data->Value(b.index, i);
405 std::vector<IndexData> keys;
406 keys.reserve(data_->NumTuples());
407 for (int index = 0; index < data_->NumTuples(); ++index) {
408 keys.push_back(IndexData(index, data_));
410 std::sort(keys.begin(), keys.end(), IntTupleSet::IndexData::Compare);
411 const int arity = data_->Arity();
413 for (int i = 0; i < keys.size(); ++i) {
414 std::vector<int64_t> tuple(arity);
415 const int64_t* tuple_ptr = data_->RawData() + keys[i].index * arity;
416 sorted.Insert(std::vector<int64_t>(tuple_ptr, tuple_ptr + arity));
int Insert3(int64_t v0, int64_t v1, int64_t v2)
Definition tuple_set.h:303
int Insert4(int64_t v0, int64_t v1, int64_t v2, int64_t v3)
Definition tuple_set.h:311
IntTupleSet(int arity)
Definition tuple_set.h:265
int64_t Value(int tuple_index, int pos_in_tuple) const
Definition tuple_set.h:347
int NumTuples() const
Definition tuple_set.h:345
void Clear()
Definition tuple_set.h:281
bool Contains(const std::vector< int > &tuple) const
Definition tuple_set.h:321
int Insert(const std::vector< int > &tuple)
Definition tuple_set.h:286
int Insert2(int64_t v0, int64_t v1)
Definition tuple_set.h:296
int NumDifferentValuesInColumn(int col) const
Definition tuple_set.h:355
IntTupleSet SortedLexicographically() const
Definition tuple_set.h:404
int Arity() const
Definition tuple_set.h:351
void InsertAll(const std::vector< std::vector< int64_t > > &tuples)
Definition tuple_set.h:337
~IntTupleSet()
Definition tuple_set.h:274
IntTupleSet SortedByColumn(int col) const
Definition tuple_set.h:371
const int64_t * RawData() const
Definition tuple_set.h:353
static void mix(uint64_t &a, uint64_t &b, uint64_t &c)