OR-Tools  8.1
bitset.h
Go to the documentation of this file.
1 // Copyright 2010-2018 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 // Various utility functions on bitsets.
15 
16 #ifndef OR_TOOLS_UTIL_BITSET_H_
17 #define OR_TOOLS_UTIL_BITSET_H_
18 
19 #include <string.h>
20 
21 #include <algorithm>
22 #include <vector>
23 
25 #include "ortools/base/logging.h"
26 #include "ortools/base/macros.h"
27 
28 namespace operations_research {
29 
30 // Basic bit operations
31 
32 // Useful constants: word and double word will all bits set.
33 static const uint64 kAllBits64 = GG_ULONGLONG(0xFFFFFFFFFFFFFFFF);
34 static const uint64 kAllBitsButLsb64 = GG_ULONGLONG(0xFFFFFFFFFFFFFFFE);
35 static const uint32 kAllBits32 = 0xFFFFFFFFU;
36 
37 // Returns a word with only bit pos set.
38 inline uint64 OneBit64(int pos) { return GG_ULONGLONG(1) << pos; }
39 inline uint32 OneBit32(int pos) { return 1U << pos; }
40 
41 // Returns the number of bits set in n.
43  const uint64 m1 = GG_ULONGLONG(0x5555555555555555);
44  const uint64 m2 = GG_ULONGLONG(0x3333333333333333);
45  const uint64 m4 = GG_ULONGLONG(0x0F0F0F0F0F0F0F0F);
46  const uint64 h01 = GG_ULONGLONG(0x0101010101010101);
47  n -= (n >> 1) & m1;
48  n = (n & m2) + ((n >> 2) & m2);
49  n = (n + (n >> 4)) & m4;
50  n = (n * h01) >> 56;
51  return n;
52 }
54  n -= (n >> 1) & 0x55555555UL;
55  n = (n & 0x33333333) + ((n >> 2) & 0x33333333UL);
56  n = (n + (n >> 4)) & 0x0F0F0F0FUL;
57  n = n + (n >> 8);
58  n = n + (n >> 16);
59  return n & 0x0000003FUL;
60 }
61 
62 // Returns a word with only the least significant bit of n set.
63 inline uint64 LeastSignificantBitWord64(uint64 n) { return n & ~(n - 1); }
64 inline uint32 LeastSignificantBitWord32(uint32 n) { return n & ~(n - 1); }
65 
66 // Returns the least significant bit position in n.
67 // Discussion around lsb computation:
68 // De Bruijn is almost as fast as the bsr/bsf-instruction-based intrinsics.
69 // Both are always much faster than the Default algorithm.
70 #define USE_DEBRUIJN true // if true, use de Bruijn bit forward scanner.
71 #if defined(__GNUC__) || defined(__llvm__)
72 #define USE_FAST_LEAST_SIGNIFICANT_BIT true // if true, use fast lsb.
73 #endif
74 
75 #if defined(USE_FAST_LEAST_SIGNIFICANT_BIT)
76 inline int LeastSignificantBitPosition64Fast(uint64 n) {
77  return n == 0 ? 0 : __builtin_ctzll(n);
78 }
79 #endif
80 
82  static const uint64 kSeq = GG_ULONGLONG(0x0218a392dd5fb34f);
83  static const int kTab[64] = {
84  // initialized by 'kTab[(kSeq << i) >> 58] = i
85  0, 1, 2, 7, 3, 13, 8, 19, 4, 25, 14, 28, 9, 52, 20, 58,
86  5, 17, 26, 56, 15, 38, 29, 40, 10, 49, 53, 31, 21, 34, 59, 42,
87  63, 6, 12, 18, 24, 27, 51, 57, 16, 55, 37, 39, 48, 30, 33, 41,
88  62, 11, 23, 50, 54, 36, 47, 32, 61, 22, 35, 46, 60, 45, 44, 43,
89  };
90  return kTab[((n & (~n + 1)) * kSeq) >> 58];
91 }
92 
94  if (n == 0) return 0;
95  int pos = 63;
96  if (n & 0x00000000FFFFFFFFLL) {
97  pos -= 32;
98  } else {
99  n >>= 32;
100  }
101  if (n & 0x000000000000FFFFLL) {
102  pos -= 16;
103  } else {
104  n >>= 16;
105  }
106  if (n & 0x00000000000000FFLL) {
107  pos -= 8;
108  } else {
109  n >>= 8;
110  }
111  if (n & 0x000000000000000FLL) {
112  pos -= 4;
113  } else {
114  n >>= 4;
115  }
116  if (n & 0x0000000000000003LL) {
117  pos -= 2;
118  } else {
119  n >>= 2;
120  }
121  if (n & 0x0000000000000001LL) {
122  pos -= 1;
123  }
124  return pos;
125 }
126 
128  DCHECK_NE(n, 0);
129 #ifdef USE_FAST_LEAST_SIGNIFICANT_BIT
130  return LeastSignificantBitPosition64Fast(n);
131 #elif defined(USE_DEBRUIJN)
133 #else
135 #endif
136 }
137 
138 #if defined(USE_FAST_LEAST_SIGNIFICANT_BIT)
139 inline int LeastSignificantBitPosition32Fast(uint32 n) {
140  return n == 0 ? 0 : __builtin_ctzl(n);
141 }
142 #endif
143 
145  static const uint32 kSeq = 0x077CB531U; // de Bruijn sequence
146  static const int kTab[32] = {// initialized by 'kTab[(kSeq << i) >> 27] = i
147  0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20,
148  15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19,
149  16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
150  return kTab[((n & (~n + 1)) * kSeq) >> 27];
151 }
152 
154  if (n == 0) return 0;
155  int pos = 31;
156  if (n & 0x0000FFFFL) {
157  pos -= 16;
158  } else {
159  n >>= 16;
160  }
161  if (n & 0x000000FFL) {
162  pos -= 8;
163  } else {
164  n >>= 8;
165  }
166  if (n & 0x0000000FL) {
167  pos -= 4;
168  } else {
169  n >>= 4;
170  }
171  if (n & 0x00000003L) {
172  pos -= 2;
173  } else {
174  n >>= 2;
175  }
176  if (n & 0x00000001L) {
177  pos -= 1;
178  }
179  return pos;
180 }
181 
183  DCHECK_NE(n, 0);
184 #ifdef USE_FAST_LEAST_SIGNIFICANT_BIT
185  return LeastSignificantBitPosition32Fast(n);
186 #elif defined(USE_DEBRUIJN)
188 #else
190 #endif
191 }
192 
193 // Returns the most significant bit position in n.
194 #if USE_FAST_LEAST_SIGNIFICANT_BIT
195 inline int MostSignificantBitPosition64Fast(uint64 n) {
196  // __builtin_clzll(1) should always return 63. There is no penalty in
197  // using offset, and the code looks more like its uint32 counterpart.
198  const int offset = __builtin_clzll(1);
199  return n == 0 ? 0 : (offset - __builtin_clzll(n));
200 }
201 #endif
202 
204  int b = 0;
205  if (0 != (n & (kAllBits64 << (1 << 5)))) {
206  b |= (1 << 5);
207  n >>= (1 << 5);
208  }
209  if (0 != (n & (kAllBits64 << (1 << 4)))) {
210  b |= (1 << 4);
211  n >>= (1 << 4);
212  }
213  if (0 != (n & (kAllBits64 << (1 << 3)))) {
214  b |= (1 << 3);
215  n >>= (1 << 3);
216  }
217  if (0 != (n & (kAllBits64 << (1 << 2)))) {
218  b |= (1 << 2);
219  n >>= (1 << 2);
220  }
221  if (0 != (n & (kAllBits64 << (1 << 1)))) {
222  b |= (1 << 1);
223  n >>= (1 << 1);
224  }
225  if (0 != (n & (kAllBits64 << (1 << 0)))) {
226  b |= (1 << 0);
227  }
228  return b;
229 }
230 
232 #ifdef USE_FAST_LEAST_SIGNIFICANT_BIT
233  return MostSignificantBitPosition64Fast(n);
234 #else
236 #endif
237 }
238 
239 #if USE_FAST_LEAST_SIGNIFICANT_BIT
240 inline int MostSignificantBitPosition32Fast(uint32 n) {
241  // The constant here depends on whether we are on a 32-bit or 64-bit machine.
242  // __builtin_clzl(1) returns 63 on a 64-bit machine and 31 on a 32-bit
243  // machine.
244  const int offset = __builtin_clzl(1);
245  return n == 0 ? 0 : (offset - __builtin_clzl(n));
246 }
247 #endif
248 
250  int b = 0;
251  if (0 != (n & (kAllBits32 << (1 << 4)))) {
252  b |= (1 << 4);
253  n >>= (1 << 4);
254  }
255  if (0 != (n & (kAllBits32 << (1 << 3)))) {
256  b |= (1 << 3);
257  n >>= (1 << 3);
258  }
259  if (0 != (n & (kAllBits32 << (1 << 2)))) {
260  b |= (1 << 2);
261  n >>= (1 << 2);
262  }
263  if (0 != (n & (kAllBits32 << (1 << 1)))) {
264  b |= (1 << 1);
265  n >>= (1 << 1);
266  }
267  if (0 != (n & (kAllBits32 << (1 << 0)))) {
268  b |= (1 << 0);
269  }
270  return b;
271 }
272 
274 #ifdef USE_FAST_LEAST_SIGNIFICANT_BIT
275  return MostSignificantBitPosition32Fast(n);
276 #else
278 #endif
279 }
280 
281 #undef USE_DEBRUIJN
282 #undef USE_FAST_LEAST_SIGNIFICANT_BIT
283 
284 // Returns a word with bits from s to e set.
286  DCHECK_LE(s, 63);
287  DCHECK_LE(e, 63);
288  DCHECK_LE(s, e);
289  return (kAllBits64 << s) ^ ((kAllBits64 - 1) << e);
290 }
291 
293  DCHECK_LE(s, 31);
294  DCHECK_LE(e, 31);
295  DCHECK_LE(s, e);
296  return (kAllBits32 << s) ^ ((kAllBits32 - 1) << e);
297 }
298 
299 // Returns a word with s least significant bits unset.
301  DCHECK_LE(s, 63);
302  return kAllBits64 << s;
303 }
304 
306  DCHECK_LE(s, 31);
307  return kAllBits32 << s;
308 }
309 
310 // Returns a word with the s most significant bits unset.
312  DCHECK_LE(s, 63);
313  return kAllBits64 >> (63 - s);
314 }
315 
317  DCHECK_LE(s, 31);
318  return kAllBits32 >> (31 - s);
319 }
320 
321 // ----- Bitset operators -----
322 // Bitset: array of uint32/uint64 words
323 
324 // Bit operators used to manipulates bitsets.
325 
326 // Returns the bit number in the word computed by BitOffsetXX,
327 // corresponding to the bit at position pos in the bitset.
328 // Note: '& 63' is faster than '% 64'
329 // TODO(user): rename BitPos and BitOffset to something more understandable.
330 inline uint32 BitPos64(uint64 pos) { return (pos & 63); }
331 inline uint32 BitPos32(uint32 pos) { return (pos & 31); }
332 
333 // Returns the word number corresponding to bit number pos.
334 inline uint64 BitOffset64(uint64 pos) { return (pos >> 6); }
335 inline uint32 BitOffset32(uint32 pos) { return (pos >> 5); }
336 
337 // Returns the number of words needed to store size bits.
338 inline uint64 BitLength64(uint64 size) { return ((size + 63) >> 6); }
339 inline uint32 BitLength32(uint32 size) { return ((size + 31) >> 5); }
340 
341 // Returns the bit number in the bitset of the first bit of word number v.
342 inline uint64 BitShift64(uint64 v) { return v << 6; }
343 inline uint32 BitShift32(uint32 v) { return v << 5; }
344 
345 // Returns true if the bit pos is set in bitset.
346 inline bool IsBitSet64(const uint64* const bitset, uint64 pos) {
347  return (bitset[BitOffset64(pos)] & OneBit64(BitPos64(pos)));
348 }
349 inline bool IsBitSet32(const uint32* const bitset, uint32 pos) {
350  return (bitset[BitOffset32(pos)] & OneBit32(BitPos32(pos)));
351 }
352 
353 // Sets the bit pos to true in bitset.
354 inline void SetBit64(uint64* const bitset, uint64 pos) {
355  bitset[BitOffset64(pos)] |= OneBit64(BitPos64(pos));
356 }
357 inline void SetBit32(uint32* const bitset, uint32 pos) {
358  bitset[BitOffset32(pos)] |= OneBit32(BitPos32(pos));
359 }
360 
361 // Sets the bit pos to false in bitset.
362 inline void ClearBit64(uint64* const bitset, uint64 pos) {
363  bitset[BitOffset64(pos)] &= ~OneBit64(BitPos64(pos));
364 }
365 inline void ClearBit32(uint32* const bitset, uint32 pos) {
366  bitset[BitOffset32(pos)] &= ~OneBit32(BitPos32(pos));
367 }
368 
369 // Returns the number of bits set in bitset between positions start and end.
370 uint64 BitCountRange64(const uint64* const bitset, uint64 start, uint64 end);
371 uint32 BitCountRange32(const uint32* const bitset, uint32 start, uint32 end);
372 
373 // Returns true if no bits are set in bitset between start and end.
374 bool IsEmptyRange64(const uint64* const bitset, uint64 start, uint64 end);
375 bool IsEmptyRange32(const uint32* const bitset, uint32 start, uint32 end);
376 
377 // Returns the first bit set in bitset between start and max_bit.
379  uint64 end);
380 int LeastSignificantBitPosition32(const uint32* const bitset, uint32 start,
381  uint32 end);
382 
383 // Returns the last bit set in bitset between min_bit and start.
384 int64 MostSignificantBitPosition64(const uint64* const bitset, uint64 start,
385  uint64 end);
386 int MostSignificantBitPosition32(const uint32* const bitset, uint32 start,
387  uint32 end);
388 
389 // Unsafe versions of the functions above where respectively end and start
390 // are supposed to be set.
392  uint64 start, uint64 end);
394  uint32 start, uint32 end);
395 
397  uint64 start, uint64 end);
399  uint32 start, uint32 end);
400 
401 // Returns a mask with the bits pos % 64 and (pos ^ 1) % 64 sets.
403  return GG_ULONGLONG(3) << (pos & 62);
404 }
405 
406 // This class is like an ITIVector<IndexType, bool> except that it provides a
407 // more efficient way to iterate over the positions set to true. It achieves
408 // this by caching the current uint64 bucket in the Iterator and using
409 // LeastSignificantBitPosition64() to iterate over the positions at 1 in this
410 // bucket.
411 template <typename IndexType = int64>
412 class Bitset64 {
413  public:
414  Bitset64() : size_(), data_(), end_(*this, /*at_end=*/true) {}
415  explicit Bitset64(IndexType size)
416  : size_(Value(size) > 0 ? size : IndexType(0)),
417  data_(BitLength64(Value(size_))),
418  end_(*this, /*at_end=*/true) {}
419 
420  // Returns how many bits this Bitset64 can hold.
421  IndexType size() const { return size_; }
422 
423  // Appends value at the end of the bitset.
424  void PushBack(bool value) {
425  ++size_;
426  data_.resize(BitLength64(Value(size_)), 0);
427  Set(size_ - 1, value);
428  }
429 
430  // Resizes the Bitset64 to the given number of bits. New bits are sets to 0.
431  void Resize(IndexType size) {
432  DCHECK_GE(Value(size), 0);
433  size_ = Value(size) > 0 ? size : IndexType(0);
434  data_.resize(BitLength64(Value(size_)), 0);
435  }
436 
437  // Changes the number of bits the Bitset64 can hold and set all of them to 0.
438  void ClearAndResize(IndexType size) {
439  DCHECK_GE(Value(size), 0);
440  size_ = Value(size) > 0 ? size : IndexType(0);
441 
442  // Memset is 4x faster than data_.assign() as of 19/03/2014.
443  // TODO(user): Ideally if a realloc happens, we don't need to copy the old
444  // data...
445  const size_t bit_length = static_cast<size_t>(BitLength64(Value(size_)));
446  const size_t to_clear = std::min(data_.size(), bit_length);
447  data_.resize(bit_length, 0);
448  memset(data_.data(), 0, to_clear * sizeof(int64));
449  }
450 
451  // Sets all bits to 0.
452  void ClearAll() { memset(data_.data(), 0, data_.size() * sizeof(int64)); }
453 
454  // Sets the bit at position i to 0.
455  void Clear(IndexType i) {
456  DCHECK_GE(Value(i), 0);
457  DCHECK_LT(Value(i), Value(size_));
458  data_[BitOffset64(Value(i))] &= ~OneBit64(BitPos64(Value(i)));
459  }
460 
461  // Sets bucket containing bit i to 0.
462  void ClearBucket(IndexType i) {
463  DCHECK_GE(Value(i), 0);
464  DCHECK_LT(Value(i), Value(size_));
465  data_[BitOffset64(Value(i))] = 0;
466  }
467 
468  // Clears the bits at position i and i ^ 1.
469  void ClearTwoBits(IndexType i) {
470  DCHECK_GE(Value(i), 0);
471  DCHECK_LT(Value(i), Value(size_));
472  data_[BitOffset64(Value(i))] &= ~TwoBitsFromPos64(Value(i));
473  }
474 
475  // Returns true if the bit at position i or the one at position i ^ 1 is set.
476  bool AreOneOfTwoBitsSet(IndexType i) const {
477  DCHECK_GE(Value(i), 0);
478  DCHECK_LT(Value(i), Value(size_));
479  return data_[BitOffset64(Value(i))] & TwoBitsFromPos64(Value(i));
480  }
481 
482  // Returns true if the bit at position i is set.
483  bool IsSet(IndexType i) const {
484  DCHECK_GE(Value(i), 0);
485  DCHECK_LT(Value(i), Value(size_));
486  return data_[BitOffset64(Value(i))] & OneBit64(BitPos64(Value(i)));
487  }
488 
489  // Same as IsSet().
490  bool operator[](IndexType i) const { return IsSet(i); }
491 
492  // Sets the bit at position i to 1.
493  void Set(IndexType i) {
494  DCHECK_GE(Value(i), 0);
495  DCHECK_LT(Value(i), size_);
496  data_[BitOffset64(Value(i))] |= OneBit64(BitPos64(Value(i)));
497  }
498 
499  // If value is true, sets the bit at position i to 1, sets it to 0 otherwise.
500  void Set(IndexType i, bool value) {
501  if (value) {
502  Set(i);
503  } else {
504  Clear(i);
505  }
506  }
507 
508  // Copies bucket containing bit i from "other" to "this".
509  void CopyBucket(const Bitset64<IndexType>& other, IndexType i) {
510  const uint64 offset = BitOffset64(Value(i));
511  data_[offset] = other.data_[offset];
512  }
513 
514  // Copies "other" to "this". The bitsets do not have to be of the same size.
515  // If "other" is smaller, high order bits are not changed. If "other" is
516  // larger, its high order bits are ignored. In any case "this" is not resized.
517  template <typename OtherIndexType>
519  const int64 min_size = std::min(data_.size(), other.data_.size());
520  if (min_size == 0) return;
521  const uint64 last_common_bucket = data_[min_size - 1];
522  memcpy(data_.data(), other.data_.data(), min_size * sizeof(uint64));
523  if (data_.size() >= other.data_.size()) {
524  const uint64 bitmask = kAllBitsButLsb64
525  << BitPos64(other.Value(other.size() - 1));
526  data_[min_size - 1] &= ~bitmask;
527  data_[min_size - 1] |= (bitmask & last_common_bucket);
528  }
529  }
530 
531  // Same as SetContentFromBitset where "this" and "other" have the same size.
532  template <typename OtherIndexType>
534  DCHECK_EQ(Value(size()), other.Value(other.size()));
535  memcpy(data_.data(), other.data_.data(), data_.size() * sizeof(uint64));
536  }
537 
538  // Sets "this" to be the intersection of "this" and "other". The
539  // bitsets do not have to be the same size. If other is smaller, all
540  // the higher order bits are assumed to be 0.
541  void Intersection(const Bitset64<IndexType>& other) {
542  const int min_size = std::min(data_.size(), other.data_.size());
543  for (int i = 0; i < min_size; ++i) {
544  data_[i] &= other.data_[i];
545  }
546  for (int i = min_size; i < data_.size(); ++i) {
547  data_[i] = 0;
548  }
549  }
550 
551  // Sets "this" to be the union of "this" and "other". The
552  // bitsets do not have to be the same size. If other is smaller, all
553  // the higher order bits are assumed to be 0.
554  void Union(const Bitset64<IndexType>& other) {
555  const int min_size = std::min(data_.size(), other.data_.size());
556  for (int i = 0; i < min_size; ++i) {
557  data_[i] |= other.data_[i];
558  }
559  }
560 
561  // Class to iterate over the bit positions at 1 of a Bitset64.
562  //
563  // IMPORTANT: Because the iterator "caches" the current uint64 bucket, this
564  // will probably not do what you want if Bitset64 is modified while iterating.
565  class Iterator {
566  public:
567  explicit Iterator(const Bitset64& data_)
568  : bitset_(data_), index_(0), base_index_(0), current_(0) {
569  if (bitset_.data_.empty()) {
570  index_ = -1;
571  } else {
572  current_ = bitset_.data_[0];
573  Next();
574  }
575  }
576 
577  // Returns true if the Iterator is at a valid position.
578  bool Ok() const { return index_ != -1; }
579 
580  // Returns the current position of the iterator.
581  IndexType Index() const {
582  DCHECK(Ok());
583  return IndexType(index_);
584  }
585 
586  // Moves the iterator the the next position at 1 of the Bitset64.
587  void Next() {
588  DCHECK(Ok());
589  if (current_ == 0) {
590  int bucket = BitOffset64(base_index_);
591  const int size = bitset_.data_.size();
592  do {
593  bucket++;
594  } while (bucket < size && bitset_.data_[bucket] == 0);
595  if (bucket == size) {
596  index_ = -1;
597  return;
598  }
599  current_ = bitset_.data_[bucket];
600  base_index_ = BitShift64(bucket);
601  }
602 
603  // Computes the index and clear the least significant bit of current_.
604  index_ = base_index_ + LeastSignificantBitPosition64(current_);
605  current_ &= current_ - 1;
606  }
607 
608  // STL version of the functions above to support range-based "for" loop.
609  Iterator(const Bitset64& data_, bool at_end)
610  : bitset_(data_), index_(0), base_index_(0), current_(0) {
611  if (at_end || bitset_.data_.empty()) {
612  index_ = -1;
613  } else {
614  current_ = bitset_.data_[0];
615  Next();
616  }
617  }
618  bool operator!=(const Iterator& other) const {
619  return index_ != other.index_;
620  }
621  IndexType operator*() const { return IndexType(index_); }
622  void operator++() { Next(); }
623 
624  private:
625  const Bitset64& bitset_;
626  int index_;
627  int base_index_;
628  uint64 current_;
629  };
630 
631  // Allows range-based "for" loop on the non-zero positions:
632  // for (const IndexType index : bitset) {}
633  // instead of:
634  // for (Bitset64<IndexType>::Iterator it(bitset); it.Ok(); it.Next()) {
635  // const IndexType index = it.Index();
636  Iterator begin() const { return Iterator(*this); }
637  Iterator end() const { return end_; }
638 
639  // Cryptic function!
640  // This is just an optimized version of a given piece of code and has probably
641  // little general use. Sets the bit at position i to the result of
642  // (other1[i] && use1) XOR (other2[i] && use2).
643  void SetBitFromOtherBitSets(IndexType i, const Bitset64<IndexType>& other1,
644  uint64 use1, const Bitset64<IndexType>& other2,
645  uint64 use2) {
646  DCHECK_EQ(data_.size(), other1.data_.size());
647  DCHECK_EQ(data_.size(), other2.data_.size());
648  DCHECK(use1 == 0 || use1 == 1);
649  DCHECK(use2 == 0 || use2 == 1);
650  const int bucket = BitOffset64(Value(i));
651  const int pos = BitPos64(Value(i));
652  data_[bucket] ^= ((1ull << pos) & data_[bucket]) ^
653  ((use1 << pos) & other1.data_[bucket]) ^
654  ((use2 << pos) & other2.data_[bucket]);
655  }
656 
657  // Returns a 0/1 string representing the bitset.
658  std::string DebugString() const {
659  std::string output;
660  for (IndexType i(0); i < size(); ++i) {
661  output += IsSet(i) ? "1" : "0";
662  }
663  return output;
664  }
665 
666  private:
667  // Returns the value of the index type.
668  // This function is specialized below to work with IntType and int64.
669  int64 Value(IndexType input) const;
670 
671  IndexType size_;
672  std::vector<uint64> data_;
673 
674  // It is faster to store the end() Iterator than to recompute it every time.
675  // Note that we cannot do the same for begin().
676  const Iterator end_;
677 
678  template <class OtherIndexType>
679  friend class Bitset64;
681 };
682 
683 // Specialized version of Bitset64 that allows to query the last bit set more
684 // efficiently.
685 class BitQueue64 {
686  public:
687  BitQueue64() : size_(), top_(-1), data_() {}
688  explicit BitQueue64(int size)
689  : size_(size), top_(-1), data_(BitLength64(size), 0) {}
690 
691  void IncreaseSize(int size) {
692  CHECK_GE(size, size_);
693  size_ = size;
694  data_.resize(BitLength64(size), 0);
695  }
696 
697  void ClearAndResize(int size) {
698  top_ = -1;
699  size_ = size;
700  data_.assign(BitLength64(size), 0);
701  }
702 
703  void Set(int i) {
704  DCHECK_GE(i, 0);
705  DCHECK_LT(i, size_);
706  top_ = std::max(top_, i);
707  data_[BitOffset64(i)] |= OneBit64(BitPos64(i));
708  }
709 
710  // Sets all the bits from 0 up to i-1 to 1.
711  void SetAllBefore(int i) {
712  DCHECK_GE(i, 0);
713  DCHECK_LT(i, size_);
714  top_ = std::max(top_, i - 1);
715  int bucket_index = static_cast<int>(BitOffset64(i));
716  data_[bucket_index] |= OneBit64(BitPos64(i)) - 1;
717  for (--bucket_index; bucket_index >= 0; --bucket_index) {
718  data_[bucket_index] = kAllBits64;
719  }
720  }
721 
722  // Returns the position of the highest bit set in O(1) or -1 if no bit is set.
723  int Top() const { return top_; }
724 
725  // Clears the Top() bit and recomputes the position of the next Top().
726  void ClearTop() {
727  DCHECK_NE(top_, -1);
728  int bucket_index = static_cast<int>(BitOffset64(top_));
729  uint64 bucket = data_[bucket_index] &= ~OneBit64(BitPos64(top_));
730  while (!bucket) {
731  if (bucket_index == 0) {
732  top_ = -1;
733  return;
734  }
735  bucket = data_[--bucket_index];
736  }
737 
738  // Note(user): I experimented with reversing the bit order in a bucket to
739  // use LeastSignificantBitPosition64() and it is only slightly faster at the
740  // cost of a lower Set() speed. So I prefered this version.
741  top_ = static_cast<int>(BitShift64(bucket_index) +
743  }
744 
745  private:
746  int size_;
747  int top_;
748  std::vector<uint64> data_;
749  DISALLOW_COPY_AND_ASSIGN(BitQueue64);
750 };
751 
752 // The specialization of Value() for IntType and int64.
753 template <typename IntType>
754 inline int64 Bitset64<IntType>::Value(IntType input) const {
755  DCHECK_GE(input.value(), 0);
756  return input.value();
757 }
758 template <>
759 inline int64 Bitset64<int64>::Value(int64 input) const {
760  DCHECK_GE(input, 0);
761  return input;
762 }
763 
764 // A simple utility class to set/unset integer in a range [0, size).
765 // This is optimized for sparsity.
766 template <typename IntegerType = int64>
768  public:
770  explicit SparseBitset(IntegerType size) : bitset_(size) {}
771  IntegerType size() const { return bitset_.size(); }
772  void SparseClearAll() {
773  for (const IntegerType i : to_clear_) bitset_.ClearBucket(i);
774  to_clear_.clear();
775  }
776  void ClearAll() {
777  bitset_.ClearAll();
778  to_clear_.clear();
779  }
780  void ClearAndResize(IntegerType size) {
781  // As of 19/03/2014, experiments show that this is a reasonable threshold.
782  const int kSparseThreshold = 300;
783  if (to_clear_.size() * kSparseThreshold < size) {
784  SparseClearAll();
785  bitset_.Resize(size);
786  } else {
787  bitset_.ClearAndResize(size);
788  to_clear_.clear();
789  }
790  }
791  void Resize(IntegerType size) {
792  if (size < bitset_.size()) {
793  int new_index = 0;
794  for (IntegerType index : to_clear_) {
795  if (index < size) {
796  to_clear_[new_index] = index;
797  ++new_index;
798  }
799  }
800  to_clear_.resize(new_index);
801  }
802  bitset_.Resize(size);
803  }
804  bool operator[](IntegerType index) const { return bitset_[index]; }
805  void Set(IntegerType index) {
806  if (!bitset_[index]) {
807  bitset_.Set(index);
808  to_clear_.push_back(index);
809  }
810  }
811  void Clear(IntegerType index) { bitset_.Clear(index); }
813  return to_clear_.size();
814  }
815  const std::vector<IntegerType>& PositionsSetAtLeastOnce() const {
816  return to_clear_;
817  }
818 
819  // Tells the class that all its bits are cleared, so it can reset to_clear_
820  // to the empty vector. Note that this call is "unsafe" since the fact that
821  // the class is actually all cleared is only checked in debug mode.
822  //
823  // This is useful to iterate on the "set" positions while clearing them for
824  // instance. This way, after the loop, a client can call this for efficiency.
825  void NotifyAllClear() {
826  if (DEBUG_MODE) {
827  for (IntegerType index : to_clear_) CHECK(!bitset_[index]);
828  }
829  to_clear_.clear();
830  }
831 
832  private:
833  Bitset64<IntegerType> bitset_;
834  std::vector<IntegerType> to_clear_;
836 };
837 
838 } // namespace operations_research
839 
840 #endif // OR_TOOLS_UTIL_BITSET_H_
operations_research::Bitset64::Iterator::Iterator
Iterator(const Bitset64 &data_)
Definition: bitset.h:567
operations_research::BitQueue64::Set
void Set(int i)
Definition: bitset.h:703
operations_research::MostSignificantBitPosition64Default
int MostSignificantBitPosition64Default(uint64 n)
Definition: bitset.h:203
operations_research::LeastSignificantBitWord64
uint64 LeastSignificantBitWord64(uint64 n)
Definition: bitset.h:63
operations_research::BitPos64
uint32 BitPos64(uint64 pos)
Definition: bitset.h:330
operations_research::kAllBits32
static const uint32 kAllBits32
Definition: bitset.h:35
min
int64 min
Definition: alldiff_cst.cc:138
integral_types.h
DCHECK_LT
#define DCHECK_LT(val1, val2)
Definition: base/logging.h:888
operations_research::Bitset64::IsSet
bool IsSet(IndexType i) const
Definition: bitset.h:483
operations_research::SparseBitset::size
IntegerType size() const
Definition: bitset.h:771
operations_research::Bitset64::Set
void Set(IndexType i, bool value)
Definition: bitset.h:500
max
int64 max
Definition: alldiff_cst.cc:139
operations_research::IntervalDown64
uint64 IntervalDown64(uint64 s)
Definition: bitset.h:311
operations_research::SparseBitset::ClearAndResize
void ClearAndResize(IntegerType size)
Definition: bitset.h:780
operations_research::SparseBitset::operator[]
bool operator[](IntegerType index) const
Definition: bitset.h:804
operations_research::Bitset64::Bitset64
Bitset64(IndexType size)
Definition: bitset.h:415
operations_research::IsEmptyRange64
bool IsEmptyRange64(const uint64 *const bitset, uint64 start, uint64 end)
operations_research::BitQueue64::BitQueue64
BitQueue64()
Definition: bitset.h:687
operations_research::OneBit32
uint32 OneBit32(int pos)
Definition: bitset.h:39
operations_research::MostSignificantBitPosition32
int MostSignificantBitPosition32(uint32 n)
Definition: bitset.h:273
operations_research::BitQueue64::BitQueue64
BitQueue64(int size)
Definition: bitset.h:688
operations_research::Bitset64::Iterator::Ok
bool Ok() const
Definition: bitset.h:578
operations_research::Bitset64::end
Iterator end() const
Definition: bitset.h:637
operations_research::IsBitSet32
bool IsBitSet32(const uint32 *const bitset, uint32 pos)
Definition: bitset.h:349
CHECK_GE
#define CHECK_GE(val1, val2)
Definition: base/logging.h:701
operations_research::LeastSignificantBitPosition64Default
int LeastSignificantBitPosition64Default(uint64 n)
Definition: bitset.h:93
operations_research::Bitset64::Iterator::operator++
void operator++()
Definition: bitset.h:622
GG_ULONGLONG
#define GG_ULONGLONG(x)
Definition: integral_types.h:47
operations_research::Bitset64::Resize
void Resize(IndexType size)
Definition: bitset.h:431
logging.h
operations_research::IsBitSet64
bool IsBitSet64(const uint64 *const bitset, uint64 pos)
Definition: bitset.h:346
operations_research::Bitset64::AreOneOfTwoBitsSet
bool AreOneOfTwoBitsSet(IndexType i) const
Definition: bitset.h:476
operations_research::IntervalUp64
uint64 IntervalUp64(uint64 s)
Definition: bitset.h:300
operations_research::kAllBitsButLsb64
static const uint64 kAllBitsButLsb64
Definition: bitset.h:34
operations_research::BitOffset64
uint64 BitOffset64(uint64 pos)
Definition: bitset.h:334
value
int64 value
Definition: demon_profiler.cc:43
operations_research::OneRange64
uint64 OneRange64(uint64 s, uint64 e)
Definition: bitset.h:285
macros.h
operations_research
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Definition: dense_doubly_linked_list.h:21
operations_research::Bitset64
Definition: bitset.h:412
operations_research::BitCountRange64
uint64 BitCountRange64(const uint64 *const bitset, uint64 start, uint64 end)
operations_research::Bitset64::Union
void Union(const Bitset64< IndexType > &other)
Definition: bitset.h:554
operations_research::Bitset64::operator[]
bool operator[](IndexType i) const
Definition: bitset.h:490
operations_research::Bitset64::size
IndexType size() const
Definition: bitset.h:421
operations_research::BitPos32
uint32 BitPos32(uint32 pos)
Definition: bitset.h:331
int64
int64_t int64
Definition: integral_types.h:34
operations_research::BitQueue64::Top
int Top() const
Definition: bitset.h:723
operations_research::BitShift64
uint64 BitShift64(uint64 v)
Definition: bitset.h:342
operations_research::UnsafeMostSignificantBitPosition32
int32 UnsafeMostSignificantBitPosition32(const uint32 *const bitset, uint32 start, uint32 end)
operations_research::Bitset64::ClearAll
void ClearAll()
Definition: bitset.h:452
operations_research::Bitset64::ClearTwoBits
void ClearTwoBits(IndexType i)
Definition: bitset.h:469
index
int index
Definition: pack.cc:508
operations_research::Bitset64::Iterator
Definition: bitset.h:565
int32
int int32
Definition: integral_types.h:33
operations_research::BitQueue64::ClearTop
void ClearTop()
Definition: bitset.h:726
operations_research::LeastSignificantBitPosition32DeBruijn
int LeastSignificantBitPosition32DeBruijn(uint32 n)
Definition: bitset.h:144
operations_research::SparseBitset::NumberOfSetCallsWithDifferentArguments
int NumberOfSetCallsWithDifferentArguments() const
Definition: bitset.h:812
operations_research::Bitset64::SetBitFromOtherBitSets
void SetBitFromOtherBitSets(IndexType i, const Bitset64< IndexType > &other1, uint64 use1, const Bitset64< IndexType > &other2, uint64 use2)
Definition: bitset.h:643
operations_research::SparseBitset::Set
void Set(IntegerType index)
Definition: bitset.h:805
DCHECK_NE
#define DCHECK_NE(val1, val2)
Definition: base/logging.h:886
operations_research::SparseBitset::NotifyAllClear
void NotifyAllClear()
Definition: bitset.h:825
operations_research::LeastSignificantBitPosition32Default
int LeastSignificantBitPosition32Default(uint32 n)
Definition: bitset.h:153
operations_research::IntervalUp32
uint32 IntervalUp32(uint32 s)
Definition: bitset.h:305
DEBUG_MODE
const bool DEBUG_MODE
Definition: macros.h:24
operations_research::Bitset64::Bitset64
Bitset64()
Definition: bitset.h:414
operations_research::SparseBitset::SparseBitset
SparseBitset()
Definition: bitset.h:769
operations_research::OneRange32
uint32 OneRange32(uint32 s, uint32 e)
Definition: bitset.h:292
operations_research::SparseBitset
Definition: bitset.h:767
operations_research::LeastSignificantBitPosition64DeBruijn
int LeastSignificantBitPosition64DeBruijn(uint64 n)
Definition: bitset.h:81
operations_research::OneBit64
uint64 OneBit64(int pos)
Definition: bitset.h:38
operations_research::UnsafeLeastSignificantBitPosition64
int64 UnsafeLeastSignificantBitPosition64(const uint64 *const bitset, uint64 start, uint64 end)
operations_research::SparseBitset::SparseClearAll
void SparseClearAll()
Definition: bitset.h:772
operations_research::Bitset64::ClearBucket
void ClearBucket(IndexType i)
Definition: bitset.h:462
uint32
unsigned int uint32
Definition: integral_types.h:38
operations_research::Bitset64::Clear
void Clear(IndexType i)
Definition: bitset.h:455
operations_research::BitQueue64::ClearAndResize
void ClearAndResize(int size)
Definition: bitset.h:697
operations_research::LeastSignificantBitPosition32
int LeastSignificantBitPosition32(uint32 n)
Definition: bitset.h:182
operations_research::Bitset64::Iterator::Index
IndexType Index() const
Definition: bitset.h:581
operations_research::Bitset64::PushBack
void PushBack(bool value)
Definition: bitset.h:424
operations_research::MostSignificantBitPosition32Default
int MostSignificantBitPosition32Default(uint32 n)
Definition: bitset.h:249
operations_research::SparseBitset::PositionsSetAtLeastOnce
const std::vector< IntegerType > & PositionsSetAtLeastOnce() const
Definition: bitset.h:815
operations_research::LeastSignificantBitWord32
uint32 LeastSignificantBitWord32(uint32 n)
Definition: bitset.h:64
operations_research::Bitset64::SetContentFromBitsetOfSameSize
void SetContentFromBitsetOfSameSize(const Bitset64< OtherIndexType > &other)
Definition: bitset.h:533
operations_research::BitOffset32
uint32 BitOffset32(uint32 pos)
Definition: bitset.h:335
operations_research::Bitset64::Iterator::operator*
IndexType operator*() const
Definition: bitset.h:621
uint64
uint64_t uint64
Definition: integral_types.h:39
operations_research::UnsafeMostSignificantBitPosition64
int64 UnsafeMostSignificantBitPosition64(const uint64 *const bitset, uint64 start, uint64 end)
operations_research::MostSignificantBitPosition64
int MostSignificantBitPosition64(uint64 n)
Definition: bitset.h:231
operations_research::Bitset64::begin
Iterator begin() const
Definition: bitset.h:636
DCHECK
#define DCHECK(condition)
Definition: base/logging.h:884
operations_research::SparseBitset::ClearAll
void ClearAll()
Definition: bitset.h:776
operations_research::Bitset64::Set
void Set(IndexType i)
Definition: bitset.h:493
operations_research::BitQueue64::IncreaseSize
void IncreaseSize(int size)
Definition: bitset.h:691
operations_research::BitLength64
uint64 BitLength64(uint64 size)
Definition: bitset.h:338
DCHECK_GE
#define DCHECK_GE(val1, val2)
Definition: base/logging.h:889
operations_research::Bitset64::Iterator::operator!=
bool operator!=(const Iterator &other) const
Definition: bitset.h:618
operations_research::UnsafeLeastSignificantBitPosition32
int32 UnsafeLeastSignificantBitPosition32(const uint32 *const bitset, uint32 start, uint32 end)
operations_research::SparseBitset::Resize
void Resize(IntegerType size)
Definition: bitset.h:791
operations_research::BitQueue64::SetAllBefore
void SetAllBefore(int i)
Definition: bitset.h:711
operations_research::BitCount64
uint64 BitCount64(uint64 n)
Definition: bitset.h:42
operations_research::SparseBitset::Clear
void Clear(IntegerType index)
Definition: bitset.h:811
operations_research::SetBit32
void SetBit32(uint32 *const bitset, uint32 pos)
Definition: bitset.h:357
operations_research::BitQueue64
Definition: bitset.h:685
input
static int input(yyscan_t yyscanner)
operations_research::kAllBits64
static const uint64 kAllBits64
Definition: bitset.h:33
operations_research::TwoBitsFromPos64
uint64 TwoBitsFromPos64(uint64 pos)
Definition: bitset.h:402
operations_research::ClearBit32
void ClearBit32(uint32 *const bitset, uint32 pos)
Definition: bitset.h:365
DCHECK_EQ
#define DCHECK_EQ(val1, val2)
Definition: base/logging.h:885
operations_research::Bitset64::Iterator::Next
void Next()
Definition: bitset.h:587
operations_research::BitCount32
uint32 BitCount32(uint32 n)
Definition: bitset.h:53
operations_research::Bitset64::SetContentFromBitset
void SetContentFromBitset(const Bitset64< OtherIndexType > &other)
Definition: bitset.h:518
b
int64 b
Definition: constraint_solver/table.cc:43
DISALLOW_COPY_AND_ASSIGN
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: macros.h:29
operations_research::BitCountRange32
uint32 BitCountRange32(const uint32 *const bitset, uint32 start, uint32 end)
operations_research::Bitset64::Intersection
void Intersection(const Bitset64< IndexType > &other)
Definition: bitset.h:541
operations_research::ClearBit64
void ClearBit64(uint64 *const bitset, uint64 pos)
Definition: bitset.h:362
operations_research::Bitset64::DebugString
std::string DebugString() const
Definition: bitset.h:658
operations_research::Bitset64::Iterator::Iterator
Iterator(const Bitset64 &data_, bool at_end)
Definition: bitset.h:609
operations_research::BitLength32
uint32 BitLength32(uint32 size)
Definition: bitset.h:339
operations_research::IntervalDown32
uint32 IntervalDown32(uint32 s)
Definition: bitset.h:316
DCHECK_LE
#define DCHECK_LE(val1, val2)
Definition: base/logging.h:887
operations_research::Bitset64::ClearAndResize
void ClearAndResize(IndexType size)
Definition: bitset.h:438
operations_research::BitShift32
uint32 BitShift32(uint32 v)
Definition: bitset.h:343
operations_research::Bitset64::CopyBucket
void CopyBucket(const Bitset64< IndexType > &other, IndexType i)
Definition: bitset.h:509
CHECK
#define CHECK(condition)
Definition: base/logging.h:495
operations_research::IsEmptyRange32
bool IsEmptyRange32(const uint32 *const bitset, uint32 start, uint32 end)
operations_research::SetBit64
void SetBit64(uint64 *const bitset, uint64 pos)
Definition: bitset.h:354
operations_research::SparseBitset::SparseBitset
SparseBitset(IntegerType size)
Definition: bitset.h:770
operations_research::LeastSignificantBitPosition64
int LeastSignificantBitPosition64(uint64 n)
Definition: bitset.h:127