Generated on Mon Aug 25 11:35:37 2008 for Gecode by doxygen 1.5.6

int-set.cc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2003
00008  *
00009  *  Last modified:
00010  *     $Date: 2008-07-11 09:31:51 +0200 (Fri, 11 Jul 2008) $ by $Author: tack $
00011  *     $Revision: 7288 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 #include "gecode/int.hh"
00039 
00040 namespace Gecode {
00041 
00042   IntSet::IntSetObject*
00043   IntSet::IntSetObject::allocate(int n) {
00044     IntSetObject* o = new IntSetObject;
00045     o->n = n;
00046     o->r = static_cast<Range*>(Memory::malloc(n*sizeof(Range)));
00047     return o;
00048   }
00049 
00050   SharedHandle::Object*
00051   IntSet::IntSetObject::copy(void) const {
00052     IntSetObject* o = allocate(n);
00053     for (int i=n; i--; )
00054       o->r[i]=r[i];
00055     return o;
00056   }
00057 
00058   IntSet::IntSetObject::~IntSetObject(void) {
00059     Memory::free(r);
00060   }
00061 
00063   class IntSet::MinInc {
00064   public:
00065     bool operator()(const Range &x, const Range &y);
00066   };
00067 
00068   forceinline bool
00069   IntSet::MinInc::operator()(const Range &x, const Range &y) {
00070     return x.min < y.min;
00071   }
00072 
00073   void
00074   IntSet::normalize(Range* r, int n) {
00075     if (n > 0) {
00076       // Sort ranges
00077       {
00078         MinInc lt_mi;
00079         Support::quicksort<Range>(r, n, lt_mi);
00080       }
00081       // Conjoin continuous ranges
00082       {
00083         int min = r[0].min;
00084         int max = r[0].max;
00085         int i = 1;
00086         int j = 0;
00087         while (i < n) {
00088           if (max+1 < r[i].min) {
00089             r[j].min = min; r[j].max = max; j++;
00090             min = r[i].min; max = r[i].max; i++;
00091           } else {
00092             max = std::max(max,r[i].max); i++;
00093           }
00094         }
00095         r[j].min = min; r[j].max = max;
00096         n=j+1;
00097       }
00098       IntSetObject* o = IntSetObject::allocate(n);
00099       for (int i=n; i--; )
00100         o->r[i]=r[i];
00101       object(o);
00102     }
00103   }
00104 
00105   void
00106   IntSet::init(const int r[], int n) {
00107     GECODE_AUTOARRAY(Range,dr,n);
00108     for (int i=n; i--; ) {
00109       dr[i].min=r[i]; dr[i].max=r[i];
00110     }
00111     normalize(&dr[0],n);
00112   }
00113 
00114   void
00115   IntSet::init(const int r[][2], int n) {
00116     GECODE_AUTOARRAY(Range,dr,n);
00117     int j = 0;
00118     for (int i=n; i--; )
00119       if (r[i][0] <= r[i][1]) {
00120         dr[j].min=r[i][0]; dr[j].max=r[i][1]; j++;
00121       }
00122     normalize(&dr[0],j);
00123   }
00124 
00125   void
00126   IntSet::init(int n, int m) {
00127     if (n <= m) {
00128       IntSetObject* o = IntSetObject::allocate(1);
00129       o->r[0].min = n; o->r[0].max = m;
00130       object(o);
00131     }
00132   }
00133 
00134   const IntSet IntSet::empty;
00135 
00136 }
00137 
00138 std::ostream&
00139 operator<<(std::ostream& os, const Gecode::IntSet& is) {
00140   os << '{';
00141   for (int i = 0; i < is.size(); ) {
00142     int min = is.min(i);
00143     int max = is.max(i);
00144     if (min == max)
00145       os << min;
00146     else
00147       os << min << ".." << max;
00148     i++;
00149     if (i < is.size())
00150       os << ',';
00151   }
00152   return os << '}';
00153 }
00154 
00155 
00156 // STATISTICS: int-var
00157