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
00035
00036
00037
00038
00039
00040 #include <gecode/int/rel.hh>
00041 #include <gecode/int/distinct.hh>
00042
00043 namespace Gecode { namespace Int { namespace BinPacking {
00044
00045 forceinline int
00046 ConflictGraph::nodes(void) const {
00047 return b.size();
00048 }
00049
00050 forceinline
00051 ConflictGraph::NodeSet::NodeSet(void) {}
00052 forceinline
00053 ConflictGraph::NodeSet::NodeSet(Region& r, int n)
00054 : Support::RawBitSetBase(r,static_cast<unsigned int>(n)) {}
00055 forceinline
00056 ConflictGraph::NodeSet::NodeSet(Region& r, int n,
00057 const NodeSet& ns)
00058 : Support::RawBitSetBase(r,static_cast<unsigned int>(n),ns) {}
00059 forceinline void
00060 ConflictGraph::NodeSet::allocate(Region& r, int n) {
00061 Support::RawBitSetBase::allocate(r,static_cast<unsigned int>(n));
00062 }
00063 forceinline void
00064 ConflictGraph::NodeSet::init(Region& r, int n) {
00065 Support::RawBitSetBase::init(r,static_cast<unsigned int>(n));
00066 }
00067 forceinline bool
00068 ConflictGraph::NodeSet::in(int i) const {
00069 return RawBitSetBase::get(static_cast<unsigned int>(i));
00070 }
00071 forceinline void
00072 ConflictGraph::NodeSet::incl(int i) {
00073 RawBitSetBase::set(static_cast<unsigned int>(i));
00074 }
00075 forceinline void
00076 ConflictGraph::NodeSet::excl(int i) {
00077 RawBitSetBase::clear(static_cast<unsigned int>(i));
00078 }
00079 forceinline void
00080 ConflictGraph::NodeSet::copy(int n, const NodeSet& ns) {
00081 RawBitSetBase::copy(static_cast<unsigned int>(n),ns);
00082 }
00083 forceinline void
00084 ConflictGraph::NodeSet::empty(int n) {
00085 RawBitSetBase::clearall(static_cast<unsigned int>(n));
00086 }
00087 forceinline bool
00088 ConflictGraph::NodeSet::iwn(NodeSet& cwa, const NodeSet& a,
00089 NodeSet& cwb, const NodeSet& b,
00090 const NodeSet& c, int _n) {
00091 unsigned int n = static_cast<unsigned int>(_n);
00092
00093 unsigned int pos = n / bpb;
00094 unsigned int bits = n % bpb;
00095
00096
00097 Support::BitSetData abc; abc.init();
00098 for (unsigned int i=0; i<pos; i++) {
00099 cwa.data[i] = Support::BitSetData::a(a.data[i],c.data[i]);
00100 cwb.data[i] = Support::BitSetData::a(b.data[i],c.data[i]);
00101 abc.o(cwa.data[i]);
00102 abc.o(cwb.data[i]);
00103 }
00104
00105 cwa.data[pos] = Support::BitSetData::a(a.data[pos],c.data[pos]);
00106 cwb.data[pos] = Support::BitSetData::a(b.data[pos],c.data[pos]);
00107 abc.o(cwa.data[pos],bits);
00108 abc.o(cwb.data[pos],bits);
00109
00110 assert(cwa.get(n) && cwb.get(n));
00111 return abc.none();
00112 }
00113
00114
00115 forceinline
00116 ConflictGraph::Node::Node(void) {}
00117
00118 forceinline
00119 ConflictGraph::Nodes::Nodes(const NodeSet& ns0)
00120 : ns(ns0), c(ns.next(0)) {}
00121 forceinline void
00122 ConflictGraph::Nodes::operator ++(void) {
00123 c = ns.next(c+1);
00124 }
00125 forceinline int
00126 ConflictGraph::Nodes::operator ()(void) const {
00127 return static_cast<int>(c);
00128 }
00129
00130 forceinline
00131 ConflictGraph::Clique::Clique(Region& r, int m)
00132 : n(r,m), c(0), w(0) {}
00133 forceinline void
00134 ConflictGraph::Clique::incl(int i, unsigned int wi) {
00135 n.incl(i); c++; w += wi;
00136 }
00137 forceinline void
00138 ConflictGraph::Clique::excl(int i, unsigned int wi) {
00139 n.excl(i); c--; w -= wi;
00140 }
00141
00142 forceinline
00143 ConflictGraph::ConflictGraph(Home& h, Region& reg,
00144 const IntVarArgs& b0, int m)
00145 : home(h), b(b0),
00146 bins(static_cast<unsigned int>(m)),
00147 node(reg.alloc<Node>(nodes())),
00148 cur(reg,nodes()), max(reg,nodes()) {
00149 for (int i=nodes(); i--; ) {
00150 node[i].n.init(reg,nodes());
00151 node[i].d=node[i].w=0;
00152 }
00153 }
00154
00155 forceinline
00156 ConflictGraph::~ConflictGraph(void) {
00157 }
00158
00159 forceinline void
00160 ConflictGraph::edge(int i, int j, bool add) {
00161 if (add) {
00162 assert(!node[i].n.in(j) && !node[j].n.in(i));
00163 node[i].n.incl(j); node[i].d++; node[i].w++;
00164 node[j].n.incl(i); node[j].d++; node[j].w++;
00165 } else {
00166 assert(node[i].n.in(j) && node[j].n.in(i));
00167 node[i].n.excl(j); node[i].d--;
00168 node[j].n.excl(i); node[j].d--;
00169 }
00170 }
00171
00172 forceinline bool
00173 ConflictGraph::adjacent(int i, int j) const {
00174 assert(node[i].n.in(j) == node[j].n.in(i));
00175 return node[i].n.in(j);
00176 }
00177
00178 forceinline int
00179 ConflictGraph::pivot(const NodeSet& a, const NodeSet& b) const {
00180 Nodes i(a), j(b);
00181 assert((i() < nodes()) || (j() < nodes()));
00182 int p;
00183 if (i() < nodes()) {
00184 p = i(); ++i;
00185 } else {
00186 p = j(); ++j;
00187 }
00188 unsigned int m = node[p].d;
00189 while (i() < nodes()) {
00190 if (node[i()].d > m) {
00191 p=i(); m=node[p].d;
00192 }
00193 ++i;
00194 }
00195 while (j() < nodes()) {
00196 if (node[j()].d > m) {
00197 p=j(); m=node[p].d;
00198 }
00199 ++j;
00200 }
00201 return p;
00202 }
00203
00204 forceinline ExecStatus
00205 ConflictGraph::clique(void) {
00206
00207 if ((cur.c > max.c) || ((cur.c == max.c) && (cur.w > max.w))) {
00208 max.n.copy(nodes(),cur.n); max.c=cur.c; max.w=cur.w;
00209 if (max.c > bins)
00210 return ES_FAILED;
00211 }
00212
00213 ViewArray<IntView> bv(home,static_cast<int>(cur.c));
00214 int i=0;
00215 for (Nodes c(cur.n); c() < nodes(); ++c)
00216 bv[i++] = b[c()];
00217 assert(i == static_cast<int>(cur.c));
00218 return Distinct::Dom<IntView>::post(home,bv);
00219 }
00220
00221 forceinline ExecStatus
00222 ConflictGraph::clique(int i) {
00223 if (1 > max.c) {
00224 assert(max.n.none(nodes()));
00225 max.n.incl(i); max.c=1; max.w=0;
00226 }
00227 return ES_OK;
00228 }
00229
00230 forceinline ExecStatus
00231 ConflictGraph::clique(int i, int j) {
00232 unsigned int w = node[i].w + node[j].w;
00233 if ((2 > max.c) || ((2 == max.c) && (cur.w > max.w))) {
00234 max.n.empty(nodes());
00235 max.n.incl(i); max.n.incl(j);
00236 max.c=2; max.w=w;
00237 if (max.c > bins)
00238 return ES_FAILED;
00239 }
00240 return Rel::Nq<IntView,IntView>::post(home,b[i],b[j]);
00241 }
00242
00243 forceinline ExecStatus
00244 ConflictGraph::clique(int i, int j, int k) {
00245 unsigned int w = node[i].w + node[j].w + node[k].w;
00246 if ((3 > max.c) || ((3 == max.c) && (cur.w > max.w))) {
00247 max.n.empty(nodes());
00248 max.n.incl(i); max.n.incl(j); max.n.incl(k);
00249 max.c=3; max.w=w;
00250 if (max.c > bins)
00251 return ES_FAILED;
00252 }
00253
00254 ViewArray<IntView> bv(home,3);
00255 bv[0]=b[i]; bv[1]=b[j]; bv[2]=b[k];
00256 return Distinct::Dom<IntView>::post(home,bv);
00257 }
00258
00259 forceinline ExecStatus
00260 ConflictGraph::post(void) {
00261
00262 {
00263 Region reg(home);
00264
00265 Support::StaticStack<int,Region> n(reg,2*nodes());
00266
00267
00268 for (int i=nodes(); i--; ) {
00269 if ((node[i].d == 1) || (node[i].d == 2))
00270 n.push(i);
00271 }
00272 while (!n.empty()) {
00273 int i = n.pop();
00274 switch (node[i].d) {
00275 case 0:
00276
00277 break;
00278 case 1: {
00279 Nodes ii(node[i].n);
00280 int j=ii();
00281 GECODE_ES_CHECK(clique(i,j));
00282
00283 edge(i,j,false);
00284 if ((node[j].d == 1) || (node[j].d == 2))
00285 n.push(j);
00286 break;
00287 }
00288 case 2: {
00289 Nodes ii(node[i].n);
00290 int j=ii(); ++ii;
00291 int k=ii();
00292 if (adjacent(j,k)) {
00293 GECODE_ES_CHECK(clique(i,j,k));
00294
00295 if ((node[j].d == 2) || (node[k].d == 2))
00296 edge(j,k,false);
00297 } else {
00298 GECODE_ES_CHECK(clique(i,j));
00299 GECODE_ES_CHECK(clique(i,k));
00300 }
00301 edge(i,j,false);
00302 edge(i,k,false);
00303 if ((node[j].d == 1) || (node[j].d == 2))
00304 n.push(j);
00305 if ((node[k].d == 1) || (node[k].d == 2))
00306 n.push(k);
00307 break;
00308 }
00309 default: GECODE_NEVER;
00310 }
00311 }
00312 }
00313
00314 {
00315 Region reg(home);
00316 NodeSet p(reg,nodes()), x(reg,nodes());
00317 bool empty = true;
00318 for (int i=nodes(); i--; )
00319 if (node[i].d > 0) {
00320 p.incl(i); empty = false;
00321 } else {
00322
00323 GECODE_ES_CHECK(clique(i));
00324 }
00325 if (empty)
00326 return ES_OK;
00327 GECODE_ES_CHECK(bk(p,x));
00328 }
00329 return ES_OK;
00330 }
00331
00332 inline IntSet
00333 ConflictGraph::maxclique(void) const {
00334 Region reg(home);
00335 int* n=reg.alloc<int>(max.c);
00336 int j=0;
00337 for (Nodes i(max.n); i() < nodes(); ++i)
00338 n[j++]=i();
00339 assert(j == static_cast<int>(max.c));
00340 IntSet s(n,static_cast<int>(max.c));
00341 return s;
00342 }
00343
00344 }}}
00345
00346
00347