void element(Home home, IntSharedArray c, IntVar x0, BoolVar x1, IntConLevel) { using namespace Int; if (c.size() == 0) throw TooFewArguments("Int::element"); if (home.failed()) return; for (int i = c.size(); i--; ) Limits::check(c[i],"Int::element"); GECODE_ES_FAIL((Element::post_int<IntView,BoolView>(home,c,x0,x1))); }
void element(Home home, IntSharedArray a, IntVar x, int w, IntVar y, int h, BoolVar z, IntConLevel icl) { using namespace Int; if (a.size() != w*h) throw Int::ArgumentSizeMismatch("Int::element"); if (home.failed()) return; element(home, a, pair(home,x,w,y,h), z, icl); }
forceinline ExecStatus post_int(Home home, IntSharedArray& c, V0 x0, V1 x1) { assert(c.size() > 0); GECODE_ME_CHECK(x0.gq(home,0)); GECODE_ME_CHECK(x0.le(home,c.size())); Support::IntType idx_type = Support::s_type(c.size()); int min = c[0]; int max = c[0]; for (int i=1; i<c.size(); i++) { min = std::min(c[i],min); max = std::max(c[i],max); } GECODE_ME_CHECK(x1.gq(home,min)); GECODE_ME_CHECK(x1.lq(home,max)); Support::IntType val_type = std::max(Support::s_type(min),Support::s_type(max)); switch (idx_type) { case Support::IT_CHAR: switch (val_type) { case Support::IT_CHAR: return Int<V0,V1,signed char,signed char>::post(home,c,x0,x1); case Support::IT_SHRT: return Int<V0,V1,signed char,signed short int>::post(home,c,x0,x1); default: break; } break; case Support::IT_SHRT: switch (val_type) { case Support::IT_CHAR: case Support::IT_SHRT: return Int<V0,V1,signed short int,signed short int>::post(home,c,x0,x1); default: break; } break; default: break; } return Int<V0,V1,signed int,signed int>::post(home,c,x0,x1); }
void multibinpacking(Home home, int n, int m, int k, const IntVarArgs& y, const IntVarArgs& x, const IntSharedArray& D, const IntSharedArray& B, IntConLevel) { /// Check input sizes if (n*k != D.size() ) throw ArgumentSizeMismatch("Int::multibinpacking"); if (k != B.size() ) throw ArgumentSizeMismatch("Int::multibinpacking"); if (n != x.size() ) throw ArgumentSizeMismatch("Int::multibinpacking"); if (m*k != y.size() ) throw ArgumentSizeMismatch("Int::multibinpacking"); for (int i=B.size(); i--; ) Limits::nonnegative(B[i],"Int::multibinpacking"); if (home.failed()) return; /// Post first each single binpacking constraint /// Capacity constraint for each dimension for ( int j = 0; j < m; ++j ) for ( int l = 0; l < k; ++l ) { IntView yi(y[j*k+l]); GECODE_ME_FAIL(yi.lq(home,B[l])); } /// Post a binpacking constraints for each dimension for ( int l = 0; l < k; ++l ) { ViewArray<OffsetView> yv(home,m); for (int j=m; j--; ) yv[j] = OffsetView(y[j*k+l],0); ViewArray<BinPacking::Item> xs(home,x.size()); for (int i=xs.size(); i--; ) xs[i] = BinPacking::Item(x[i],D[i*k+l]); Support::quicksort(&xs[0], xs.size()); GECODE_ES_FAIL(Int::BinPacking::Pack::post(home,yv,xs)); } /// Clique Finding and Alldifferent posting { /// Firt construct the conflict graph graph_t* g = graph_new(n); for ( int a = 0; a < n-1; ++a ) { for ( int b = a+1; b < n; ++b ) { int v = a; /// The variable with smaller domain int w = b; unsigned int nl = 0; if ( x[a].size() > x[b].size() ) { v = b; w = a; } IntVarValues i(x[v]); IntVarValues j(x[w]); while ( i() ) { if ( i.val() != j.val() ) { if ( i.val() < j.val() ) break; else ++i; } else { for ( int l = 0; l < k; ++l ) if ( D[a*k+l] + D[b*k+l] > B[l] ) { nl++; break; } ++i; ++j; } } if ( nl >= x[v].size() ) GRAPH_ADD_EDGE(g,a,b); } } /// Consitency cheking: look for the maximum clique clique_options* opts; opts = (clique_options*) malloc (sizeof(clique_options)); opts->time_function=NULL; opts->reorder_function=reorder_by_default; opts->reorder_map=NULL; opts->user_function=NULL; opts->user_data=NULL; opts->clique_list=NULL; opts->clique_list_length=0; set_t s; s = clique_find_single ( g, 0, 0, TRUE, opts); if ( s != NULL ) { if ( set_size(s) > m ) { set_free(s); free(opts); graph_free(g); GECODE_ES_FAIL(ES_FAILED); } if ( true ) { //option == 1 ) { FIXING for ( int a = 0, j = 0; a < n; ++a ) { if ( SET_CONTAINS_FAST(s,a) ) { assert( x[a].in(j) ); IntView xi(x[a]); GECODE_ME_FAIL(xi.eq(home,j++)); } } } } if ( s!=NULL ) set_free(s); /// List every maximal clique in the conflict graph opts->user_function=record_clique_func; clique_find_all ( g, 2, 0, TRUE, opts); for ( int c = 0; c < clique_count; c++ ) { ViewArray<IntView> xv(home, set_size(clique_list[c])); for ( int a = 0, idx = 0; a < n; ++a ) if ( SET_CONTAINS_FAST(clique_list[c],a) ) xv[idx++] = x[a]; GECODE_ES_FAIL(Distinct::Dom<IntView>::post(home,xv)); set_free(clique_list[c]); } free(opts); graph_free(g); } }