Пример #1
0
	Sudoku(const SizeOptions& opt) : x(*this, 9 * 9, 1, 9) {

		Matrix<IntVarArray> m(x, 9, 9);

		for (int i = 0; i < 9; i++) {
			distinct(*this, m.row(i), opt.icl());
			distinct(*this, m.col(i), opt.icl());
		}

		for (int i = 0; i < 9; i += 3) {
			for (int j = 0; j < 9; j += 3) {
				distinct(*this, m.slice(i, i + 3, j, j + 3), opt.icl());
			}
		}

		for (int i = 0; i < 9; i++) {
			for (int j = 0; j < 9; j++) {
				if (int v = sudokuField(board, i, j)) {
					//Here the m(i, j) is the element in colomn i and row j.
					rel(*this, m(i, j), IRT_EQ, v);
				}
			}
		}

		branch(*this, x, INT_VAR_NONE(), INT_VAL_SPLIT_MIN());
	}
Пример #2
0
  Coins3(const SizeOptions& opt) 
  : 
    num_coins_val(opt.size()),
    x(*this, n, 0, 99),
    num_coins(*this, 0, 99)
  {

    // values of the coins
    int _variables[] = {1, 2, 5, 10, 25, 50}; 
    IntArgs variables(n, _variables); 

    // sum the number of coins
    linear(*this, x, IRT_EQ, num_coins, opt.icl());

    // This is the "main loop":
    // Checks that all changes from 1 to 99 can be made
    for(int j = 0; j < 99; j++) {
      IntVarArray tmp(*this, n, 0, 99);
      linear(*this, variables, tmp, IRT_EQ, j, opt.icl());
      for(int i = 0; i < n; i++) {
        rel(*this, tmp[i] <= x[i], opt.icl());
      }
    }

    // set the number of coins (via opt.size())
    // don't forget 
    //  -search dfs
    if (num_coins_val) {
      rel(*this, num_coins == num_coins_val, opt.icl());
    }

    branch(*this, x, INT_VAR_SIZE_MAX(), INT_VAL_MIN()); 

  }
Пример #3
0
  /// Actual model
  OrthoLatinSquare(const SizeOptions& opt)
    : Script(opt),
      n(opt.size()),
      x1(*this,n*n,1,n), x2(*this,n*n,1,n) {
    const int nn = n*n;
    IntVarArgs z(*this,nn,0,n*n-1);

    distinct(*this, z, opt.icl());
    // Connect
    {
      IntArgs mod(n*n);
      IntArgs div(n*n);
      for (int i=0; i<n; i++)
        for (int j=0; j<n; j++) {
          mod[i*n+j] = j+1;
          div[i*n+j] = i+1;
        }
      for (int i = nn; i--; ) {
        element(*this, div, z[i], x2[i]);
        element(*this, mod, z[i], x1[i]);
      }
    }

    // Rows
    for (int i = n; i--; ) {
      IntVarArgs ry(n);
      for (int j = n; j--; )
        ry[j] = y1(i,j);
      distinct(*this, ry, opt.icl());
      for (int j = n; j--; )
        ry[j] = y2(i,j);
      distinct(*this, ry, opt.icl());
    }
    for (int j = n; j--; ) {
      IntVarArgs cy(n);
      for (int i = n; i--; )
        cy[i] = y1(i,j);
      distinct(*this, cy, opt.icl());
      for (int i = n; i--; )
        cy[i] = y2(i,j);
      distinct(*this, cy, opt.icl());
    }

    for (int i = 1; i<n; i++) {
      IntVarArgs ry1(n);
      IntVarArgs ry2(n);
      for (int j = n; j--; ) {
        ry1[j] = y1(i-1,j);
        ry2[j] = y2(i,j);
      }
      rel(*this, ry1, IRT_GQ, ry2);
    }

    branch(*this, z, INT_VAR_SIZE_MIN(), INT_VAL_SPLIT_MIN());
  }
Пример #4
0
  /// Actual model
  TSP(const SizeOptions& opt)
    : p(ps[opt.size()]),
      succ(*this, p.size(), 0, p.size()-1),
      total(*this, 0, p.max()) {
    int n = p.size();

    // Cost matrix
    IntArgs c(n*n, p.d());

    for (int i=n; i--; )
      for (int j=n; j--; )
        if (p.d(i,j) == 0)
          rel(*this, succ[i], IRT_NQ, j);

    // Cost of each edge
    IntVarArgs costs(*this, n, Int::Limits::min, Int::Limits::max);

    // Enforce that the succesors yield a tour with appropriate costs
    circuit(*this, c, succ, costs, total, opt.icl());

    // Just assume that the circle starts forwards
    {
      IntVar p0(*this, 0, n-1);
      element(*this, succ, p0, 0);
      rel(*this, p0, IRT_LE, succ[0]);
    }

    // First enumerate cost values, prefer those that maximize cost reduction
    branch(*this, costs, INT_VAR_REGRET_MAX_MAX(), INT_VAL_SPLIT_MIN());

    // Then fix the remaining successors
    branch(*this, succ,  INT_VAR_MIN_MIN(), INT_VAL_MIN());
  }
Пример #5
0
  /// Actual model
  Photo(const SizeOptions& opt) :
    IntMinimizeScript(opt),
    spec(opt.size() == 0 ? p_small : p_large),
    pos(*this,spec.n_names, 0, spec.n_names-1),
    violations(*this,0,spec.n_prefs)
  {
    // Map preferences to violation
    BoolVarArgs viol(spec.n_prefs);
    for (int i=0; i<spec.n_prefs; i++) {
      int pa = spec.prefs[2*i+0];
      int pb = spec.prefs[2*i+1];
      viol[i] = expr(*this, abs(pos[pa]-pos[pb]) > 1);
    }
    rel(*this, violations == sum(viol));

    distinct(*this, pos, opt.icl());

    // Break some symmetries
    rel(*this, pos[0] < pos[1]);

    if (opt.branching() == BRANCH_NONE) {
      branch(*this, pos, INT_VAR_NONE(), INT_VAL_MIN());
    } else {
      branch(*this, pos, tiebreak(INT_VAR_DEGREE_MAX(),INT_VAR_SIZE_MIN()),
             INT_VAL_MIN());
    }
  }
  /// Actual model
  GolombRuler(const SizeOptions& opt)
    : IntMinimizeScript(opt),
      m(*this,opt.size(),0,
        (opt.size() < 31) ? (1 << (opt.size()-1))-1 : Int::Limits::max) {

    // Assume first mark to be zero
    rel(*this, m[0], IRT_EQ, 0);

    // Order marks
    rel(*this, m, IRT_LE);

    // Number of marks and differences
    const int n = m.size();
    const int n_d = (n*n-n)/2;

    // Array of differences
    IntVarArgs d(n_d);

    // Setup difference constraints
    for (int k=0, i=0; i<n-1; i++)
      for (int j=i+1; j<n; j++, k++)
        // d[k] is m[j]-m[i] and must be at least sum of first j-i integers
        rel(*this, d[k] = expr(*this, m[j]-m[i]),
                   IRT_GQ, (j-i)*(j-i+1)/2);

    distinct(*this, d, opt.icl());

    // Symmetry breaking
    if (n > 2)
      rel(*this, d[0], IRT_LE, d[n_d-1]);

    branch(*this, m, INT_VAR_NONE(), INT_VAL_MIN());
  }
Пример #7
0
 /// Post a distinct-linear constraint on variables \a x with sum \a c
 void distinctlinear(Cache& dc, const IntVarArgs& x, int c,
                     const SizeOptions& opt) {
   int n=x.size();
   if (opt.model() == MODEL_DECOMPOSE) {
     if (n < 8)
       linear(*this, x, IRT_EQ, c, opt.icl());
     else if (n == 8)
       rel(*this, x, IRT_NQ, 9*(9+1)/2 - c);
     distinct(*this, x, opt.icl());
   } else {
     switch (n) {
     case 0:
       return;
     case 1:
       rel(*this, x[0], IRT_EQ, c);
       return;
     case 8:
       // Prune the single missing digit
       rel(*this, x, IRT_NQ, 9*(9+1)/2 - c);
       break;
     case 9:
       break;
     default:
       if (c == n*(n+1)/2) {
         // sum has unique decomposition: 1 + ... + n
         rel(*this, x, IRT_LQ, n);
       } else if (c == n*(n+1)/2 + 1) {
         // sum has unique decomposition: 1 + ... + n-1 + n+1
         rel(*this, x, IRT_LQ, n+1);
         rel(*this, x, IRT_NQ, n);
       } else if (c == 9*(9+1)/2 - (9-n)*(9-n+1)/2) {
         // sum has unique decomposition: (9-n+1) + (9-n+2) + ... + 9
         rel(*this, x, IRT_GQ, 9-n+1);
       } else if (c == 9*(9+1)/2 - (9-n)*(9-n+1)/2 + 1) {
         // sum has unique decomposition: (9-n) + (9-n+2) + ... + 9
         rel(*this, x, IRT_GQ, 9-n);
         rel(*this, x, IRT_NQ, 9-n+1);
       } else {
         extensional(*this, x, dc.get(n,c));
         return;
       }
     }
     distinct(*this, x, opt.icl());
   }
 }
Пример #8
0
  LatinSquares(const SizeOptions& opt) 
    : 
    n(opt.size()), 
    x(*this, n*n, 1, n) {

  
    // Matrix wrapper for the x grid
    Matrix<IntVarArray> m(x, n, n);

    latin_square(*this, m, opt.icl());

    // Symmetry breaking. 0 is upper left column
    if (opt.symmetry() == SYMMETRY_MIN) {
      rel(*this, x[0] == 1, opt.icl());
    }

    branch(*this, x, INT_VAR_SIZE_MIN(), INT_VAL_RANGE_MAX());

  }
Пример #9
0
  /// Actual model
  AllInterval(const SizeOptions& opt) :
    x(*this, opt.size(), 0, opt.size()-1),
    d(*this, opt.size()-1, 1, opt.size()-1) {
    const int n = x.size();

    // Set up variables for distance
    for (int i=0; i<n-1; i++)
      rel(*this, d[i] == abs(x[i+1]-x[i]), opt.icl());

    distinct(*this, x, opt.icl());
    distinct(*this, d, opt.icl());

    // Break mirror symmetry
    rel(*this, x[0], IRT_LE, x[1]);
    // Break symmetry of dual solution
    rel(*this, d[0], IRT_GR, d[n-2]);

    branch(*this, x, INT_VAR_SIZE_MIN(), INT_VAL_SPLIT_MIN());
  }
Пример #10
0
  // Actual model
  AllEqual(const SizeOptions& opt) : 
    x(*this, n, 0, 6)
  {

    all_equal(*this, x, n, opt.icl());
      
    // branching
    branch(*this, x, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
    
  }
Пример #11
0
 /// The actual problem
 Queens(const SizeOptions& opt)
   : q(*this,opt.size(),0,opt.size()-1) {
   const int n = q.size();
   switch (opt.propagation()) {
   case PROP_BINARY:
     for (int i = 0; i<n; i++)
       for (int j = i+1; j<n; j++) {
         rel(*this, q[i] != q[j]);
         rel(*this, q[i]+i != q[j]+j);
         rel(*this, q[i]-i != q[j]-j);
       }
     break;
   case PROP_MIXED:
     for (int i = 0; i<n; i++)
       for (int j = i+1; j<n; j++) {
         rel(*this, q[i]+i != q[j]+j);
         rel(*this, q[i]-i != q[j]-j);
       }
     distinct(*this, q, opt.icl());
     break;
   case PROP_DISTINCT:
     distinct(*this, IntArgs::create(n,0,1), q, opt.icl());
     distinct(*this, IntArgs::create(n,0,-1), q, opt.icl());
     distinct(*this, q, opt.icl());
     break;
   }
   switch(opt.branching()) {
   case BRANCH_MIN:
       branch(*this, q, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
       break;
   case BRANCH_MID:
     branch(*this, q, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
     break;
   case BRANCH_MAX_MAX:
     branch(*this, q, INT_VAR_SIZE_MAX(), INT_VAL_MIN());
     break;
   case BRANCH_KNIGHT_MOVE:
     branch(*this, q, INT_VAR_MIN_MIN(), INT_VAL_MED());
     break;
   }
 }
Пример #12
0
  SetCovering(const SizeOptions& opt) 
  : 
    min_distance(opt.size()),
    x(*this, num_cities, 0, 1),
    z(*this, 0, num_cities)
  {

    // distance between the cities
    int distance[] =
      {
        0,10,20,30,30,20,
       10, 0,25,35,20,10,
       20,25, 0,15,30,20,
       30,35,15, 0,15,25,
       30,20,30,15, 0,14,
       20,10,20,25,14, 0
      };

    // z = sum of placed fire stations
    linear(*this, x, IRT_EQ, z, opt.icl());

    // ensure that all cities are covered by at least one fire station
    for(int i = 0; i < num_cities; i++) {

      IntArgs in_distance(num_cities);  // the cities within the distance
      for(int j = 0; j < num_cities; j++) {
        if (distance[i*num_cities+j] <= min_distance) {
          in_distance[j] = 1;
        } else {
          in_distance[j] = 0;
        }
      }

      linear(*this, in_distance, x, IRT_GQ, 1, opt.icl());
    }
    
    branch(*this, x, INT_VAR_SIZE_MAX(), INT_VAL_SPLIT_MIN()); 

  }
  /// Actual model
  AllInterval(const SizeOptions& opt) :
    x(*this, opt.size(), 0, opt.size() - 1) {
    const int n = x.size();

    IntVarArgs d(n-1);

    // Set up variables for distance
    for (int i=0; i<n-1; i++)
      d[i] = expr(*this, abs(x[i+1]-x[i]), opt.icl());

    // Constrain them to be between 1 and n-1
    dom(*this, d, 1, n-1);

    distinct(*this, x, opt.icl());
    distinct(*this, d, opt.icl());

    // Break mirror symmetry
    rel(*this, x[0], IRT_LE, x[1]);
    // Break symmetry of dual solution
    rel(*this, d[0], IRT_GR, d[n-2]);

    branch(*this, x, INT_VAR_SIZE_MIN, INT_VAL_SPLIT_MIN);
  }
Пример #14
0
  /// Post constraints
  MagicSquare(const SizeOptions& opt)
    : n(opt.size()), x(*this,n*n,1,n*n) {
    // Number of fields on square
    const int nn = n*n;

    // Sum of all a row, column, or diagonal
    const int s  = nn*(nn+1) / (2*n);

    // Matrix-wrapper for the square
    Matrix<IntVarArray> m(x, n, n);

    for (int i = n; i--; ) {
      linear(*this, m.row(i), IRT_EQ, s, opt.icl());
      linear(*this, m.col(i), IRT_EQ, s, opt.icl());
    }
    // Both diagonals must have sum s
    {
      IntVarArgs d1y(n);
      IntVarArgs d2y(n);
      for (int i = n; i--; ) {
        d1y[i] = m(i,i);
        d2y[i] = m(n-i-1,i);
      }
      linear(*this, d1y, IRT_EQ, s, opt.icl());
      linear(*this, d2y, IRT_EQ, s, opt.icl());
    }

    // All fields must be distinct
    distinct(*this, x, opt.icl());

    // Break some (few) symmetries
    rel(*this, m(0,0), IRT_GR, m(0,n-1));
    rel(*this, m(0,0), IRT_GR, m(n-1,0));

    branch(*this, x, INT_VAR_SIZE_MIN, INT_VAL_SPLIT_MIN);
  }
Пример #15
0
  // Actual model
  AlldifferentCst(const SizeOptions& opt) : 
    x(*this, n, 1, 9),
    cst(*this, n, 0, 9)
  {

    int _cst1[] = {0,1,0,4};
    IntArgs cst1(n, _cst1);
    for(int i = 0; i < n; i++) {
      rel(*this, cst[i] == cst1[i]);
    }

    alldifferent_cst(*this, x, cst, n, opt.icl());

    // branching
    branch(*this, x, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
    
  }
Пример #16
0
  // Actual model
  AlldifferentModulo(const SizeOptions& opt) : 
    x(*this, n, 1, 25),
    m(*this, 1, 5)
  {

    int _tmp[] = {25,1,14,3};
    IntArgs tmp(n, _tmp);
    for(int i = 0; i < n; i++) {
      rel(*this, x[i] == tmp[i]);
    }

    alldifferent_modulo(*this, x, n, m, opt.icl());
    // rel(*this, m==5);

    // branching
    branch(*this, x, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
    branch(*this, m, INT_VAL_MIN());
    
  }
Пример #17
0
  /// Actual model
  Partition(const SizeOptions& opt)
    : x(*this,opt.size(),1,2*opt.size()),
      y(*this,opt.size(),1,2*opt.size()) {
    const int n = opt.size();

    // Break symmetries by ordering numbers in each group
    rel(*this, x, IRT_LE);
    rel(*this, y, IRT_LE);

    rel(*this, x[0], IRT_LE, y[0]);

    IntVarArgs xy(2*n);
    for (int i = n; i--; ) {
      xy[i] = x[i]; xy[n+i] = y[i];
    }
    distinct(*this, xy, opt.icl());

    IntArgs c(2*n);
    for (int i = n; i--; ) {
      c[i] = 1; c[n+i] = -1;
    }
    linear(*this, c, xy, IRT_EQ, 0);

    // Array of products
    IntVarArgs sxy(2*n), sx(n), sy(n);

    for (int i = n; i--; ) {
      sx[i] = sxy[i] =   expr(*this, sqr(x[i]));
      sy[i] = sxy[n+i] = expr(*this, sqr(y[i]));
    }
    linear(*this, c, sxy, IRT_EQ, 0);

    // Redundant constraints
    linear(*this, x, IRT_EQ, 2*n*(2*n+1)/4);
    linear(*this, y, IRT_EQ, 2*n*(2*n+1)/4);
    linear(*this, sx, IRT_EQ, 2*n*(2*n+1)*(4*n+1)/12);
    linear(*this, sy, IRT_EQ, 2*n*(2*n+1)*(4*n+1)/12);

    branch(*this, xy, INT_VAR_AFC_SIZE_MAX(opt.decay()), INT_VAL_MIN());
  }
Пример #18
0
  /// The actual model
  GraphColor(const SizeOptions& opt)
    : g(opt.size() == 1 ? g2 : g1),
      v(*this,g.n_v,0,g.n_v),
      m(*this,0,g.n_v) {
    rel(*this, v, IRT_LQ, m);
    for (int i = 0; g.e[i] != -1; i += 2)
      rel(*this, v[g.e[i]], IRT_NQ, v[g.e[i+1]]);

    const int* c = g.c;
    for (int i = *c++; i--; c++)
      rel(*this, v[*c], IRT_EQ, i);
    while (*c != -1) {
      int n = *c;
      IntVarArgs x(n); c++;
      for (int i = n; i--; c++)
        x[i] = v[*c];
      distinct(*this, x, opt.icl());
      if (opt.model() == MODEL_CLIQUE)
        rel(*this, m, IRT_GQ, n-1);
    }
    branch(*this, m, INT_VAL_MIN);
    switch (opt.branching()) {
    case BRANCH_SIZE:
      branch(*this, v, INT_VAR_SIZE_MIN, INT_VAL_MIN);
      break;
    case BRANCH_DEGREE:
      branch(*this, v, tiebreak(INT_VAR_DEGREE_MAX,INT_VAR_SIZE_MIN),
             INT_VAL_MIN);
      break;
    case BRANCH_SIZE_DEGREE:
      branch(*this, v, INT_VAR_SIZE_DEGREE_MIN, INT_VAL_MIN);
      break;
    case BRANCH_SIZE_AFC:
      branch(*this, v, INT_VAR_SIZE_AFC_MIN, INT_VAL_MIN);
      break;
    default:
      break;
    }
  }
  // Actual model
  AlldifferentOnIntersection(const SizeOptions& opt) : 
    x(*this, m, 1, 9),
    y(*this, n, 1, 9)
  {

    int _xtmp[] = {5,9,1,5};
    IntArgs xtmp(m, _xtmp);
    for(int i = 0; i < m; i++) {
      rel(*this, x[i] == xtmp[i]);
    }

    int _ytmp[] = {2, 1, 6, 9, 6, 2};
    IntArgs ytmp(n, _ytmp);
    for(int j = 0; j < n; j++) {
      rel(*this, y[j] == ytmp[j]);
    }

    alldifferent_on_intersection(*this, x, m, y, n, opt.icl());

    // branching
    branch(*this, x, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
    branch(*this, y, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
    
  }
Пример #20
0
  /// Setup model
  SportsLeague(const SizeOptions& opt) :
    teams(opt.size()),
    home(*this, periods() * teams, 1, weeks()),
    away(*this, periods() * teams, 2, weeks()+1),
    game(*this, weeks()*periods(), 2, teams*weeks())
  {
    // Initialize round robin schedule
    RRS r(teams);

    // Domain for gamenumber of period
    for (int w=0; w<weeks(); w++) {
      IntArgs rh(periods()), ra(periods()), rg(periods());
      IntVarArgs n(*this,periods(),0,periods()-1);

      distinct(*this, n, opt.icl());

      r.hag(w,rh,ra,rg);

      for (int p=0; p<periods(); p++) {
        element(*this, rh, n[p], h(p,w));
        element(*this, ra, n[p], a(p,w));
        element(*this, rg, n[p], g(p,w));
      }
    }

    /// (h,a) and (a,h) are the same game, focus on home (that is, h<a)
    for (int p=0; p<periods(); p++)
      for (int w=0; w<teams; w++)
        rel(*this, h(p,w), IRT_LE, a(p,w));

    // Home teams in first week are ordered
    {
      IntVarArgs h0(periods());
      for (int p=0; p<periods(); p++)
        h0[p] = h(p,0);
      rel(*this, h0, IRT_LE);
    }

    // Fix first pair
    rel(*this, h(0,0), IRT_EQ, 1);
    rel(*this, a(0,0), IRT_EQ, 2);

    /// Column constraint: each team occurs exactly once
    for (int w=0; w<teams; w++) {
      IntVarArgs c(teams);
      for (int p=0; p<periods(); p++) {
        c[2*p] = h(p,w); c[2*p+1] = a(p,w);
      }
      distinct(*this, c, opt.icl());
    }

    /// Row constraint: no team appears more than twice
    for (int p=0; p<periods(); p++) {
      IntVarArgs r(2*teams);
      for (int t=0; t<teams; t++) {
        r[2*t]   = h(p,t);
        r[2*t+1] = a(p,t);
      }
      IntArgs values(teams);
      for (int i=1; i<=teams; i++)
        values[i-1] = i;
      count(*this, r, IntSet(2,2), values, opt.icl());
    }

    // Redundant constraint
    for (int p=0; p<periods(); p++)
      for (int w=0; w<weeks(); w ++)
        rel(*this, teams * h(p,w) + a(p,w) - g(p,w) == teams);

    distinct(*this, game, opt.icl());

    branch(*this, game, INT_VAR_NONE(), INT_VAL_SPLIT_MIN());
  }
Пример #21
0
  /// The model of the problem
  CrowdedChess(const SizeOptions& opt)
    : n(opt.size()),
      s(*this, n*n, 0, PMAX-1),
      queens(*this, n, 0, n-1),
      rooks(*this, n, 0, n-1),
      knights(*this, n*n, 0, 1) {
    const int nkval = sizeof(kval)/sizeof(int);
    const int nn = n*n, q = n, r = n, b = (2*n)-2,
      k = n <= nkval ? kval[n-1] : kval[nkval-1];
    const int e = nn - (q + r + b + k);

    assert(nn == (e + q + r + b + k));

    Matrix<IntVarArray> m(s, n);

    // ***********************
    // Basic model
    // ***********************

    count(*this, s, E, IRT_EQ, e, opt.icl());
    count(*this, s, Q, IRT_EQ, q, opt.icl());
    count(*this, s, R, IRT_EQ, r, opt.icl());
    count(*this, s, B, IRT_EQ, b, opt.icl());
    count(*this, s, K, IRT_EQ, k, opt.icl());

    // Collect rows and columns for handling rooks and queens
    for (int i = 0; i < n; ++i) {
      IntVarArgs aa = m.row(i), bb = m.col(i);

      count(*this, aa, Q, IRT_EQ, 1, opt.icl());
      count(*this, bb, Q, IRT_EQ, 1, opt.icl());
      count(*this, aa, R, IRT_EQ, 1, opt.icl());
      count(*this, bb, R, IRT_EQ, 1, opt.icl());

      // Connect (queens|rooks)[i] to the row it is in
      element(*this, aa, queens[i], Q, ICL_DOM);
      element(*this, aa,  rooks[i], R, ICL_DOM);
    }

    // N-queens constraints
    distinct(*this, queens, ICL_DOM);
    distinct(*this, IntArgs::create(n,0,1), queens, ICL_DOM);
    distinct(*this, IntArgs::create(n,0,-1), queens, ICL_DOM);

    // N-rooks constraints
    distinct(*this,  rooks, ICL_DOM);

    // Collect diagonals for handling queens and bishops
    for (int l = n; l--; ) {
      const int il = (n-1) - l;
      IntVarArgs d1(l+1), d2(l+1), d3(l+1), d4(l+1);
      for (int i = 0; i <= l; ++i) {
        d1[i] = m(i+il, i);
        d2[i] = m(i, i+il);
        d3[i] = m((n-1)-i-il, i);
        d4[i] = m((n-1)-i, i+il);
      }

      count(*this, d1, Q, IRT_LQ, 1, opt.icl());
      count(*this, d2, Q, IRT_LQ, 1, opt.icl());
      count(*this, d3, Q, IRT_LQ, 1, opt.icl());
      count(*this, d4, Q, IRT_LQ, 1, opt.icl());
      if (opt.propagation() == PROP_DECOMPOSE) {
        count(*this, d1, B, IRT_LQ, 1, opt.icl());
        count(*this, d2, B, IRT_LQ, 1, opt.icl());
        count(*this, d3, B, IRT_LQ, 1, opt.icl());
        count(*this, d4, B, IRT_LQ, 1, opt.icl());
      }
    }
    if (opt.propagation() == PROP_TUPLE_SET) {
      IntVarArgs b(s.size());
      for (int i = s.size(); i--; )
        b[i] = channel(*this, expr(*this, (s[i] == B)));
      extensional(*this, b, bishops, EPK_DEF, opt.icl());
    }

    // Handle knigths
    // Connect knigths to board
    for(int i = n*n; i--; )
      knights[i] = expr(*this, (s[i] == K));
    knight_constraints();


    // ***********************
    // Redundant constraints
    // ***********************

    // Queens and rooks not in the same place
    // Faster than going through the channelled board-connection
    for (int i = n; i--; )
      rel(*this, queens[i], IRT_NQ, rooks[i]);

    // Place bishops in two corners (from Schimpf and Hansens solution)
    // Avoids some symmetries of the problem
    rel(*this, m(n-1,   0), IRT_EQ, B);
    rel(*this, m(n-1, n-1), IRT_EQ, B);


    // ***********************
    // Branching
    // ***********************
    // Place each piece in turn
    branch(*this, s, INT_VAR_MIN_MIN(), INT_VAL_MIN());
  }
Пример #22
0
  // Actual model
  Strimko(const SizeOptions& opt) : 
    prob(problems[opt.size()]),
    x(*this, prob_size()*prob_size(), 1, prob_size())
  {

    int n = prob_size();
    std::cout << "Problem " << opt.size() << " size: " << n << std::endl;

    //
    // get data for this problem
    //
    int s = 1; // we have already taken n (the size)

    // streams
    int streams[n*n];
    std::cout << "streams: " << std::endl;
    for(int i = 0; i < n; i++) {
      for(int j = 0; j < n; j++) {
        streams[i*n+j] = prob[s++];
        std::cout << streams[i*n+j] << " ";        
      }
      std::cout << std::endl;
    }
    
    // placed
    int num_placed = prob[s++];// 5;
    int placed[num_placed*3];
    std::cout << "\nplaced: " << std::endl;
    for(int i = 0; i < num_placed; i++) {
      for(int j = 0; j < 3; j++) {
        placed[i*3+j] = prob[s++];
        std::cout << placed[i*3+j] << " " ;
      }
      std::cout << std::endl;
    }
    std::cout << std::endl;

    Matrix<IntVarArray> x_m(x, n, n);

    /*
     *
     * Constraints
     *
     */

    //
    // Latin Square
    //
    for (int i = 0; i < n; i++) {
      distinct(*this, x_m.row(i), opt.icl());
      distinct(*this, x_m.col(i), opt.icl());
    }

    //
    // Streams
    //
    for(int st = 1; st <= n; st++) {
      IntVarArgs stream;
      for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
          if (streams[i*n+j] == st) {
            // stream << x[i*n+j]; // direct on x
            stream << x_m(j,i); // matrix access
          }
        }
      }
      distinct(*this, stream, opt.icl());
    }

    //
    // Placed hints
    //
    for(int i = 0; i < num_placed; i++) {
      int pi  = placed[i*3]-1;
      int pi1 = placed[i*3+1]-1;
      int pi2 = placed[i*3+2];
      // rel(*this, x[pi*n+pi1] == pi2, opt.icl()); // direct on x
      rel(*this, x_m(pi1,pi) == pi2, opt.icl()); // matrix access
    }

    branch(*this, x, INT_VAR_SIZE_MIN(), INT_VAL_MIN());

  }
Пример #23
0
  /// Actual model
  AllInterval(const SizeOptions& opt) :
  	Script(opt),
    x(*this, opt.size(), 0, 66) { // 66 or opt.size() - 1
		const int n = x.size();
		
		IntVarArgs d(n-1);
		IntVarArgs dd(66);
		IntVarArgs xx_(n); // pitch class for AllInterval Chords 
		IntVar douze;
        Rnd r(1U);
		
	if ((opt.model() == MODEL_SET) || (opt.model() == MODEL_SET_CHORD) || (opt.model() == MODEL_SSET_CHORD) ||(opt.model() == MODEL_SYMMETRIC_SET)) // Modele original : serie
		{
			// Set up variables for distance
			for (int i=0; i<n-1; i++)
				d[i] = expr(*this, abs(x[i+1]-x[i]), opt.ipl());
			
			// Constrain them to be between 1 and n-1
			dom(*this, d, 1, n-1); 
			dom(*this, x, 0, n-1); 
			
			if((opt.model() == MODEL_SET_CHORD) || (opt.model() == MODEL_SSET_CHORD))
			{
				/*expr(*this,dd[0]==0);
				// Set up variables for distance
				for (int i=0; i<n-1; i++)
				{
					 expr(*this, dd[i+1] == (dd[i]+d[i])%12, opt.icl());
				}
				
				// Constrain them to be between 1 and n-1
				dom(*this, dd,0, n-1); 
				distinct(*this, dd, opt.icl());
				 */
				
				rel(*this, abs(x[0]-x[n-1]) == 6, opt.ipl());
				
				
			}
		 
			
			if(opt.symmetry())
			{
				// Break mirror symmetry (renversement)
				rel(*this, x[0], IRT_LE, x[1]);
				// Break symmetry of dual solution (retrograde de la serie) -> 1928 solutions pour accords de 12 sons
				rel(*this, d[0], IRT_GR, d[n-2]);
			}
			//series symetriques
			if ((opt.model() == MODEL_SYMMETRIC_SET)|| (opt.model() == MODEL_SSET_CHORD))
			{
				rel (*this, d[n/2 - 1] == 6); // pivot = triton
				for (int i=0; i<(n/2)-2; i++)
					rel(*this,d[i]+d[n-i-2]==12);
			}
		}
				
else 			
		{
			for (int j=0; j<n; j++)
				xx_[j] = expr(*this, x[j] % 12);
			
			dom(*this, xx_, 0, 11);
			distinct(*this, xx_, opt.ipl());
			
			//intervalles
			for (int i=0; i<n-1; i++)
				d[i] =  expr(*this,x[i+1] - x[i],opt.ipl());
			dom(*this, d, 1, n-1); 
			
			
			dom(*this, x, 0, n * (n - 1) / 2.); 
			
			//d'autres choses dont on est certain (contraintes redondantes) :
			
			rel(*this, x[0] == 0);
			rel(*this, x[n-1] ==  n * (n - 1) / 2.);
			
			//  break symmetry of dual solution (renversement de l'accord) 
			if(opt.symmetry())
				rel(*this, d[0], IRT_GR, d[n-2]);
			
			//accords symetriques
			if (opt.model() == MODEL_SYMMETRIC_CHORD)
			{
				rel (*this, d[n/2 - 1] == 6); // pivot = triton
				for (int i=0; i<(n/2)-2; i++)
					rel(*this,d[i]+d[n-i-2]==12);
			}
			if (opt.model() == MODEL_PARALLEL_CHORD)
			{
				rel (*this, d[n/2 - 1] == 6); // pivot = triton
				for (int i=0; i<(n/2)-2; i++)
					rel(*this,d[i]+d[n/2 + i]==12);
			}
		}

		distinct(*this, x, opt.ipl());
		distinct(*this, d, opt.ipl());
#if 0		
		//TEST
		IntVarArray counter(*this,12,0,250);
		IntVar testcounter(*this,0,250);
		
		for (int i=1; i<11; i++) {
			count(*this, d, i,IRT_EQ,testcounter,opt.icl()); // OK
		}
		
		count(*this, d, counter,opt.icl()); // OK
#endif
		//END TEST
		
		if(opt.branching() == 0)
			branch(*this, x, INT_VAR_SIZE_MIN(), INT_VAL_SPLIT_MIN());
		else 
			branch(*this, x, INT_VAR_RND(r), INT_VAL_RND(r));		
	}
Пример #24
0
  // Actual model
  Speakers(const SizeOptions& opt) : 
    x(*this, n, 1, n)
  {

    //
    // available slots:
    //

    /*
    // First solution: populate from a integer array 
    // where the first number represents the number of items
    int __available[] = {
    // size: available  // Reasoning. Step# : reason
      4,  3,4,5,6,      // #2: the only one with 6 after speaker F -> 1
      2,  3,4,          // #5: 3 or 4
      4,  2,3,4,5,      // #3: only with 5 after F -> 1 and A -> 6
      3,  2,3,4,        // #4: only with 2 after C -> 5 and F -> 1 
      2,  3,4,          // #5: 3 or 4
      6,  1,2,3,4,5,6   // #1: the only with 1
    };

    // convert to IntSet
    IntSet _available[n];
    int s = 0;
    for(int i = 0; i < n; i++) {
      int num = __available[s++];
      IntArgs tmp;
      for(int j = 0; j < num; j++) {
        tmp << __available[s++];
      }
      _available[i] = IntSet(tmp);
    }
    // and then to IntSetArgs
    IntSetArgs available(n, _available);
    */

    //
    // Oh, this is much easier, at least for this small example
    //
    IntSetArgs available(n);
    available[0] = IntSet( IntArgs() << 3 << 4 << 5 << 6 );
    available[1] = IntSet( IntArgs() << 3 << 4 );
    available[2] = IntSet( IntArgs() << 2 << 3 << 4 << 5 );
    available[3] = IntSet( IntArgs() << 2 << 3 << 4 );
    available[4] = IntSet( IntArgs() << 3 << 4 );
    available[5] = IntSet( IntArgs() << 1 << 2 << 3 << 4 << 5 << 6 );

    distinct(*this, x, opt.icl());

    for(int i = 0; i < n; i++) {
      // From Modeling and Programming in Gecode, 
      // section 5.2.2, Relation constraints:
      // """
      // If x is a set variable and y is an integer variable, then
      //     rel(home, x, SRT_SUP, y);
      // constrains x to be a superset of the singleton set {y}, 
      // which means that y must be an element of x.
      // """
      // 
      // corresponds to: forall(i in 1..n) (x[i] in available[i])
      //
      // rel(*this, SetVar(*this, available[i],available[i]), SRT_SUP, x[i]);
      // this is easier:
      rel(*this, singleton(x[i]) <= available[i]);
    }

    branch(*this, x, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
    
  }
Пример #25
0
  /// The actual model
  GraphColor(const SizeOptions& opt)
    : IntMinimizeScript(opt),
      g(opt.size() == 1 ? g2 : g1),
      v(*this,g.n_v,0,g.n_v-1),
      m(*this,0,g.n_v-1) {
    rel(*this, v, IRT_LQ, m);
    for (int i = 0; g.e[i] != -1; i += 2)
      rel(*this, v[g.e[i]], IRT_NQ, v[g.e[i+1]]);

    const int* c = g.c;
    for (int i = *c++; i--; c++)
      rel(*this, v[*c], IRT_EQ, i);
    while (*c != -1) {
      int n = *c;
      IntVarArgs x(n); c++;
      for (int i = n; i--; c++)
        x[i] = v[*c];
      distinct(*this, x, opt.icl());
      if (opt.model() == MODEL_CLIQUE)
        rel(*this, m, IRT_GQ, n-1);
    }
    /// Branching on the number of colors
    branch(*this, m, INT_VAL_MIN());
    if (opt.symmetry() == SYMMETRY_NONE) {
       /// Branching without symmetry breaking
       switch (opt.branching()) {
          case BRANCH_SIZE:
             branch(*this, v, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
             break;
          case BRANCH_DEGREE:
             branch(*this, v, tiebreak(INT_VAR_DEGREE_MAX(),INT_VAR_SIZE_MIN()),
                   INT_VAL_MIN());
             break;
          case BRANCH_SIZE_DEGREE:
             branch(*this, v, INT_VAR_DEGREE_SIZE_MAX(), INT_VAL_MIN());
             break;
          case BRANCH_SIZE_AFC:
             branch(*this, v, INT_VAR_AFC_SIZE_MAX(opt.decay()), INT_VAL_MIN());
             break;
          case BRANCH_SIZE_ACTIVITY:
             branch(*this, v, INT_VAR_ACTIVITY_SIZE_MAX(opt.decay()), INT_VAL_MIN());
             break;
          default:
             break;
       }
    } else { // opt.symmetry() == SYMMETRY_LDSB
       /// Branching while considering value symmetry breaking
       /// (every permutation of color values gives equivalent solutions)
       Symmetries syms;
       syms << ValueSymmetry(IntArgs::create(g.n_v,0));
       switch (opt.branching()) {
          case BRANCH_SIZE:
             branch(*this, v, INT_VAR_SIZE_MIN(), INT_VAL_MIN(), syms);
             break;
          case BRANCH_DEGREE:
             branch(*this, v, tiebreak(INT_VAR_DEGREE_MAX(),INT_VAR_SIZE_MIN()),
                   INT_VAL_MIN(), syms);
             break;
          case BRANCH_SIZE_DEGREE:
             branch(*this, v, INT_VAR_DEGREE_SIZE_MAX(), INT_VAL_MIN(), syms);
             break;
          case BRANCH_SIZE_AFC:
             branch(*this, v, INT_VAR_AFC_SIZE_MAX(opt.decay()), INT_VAL_MIN(), syms);
             break;
          case BRANCH_SIZE_ACTIVITY:
             branch(*this, v, INT_VAR_ACTIVITY_SIZE_MAX(opt.decay()), INT_VAL_MIN(), syms);
             break;
          default:
             break;
       }
    }
  }
Пример #26
0
  DriveYaNuts(const SizeOptions& opt) 
  : 
    x(*this, m*n, 1, n),
    pos(*this, m, 0, m-1),
    pos_inv(*this, m, 0, m-1),
    start_ix(*this, m, 0, n-1)
  {


    // data

    // in base 1 (fixed below)
    int _connections[] =  {  
      //nuts    sides to be equal
      1,2,       3,6,
      2,3,       4,1,
      3,4,       5,2,
      4,5,       6,3,
      5,6,       1,4,
      6,1,       2,5,
      
      7,1,       1,4,
      7,2,       2,5,
      7,3,       3,6,
      7,4,       4,1,
      7,5,       5,2,
      7,6,       6,3,
    };
    
    IntArgs connections(num_connections*4, _connections);

    // This is the nuts in the solution order.
    // 1,4,6,2,3,5, 1,4,6,2,3,5, // 1 
    // 1,6,5,3,2,4, 1,6,5,3,2,4, // 2 
    // 1,4,3,6,5,2, 1,4,3,6,5,2, // 3
    // 1,2,3,4,5,6, 1,2,3,4,5,6, // 4
    // 1,6,4,2,5,3, 1,6,4,2,5,3, // 5
    // 1,6,5,4,3,2, 1,6,5,4,3,2, // 6 
    // 1,6,2,4,5,3, 1,6,2,4,5,3, // 7 // center nut
    

    // Note that pos_inv for the shown solution is the permutation 
    // [4,3,1,7,5,2,6]
    int _nuts[] = {
      1,2,3,4,5,6, 1,2,3,4,5,6, // 4 (row 4 in the solution order)
      1,4,3,6,5,2, 1,4,3,6,5,2, // 3
      1,4,6,2,3,5, 1,4,6,2,3,5, // 1 
      1,6,2,4,5,3, 1,6,2,4,5,3, // 7 [center nut]
      1,6,4,2,5,3, 1,6,4,2,5,3, // 5
      1,6,5,3,2,4, 1,6,5,3,2,4, // 2 
      1,6,5,4,3,2, 1,6,5,4,3,2, // 6 
    };

    IntArgs nuts1(m*n*2, _nuts);
    Matrix<IntArgs> nuts(nuts1, n*2, m);


    Matrix<IntVarArray> xm(x, n, m);

    for(int i = 0; i < m; i++) {
      distinct(*this, xm.row(i), opt.icl());

      IntVar k(*this, 0, n-1);
      IntVar p(*this, 0, m-1);

      rel(*this, start_ix[i] == k);
      rel(*this, pos[i] == p);

      for(int j = 0; j < n; j++) {
        // x[i,j] == nuts[p, j+k]
   
        // Using matrix element
        IntVar jk(*this, 0, n*2-1);
        rel(*this, jk == j+k);
        element(*this, nuts, jk, p, xm(j,i));

        // Using plain element
        /*
        IntVar pjk(*this, 0, 2*n*m);
        rel(*this, pjk == p*n*2+j+k);
        element(*this, nuts1, pjk, xm(j,i));
        */

      }
    }

    distinct(*this, pos, opt.icl());
    channel(*this, pos, pos_inv);

    // check the connections
    for(int c = 0; c < num_connections; c++) {
      // note: xm(col, row)
      rel(*this, 
          xm(connections[c*4+2]-1,connections[c*4+0]-1) ==
          xm(connections[c*4+3]-1,connections[c*4+1]-1));
    }

    // symmetry breaking:
    // We pick the solution where the center nut (nut 7) start with 1.
    rel(*this, start_ix[m-1] == 0);


    branch(*this, pos, INT_VAR_SIZE_MIN(), INT_VAL_SPLIT_MIN()); 
    branch(*this, x, INT_VAR_SIZE_MIN(), INT_VAL_MIN()); 
    branch(*this, start_ix, INT_VAR_SIZE_MIN(), INT_VAL_MIN()); 

  }
Пример #27
0
  /// Actual model
  Calculs(const SizeOptions& opt) : 
    X(*this, N, -N, N),
    X_abs(*this, N, 0, N),
    x_max(*this, 0, N),
    show_all(opt.size())
  {

    IntVar
      a(X[ 0]), b(X[ 1]), c(X[ 2]), e(X[ 4]), f(X[ 5]),
      g(X[ 6]), h(X[ 7]), i(X[ 8]), j(X[ 9]), k(X[10]),
      l(X[11]), m(X[12]), n(X[13]), o(X[14]), p(X[15]),
      q(X[16]), r(X[17]), s(X[18]), t(X[19]), u(X[20]),
      v(X[21]), w(X[22]), x(X[23]), y(X[24]), z(X[25]);


    // x_max is the max value of abs(X)   
    for(int i = 0; i < N; i++)  {
      abs(*this, X[i], X_abs[i], opt.icl());
    }
    max(*this, X_abs, x_max, opt.icl());

    rel(*this, z+e+r+o     == 0, opt.icl());
    rel(*this, o+n+e       == 1, opt.icl());
    rel(*this, t+w+o       == 2, opt.icl());
    rel(*this, t+h+r+e+e   == 3, opt.icl());
    rel(*this, f+o+u+r     == 4, opt.icl());
    rel(*this, f+i+v+e     == 5, opt.icl());
    rel(*this, s+i+x       == 6, opt.icl());
    rel(*this, s+e+v+e+n   == 7, opt.icl());
    rel(*this, e+i+g+h+t   == 8, opt.icl());
    rel(*this, n+i+n+e     == 9, opt.icl());
    rel(*this, t+e+n       == 10, opt.icl());
    rel(*this, e+l+e+v+e+n == 11, opt.icl());
    rel(*this, t+w+e+l+f   == 12, opt.icl());

    distinct(*this, X, opt.icl());

    // for showing all solutions (there are many)
    if (show_all) {
      rel(*this, x_max == 16, opt.icl());
    }

    branch(*this, X, INT_VAR_DEGREE_MAX(), INT_VAL_MIN());

  }