Пример #1
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());
    }
  }
Пример #2
0
  /// Constructor
  QueenArmies(const SizeOptions& opt) :
    n(opt.size()),
    U(*this, IntSet::empty, IntSet(0, n*n)),
    W(*this, IntSet::empty, IntSet(0, n*n)),
    w(*this, n*n, 0, 1),
    b(*this, n*n, 0, 1),
    q(*this, 0, n*n)
  {
    // Basic rules of the model
    for (int i = n*n; i--; ) {
      // w[i] means that no blacks are allowed on A[i]
      rel(*this, w[i] == (U || A[i]));
      // Make sure blacks and whites are disjoint.
      rel(*this, !w[i] || !b[i]);
      // If i in U, then b[i] has a piece.
      rel(*this, b[i] == (singleton(i) <= U));
    }

    // Connect optimization variable to number of pieces
    linear(*this, w, IRT_EQ, q);
    linear(*this, b, IRT_GQ, q);

    // Connect cardinality of U to the number of black pieces.
    IntVar unknowns = expr(*this, cardinality(U));
    rel(*this, q <= unknowns);
    linear(*this, b, IRT_EQ, unknowns);

    if (opt.branching() == BRANCH_NAIVE) {
      branch(*this, w, INT_VAR_NONE, INT_VAL_MAX);
      branch(*this, b, INT_VAR_NONE, INT_VAL_MAX);
    } else {
      QueenBranch::post(*this);
      assign(*this, b, INT_ASSIGN_MAX);
    }
  }
Пример #3
0
  /// Actual model
  WordSquare(const SizeOptions& opt)
    : w_l(opt.size()), letters(*this, w_l*w_l) {

    // Initialize letters
    Matrix<IntVarArray> ml(letters, w_l, w_l);
    for (int i=0; i<w_l; i++)
      for (int j=i; j<w_l; j++)
        ml(i,j) = ml(j,i) = IntVar(*this, 'a','z');
    
    // Number of words with that length
    const int n_w = dict.words(w_l);

    // Initialize word array
    IntVarArgs words(*this, w_l, 0, n_w-1);

    // All words must be different
    distinct(*this, words);

    // Link words with letters
    for (int i=0; i<w_l; i++) {
      // Map each word to i-th letter in that word
      IntSharedArray w2l(n_w);
      for (int n=n_w; n--; )
        w2l[n]=dict.word(w_l,n)[i];
      for (int j=0; j<w_l; j++)
        element(*this, w2l, words[j], ml(i,j));
    }

    // Symmetry breaking: the last word must be later in the wordlist
    rel(*this, words[0], IRT_LE, words[w_l-1]);

    switch (opt.branching()) {
    case BRANCH_WORDS:
      // Branch by assigning words
      branch(*this, words, INT_VAR_SIZE_MIN(), INT_VAL_SPLIT_MIN());
      break;
    case BRANCH_LETTERS:
      // Branch by assigning letters
      branch(*this, letters, INT_VAR_AFC_SIZE_MAX(opt.decay()), INT_VAL_MIN());
      break;
    }
  }
Пример #4
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;
   }
 }
Пример #5
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;
    }
  }
Пример #6
0
	SUSHI_EQUATION(const SizeOptions& opt)
	: n_x(*this, 1, wordlength),
    n_y(*this, 1, wordlength),
    n_z(*this, 1, wordlength),
    n_t(*this, opt.size()+1, opt.size()+1),
	  X(*this, wordlength , val_dom_min, val_dom_max),
    Y(*this, wordlength , val_dom_min, val_dom_max),
    Z(*this, wordlength , val_dom_min, val_dom_max),
    T(*this, opt.size()+1 , val_dom_min, val_dom_max){

      int n = opt.size();
		gecode_find_solution = false;

		REG r_a(1);
    REG r_b(2);
		REG dum(dummy_sym);
		REG reg_z = r_b(n,n) + r_a + r_b(n,n);
    if (opt.propagation() == PROP_PAD) {
      reg_z += (*dum);
    }
    

	  DFA myDFA_z(reg_z);

    // T = "a" . Y[0,n]
    rel(*this, T[0]==1);
    for (int i = 0; (i < n) && (i+1 < T.size()); i++){
      T[i+1] = Y[i];
    }
    rel(*this, n_y >= n);
    
    switch(opt.propagation()){
      case PROP_OPEN:
        extensional(*this, Z, myDFA_z, n_z);
  	    //concat(*this, X, n_x, T, n_t, Z, n_z, ICL_BND);
        rel(*this, n_z == (n_x+n_t));
        
        for(int i=0; i<wordlength; i++)
        {
          rel(*this, (i<n_x) >> (X[i]==Z[i]));
        
          BoolVar b = expr(*this, i==n_x);
        
          for(int j=0; (i+j)<wordlength; j++)
          {
            rel(*this, (b&&(j<n_t)) >> (T[j]==Z[i+j]));
          }
        }
        break;
      case PROP_CLOSED:
        extensional(*this, Z, myDFA_z);
        rel(*this, n_z == (n_x+n_t));
        rel(*this, n_y == wordlength);
  	    for(int i=0; i<wordlength; i++)
  	    {
  	    	rel(*this, (i<n_x) >> (X[i]==Z[i]));

  	    	BoolVar b = expr(*this, i==n_x);

  	    	for(int j=0; (j < T.size()) && ((i+j)<wordlength); j++)
  	    	{
  	    		rel(*this, (b&&(j<n_t)) >> (T[j]==Z[i+j]));
  	    	}
  	    }
        break;
      case PROP_PAD:
        extensional(*this, Z, myDFA_z);
  	    for(int i=0; i<wordlength; i++)
  	    {
  	    	rel(*this, (Z[i]==dummy_sym) == (n_z<=i));
  	    	rel(*this, (Y[i]==dummy_sym) == (n_y<=i));
  	    	rel(*this, (X[i]==dummy_sym) == (n_x<=i));
  	    }

  	    rel(*this, n_z == (n_x+n_t));

  	    for(int i=0; i<wordlength; i++)
  	    {
  	    	rel(*this, (i<n_x) >> (X[i]==Z[i]));

  	    	BoolVar b = expr(*this, i==n_x);

  	    	for(int j=0; (j < T.size()) && ((i+j)<wordlength); j++)
  	    	{
  	    		rel(*this, (b&&(j<n_t)) >> (T[j]==Z[i+j]));
  	    	}
  	    }
        break;
    }
	  
    IntVarArgs lengths;
		lengths << n_z << n_x << n_y;
		
    switch(opt.branching()){
    case BRANCH_N_A:
      branch(*this, lengths, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
      branch(*this, Z, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
		  branch(*this, X, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
      branch(*this, Y, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
      break;
    case BRANCH_A_N:
      branch(*this, Z, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
	    branch(*this, X, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
      branch(*this, Y, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
      branch(*this, lengths, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
      break;
    case BRANCH_BOUND:
      boundednone(*this, Z, n_z);
      boundednone(*this, X, n_x);
      boundednone(*this, Y, n_y);
      break;
    }
	}
Пример #7
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));		
	}
Пример #8
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;
       }
    }
  }
Пример #9
0
  /// Construction of the model.
  Nonogram(const SizeOptions& opt)
    : spec(specs[opt.size()]), b(*this,width()*height(),0,1) {
    Matrix<BoolVarArray> m(b, width(), height());

    {
      int spos = 2;
      // Post constraints for columns
      for (int w=0; w<width(); w++)
        extensional(*this, m.col(w), line(spos));
      // Post constraints for rows
      for (int h=0; h<height(); h++)
        extensional(*this, m.row(h), line(spos));
    }

    

    switch (opt.branching()) {
    case BRANCH_NONE:
      {
        /*
         * The following branches either by columns or rows, depending on
         * whether there are more hints relative to the height or width
         * for columns or rows.
         *
         * This idea is due to Pascal Van Hentenryck and has been suggested
         * to us by Hakan Kjellerstrand.
         */

        // Number of hints for columns
        int cols = 0;
        // Number of hints for rows
        int rows = 0;
        int spos = 2;
        for (int w=0; w<width(); w++) {
          int hint = spec[spos++];
          cols += hint; spos += hint;
        }
        for (int h=0; h<height(); h++) {
          int hint = spec[spos++];
          rows += hint; spos += hint;
        }
        
        if (rows*width() > cols*height()) {
          for (int w=0; w<width(); w++)
            branch(*this, m.col(w), INT_VAR_NONE, INT_VAL_MAX);
        } else {
          for (int h=0; h<height(); h++)
            branch(*this, m.row(h), INT_VAR_NONE, INT_VAL_MAX);
        }
      }
      break;
    case BRANCH_AFC:
      /*
       * The following just uses the AFC for branching. This is
       * equivalent to SIZE/AFC in this case since the variables are
       * binary.
       */
      branch(*this, b, INT_VAR_AFC_MAX, INT_VAL_MAX);
      break;
    }
  }