int-set.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <gecode/int.hh>
00035
00036 namespace Gecode {
00037
00038 IntSet::IntSetObject*
00039 IntSet::IntSetObject::allocate(int n) {
00040 IntSetObject* o = new IntSetObject;
00041 o->n = n;
00042 o->r = heap.alloc<Range>(n);
00043 return o;
00044 }
00045
00046 bool
00047 IntSet::IntSetObject::in(int n) const {
00048 int l = 0;
00049 int r = this->n - 1;
00050
00051 while (l <= r) {
00052 int m = l + (r - l) / 2;
00053 if ((this->r[m].min <= n) && (n <= this->r[m].max)) {
00054 return true;
00055 } else if (l == r) {
00056 return false;
00057 } else if (n < this->r[m].min) {
00058 r=m-1;
00059 } else {
00060 l=m+1;
00061 }
00062 }
00063 return false;
00064 }
00065
00066 bool
00067 IntSet::IntSetObject::equal(const IntSetObject& iso) const {
00068 assert((size == iso.size) || (n == iso.n));
00069 for (int i=0; i<n; i++)
00070 if ((r[i].min != iso.r[i].min) || (r[i].max != iso.r[i].max))
00071 return false;
00072 return true;
00073 }
00074
00075 IntSet::IntSetObject::~IntSetObject(void) {
00076 heap.free<Range>(r,n);
00077 }
00078
00080 class IntSet::MinInc {
00081 public:
00082 bool operator ()(const Range &x, const Range &y);
00083 };
00084
00085 forceinline bool
00086 IntSet::MinInc::operator ()(const Range &x, const Range &y) {
00087 return x.min < y.min;
00088 }
00089
00090 void
00091 IntSet::normalize(Range* r, int n) {
00092 if (n > 0) {
00093
00094 {
00095 MinInc lt_mi;
00096 Support::quicksort<Range>(r, n, lt_mi);
00097 }
00098
00099 {
00100 int min = r[0].min;
00101 int max = r[0].max;
00102 int i = 1;
00103 int j = 0;
00104 while (i < n) {
00105 if (max+1 < r[i].min) {
00106 r[j].min = min; r[j].max = max; j++;
00107 min = r[i].min; max = r[i].max; i++;
00108 } else {
00109 max = std::max(max,r[i].max); i++;
00110 }
00111 }
00112 r[j].min = min; r[j].max = max;
00113 n=j+1;
00114 }
00115 IntSetObject* o = IntSetObject::allocate(n);
00116 unsigned int s = 0;
00117 for (int i=0; i<n; i++) {
00118 s += static_cast<unsigned int>(r[i].max-r[i].min+1);
00119 o->r[i]=r[i];
00120 }
00121 o->size = s;
00122 object(o);
00123 }
00124 }
00125
00126 void
00127 IntSet::init(const int r[], int n) {
00128 assert(n > 0);
00129 Region reg;
00130 Range* dr = reg.alloc<Range>(n);
00131 for (int i=0; i<n; i++) {
00132 dr[i].min=r[i]; dr[i].max=r[i];
00133 }
00134 normalize(&dr[0],n);
00135 }
00136
00137 void
00138 IntSet::init(const int r[][2], int n) {
00139 assert(n > 0);
00140 Region reg;
00141 Range* dr = reg.alloc<Range>(n);
00142 int j = 0;
00143 for (int i=0; i<n; i++)
00144 if (r[i][0] <= r[i][1]) {
00145 dr[j].min=r[i][0]; dr[j].max=r[i][1]; j++;
00146 }
00147 normalize(&dr[0],j);
00148 }
00149
00150 IntSet::IntSet(std::initializer_list<int> r) {
00151 int n = static_cast<int>(r.size());
00152 assert(n > 0);
00153 Region reg;
00154 Range* dr = reg.alloc<Range>(n);
00155 int j=0;
00156 for (int k : r) {
00157 dr[j].min=dr[j].max=k; j++;
00158 }
00159 normalize(&dr[0],j);
00160 }
00161
00162 IntSet::IntSet(std::initializer_list<std::pair<int,int>> r) {
00163 int n = static_cast<int>(r.size());
00164 assert(n > 0);
00165 Region reg;
00166 Range* dr = reg.alloc<Range>(n);
00167 int j=0;
00168 for (const std::pair<int,int>& k : r)
00169 if (k.first <= k.second) {
00170 dr[j].min=k.first; dr[j].max=k.second; j++;
00171 }
00172 normalize(&dr[0],j);
00173 }
00174
00175
00176 void
00177 IntSet::init(int n, int m) {
00178 if (n <= m) {
00179 IntSetObject* o = IntSetObject::allocate(1);
00180 o->r[0].min = n; o->r[0].max = m;
00181 o->size = static_cast<unsigned int>(m - n + 1);
00182 object(o);
00183 }
00184 }
00185
00186 const IntSet IntSet::empty;
00187
00188 }
00189
00190
00191