예제 #1
0
    /**
     *
     * Solve the SEND+MORE=MONEY problem
     * using scalar product.
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("SendMoreMoney");

        //
        // Decision variables
        //
        IntVar S = solver.MakeIntVar(0, 9, "S");
        IntVar E = solver.MakeIntVar(0, 9, "E");
        IntVar N = solver.MakeIntVar(0, 9, "N");
        IntVar D = solver.MakeIntVar(0, 9, "D");
        IntVar M = solver.MakeIntVar(0, 9, "M");
        IntVar O = solver.MakeIntVar(0, 9, "O");
        IntVar R = solver.MakeIntVar(0, 9, "R");
        IntVar Y = solver.MakeIntVar(0, 9, "Y");

        // for AllDifferent()
        IntVar[] x = new IntVar[] { S, E, N, D, M, O, R, Y };

        //
        // Constraints
        //
        solver.Add(x.AllDifferent());

        /*
         * solver.Add(S*1000 + E*100 + N*10 + D + M*1000 + O*100 + R*10 + E ==
         *         M*10000 + O*1000 + N*100 + E*10 + Y);
         */

        // Here we use scalar product instead.
        int[] s1 = new int[] { 1000, 100, 10, 1 };
        int[] s2 = new int[] { 10000, 1000, 100, 10, 1 };
        solver.Add(new IntVar[] { S, E, N, D }.ScalProd(s1) + new IntVar[] { M, O, R, E }.ScalProd(s1) ==
                   new IntVar[] { M, O, N, E, Y }.ScalProd(s2));

        solver.Add(S > 0);
        solver.Add(M > 0);

        //
        // Search
        //
        DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);

        solver.NewSearch(db);
        while (solver.NextSolution())
        {
            for (int i = 0; i < 8; i++)
            {
                Console.Write(x[i].Value() + " ");
            }
            Console.WriteLine();
        }

        Console.WriteLine("\nSolutions: {0}", solver.Solutions());
        Console.WriteLine("WallTime: {0}ms", solver.WallTime());
        Console.WriteLine("Failures: {0}", solver.Failures());
        Console.WriteLine("Branches: {0}", solver.Branches());

        solver.EndSearch();
    }
예제 #2
0
  /**
   *
   * Solve the Least diff problem
   * For more info, see http://www.hakank.org/google_or_tools/least_diff.py
   *
   */
  private static void Solve()
  {
    Solver solver = new Solver("LeastDiff");

    //
    // Decision variables
    //
    IntVar A = solver.MakeIntVar(0, 9, "A");
    IntVar B = solver.MakeIntVar(0, 9, "B");
    IntVar C = solver.MakeIntVar(0, 9, "C");
    IntVar D = solver.MakeIntVar(0, 9, "D");
    IntVar E = solver.MakeIntVar(0, 9, "E");
    IntVar F = solver.MakeIntVar(0, 9, "F");
    IntVar G = solver.MakeIntVar(0, 9, "G");
    IntVar H = solver.MakeIntVar(0, 9, "H");
    IntVar I = solver.MakeIntVar(0, 9, "I");
    IntVar J = solver.MakeIntVar(0, 9, "J");

    IntVar[] all = new IntVar[] {A,B,C,D,E,F,G,H,I,J};
    int[] coeffs = {10000,1000,100,10,1};
    IntVar x = new IntVar[]{A,B,C,D,E}.ScalProd(coeffs).Var();
    IntVar y = new IntVar[]{F,G,H,I,J}.ScalProd(coeffs).Var();
    IntVar diff = (x - y).VarWithName("diff");


    //
    // Constraints
    //
    solver.Add(all.AllDifferent());
    solver.Add(A > 0);
    solver.Add(F > 0);
    solver.Add(diff > 0);


    //
    // Objective
    //
    OptimizeVar obj = diff.Minimize(1);

    //
    // Search
    //
    DecisionBuilder db = solver.MakePhase(all,
                                          Solver.CHOOSE_PATH,
                                          Solver.ASSIGN_MIN_VALUE);

    solver.NewSearch(db, obj);
    while (solver.NextSolution()) {
      Console.WriteLine("{0} - {1} = {2}  ({3}",x.Value(), y.Value(), diff.Value(), diff.ToString());
    }

    Console.WriteLine("\nSolutions: {0}", solver.Solutions());
    Console.WriteLine("WallTime: {0}ms", solver.WallTime());
    Console.WriteLine("Failures: {0}", solver.Failures());
    Console.WriteLine("Branches: {0} ", solver.Branches());

    solver.EndSearch();

  }
예제 #3
0
    /**
     *
     * Solve the Least diff problem
     * For more info, see http://www.hakank.org/google_or_tools/least_diff.py
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("LeastDiff");

        //
        // Decision variables
        //
        IntVar A = solver.MakeIntVar(0, 9, "A");
        IntVar B = solver.MakeIntVar(0, 9, "B");
        IntVar C = solver.MakeIntVar(0, 9, "C");
        IntVar D = solver.MakeIntVar(0, 9, "D");
        IntVar E = solver.MakeIntVar(0, 9, "E");
        IntVar F = solver.MakeIntVar(0, 9, "F");
        IntVar G = solver.MakeIntVar(0, 9, "G");
        IntVar H = solver.MakeIntVar(0, 9, "H");
        IntVar I = solver.MakeIntVar(0, 9, "I");
        IntVar J = solver.MakeIntVar(0, 9, "J");

        IntVar[] all = new IntVar[] { A, B, C, D, E, F, G, H, I, J };
        int[]    coeffs = { 10000, 1000, 100, 10, 1 };
        IntVar   x = new IntVar[] { A, B, C, D, E }.ScalProd(coeffs).Var();
        IntVar   y = new IntVar[] { F, G, H, I, J }.ScalProd(coeffs).Var();
        IntVar   diff = (x - y).VarWithName("diff");


        //
        // Constraints
        //
        solver.Add(all.AllDifferent());
        solver.Add(A > 0);
        solver.Add(F > 0);
        solver.Add(diff > 0);


        //
        // Objective
        //
        OptimizeVar obj = diff.Minimize(1);

        //
        // Search
        //
        DecisionBuilder db = solver.MakePhase(all,
                                              Solver.CHOOSE_PATH,
                                              Solver.ASSIGN_MIN_VALUE);

        solver.NewSearch(db, obj);
        while (solver.NextSolution())
        {
            Console.WriteLine("{0} - {1} = {2}  ({3}", x.Value(), y.Value(), diff.Value(), diff.ToString());
        }

        Console.WriteLine("\nSolutions: {0}", solver.Solutions());
        Console.WriteLine("WallTime: {0}ms", solver.WallTime());
        Console.WriteLine("Failures: {0}", solver.Failures());
        Console.WriteLine("Branches: {0} ", solver.Branches());

        solver.EndSearch();
    }
예제 #4
0
    //  We don't need helper functions here
    //  Csharp syntax is easier than C++ syntax!

    private static void CPisFun (int kBase)
    {
        //  Constraint Programming engine
        Solver solver = new Solver ("CP is fun!");

        // Decision variables
        IntVar c = solver.MakeIntVar (1, kBase - 1, "C");
        IntVar p = solver.MakeIntVar (0, kBase - 1, "P");
        IntVar i = solver.MakeIntVar (1, kBase - 1, "I");
        IntVar s = solver.MakeIntVar (0, kBase - 1, "S");
        IntVar f = solver.MakeIntVar (1, kBase - 1, "F");
        IntVar u = solver.MakeIntVar (0, kBase - 1, "U");
        IntVar n = solver.MakeIntVar (0, kBase - 1, "N");
        IntVar t = solver.MakeIntVar (1, kBase - 1, "T");
        IntVar r = solver.MakeIntVar (0, kBase - 1, "R");
        IntVar e = solver.MakeIntVar (0, kBase - 1, "E");

        // We need to group variables in a vector to be able to use
        // the global constraint AllDifferent
        IntVar[] letters = new IntVar[] { c, p, i, s, f, u, n, t, r, e};

        // Check if we have enough digits
        if (kBase < letters.Length) {
          throw new Exception("kBase < letters.Length");
        }

        //  Constraints
        solver.Add (letters.AllDifferent ());

        // CP + IS + FUN = TRUE
        solver.Add (p + s + n + kBase * (c + i + u) + kBase * kBase * f ==
               e + kBase * u + kBase * kBase * r + kBase * kBase * kBase * t);

        SolutionCollector all_solutions = solver.MakeAllSolutionCollector();
        //  Add the interesting variables to the SolutionCollector
        all_solutions.Add(c);
        all_solutions.Add(p);
        //  Create the variable kBase * c + p
        IntVar v1 = solver.MakeSum(solver.MakeProd(c, kBase), p).Var();
        //  Add it to the SolutionCollector
        all_solutions.Add(v1);

        //  Decision Builder: hot to scour the search tree
        DecisionBuilder db = solver.MakePhase (letters,
                                               Solver.CHOOSE_FIRST_UNBOUND,
                                               Solver.ASSIGN_MIN_VALUE);
        solver.Solve(db, all_solutions);

        //  Retrieve the solutions
        int numberSolutions = all_solutions.SolutionCount();
        Console.WriteLine ("Number of solutions: " + numberSolutions);

        for (int index = 0; index < numberSolutions; ++index) {
            Assignment solution = all_solutions.Solution(index);
            Console.WriteLine ("Solution found:");
            Console.WriteLine ("v1=" + solution.Value(v1));
        }
    }
예제 #5
0
    /**
     *
     * Solve the SEND+MORE=MONEY problem
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("SendMoreMoney");

        //
        // Decision variables
        //
        IntVar S = solver.MakeIntVar(0, 9, "S");
        IntVar E = solver.MakeIntVar(0, 9, "E");
        IntVar N = solver.MakeIntVar(0, 9, "N");
        IntVar D = solver.MakeIntVar(0, 9, "D");
        IntVar M = solver.MakeIntVar(0, 9, "M");
        IntVar O = solver.MakeIntVar(0, 9, "O");
        IntVar R = solver.MakeIntVar(0, 9, "R");
        IntVar Y = solver.MakeIntVar(0, 9, "Y");

        // for AllDifferent()
        IntVar[] x = new IntVar[] { S, E, N, D, M, O, R, Y };

        //
        // Constraints
        //
        solver.Add(x.AllDifferent());
        solver.Add(S * 1000 + E * 100 + N * 10 + D + M * 1000 + O * 100 + R * 10 + E ==
                   M * 10000 + O * 1000 + N * 100 + E * 10 + Y);

        solver.Add(S > 0);
        solver.Add(M > 0);

        //
        // Search
        //
        DecisionBuilder db = solver.MakePhase(x,
                                              Solver.CHOOSE_FIRST_UNBOUND,
                                              Solver.ASSIGN_MIN_VALUE);

        solver.NewSearch(db);
        while (solver.NextSolution())
        {
            for (int i = 0; i < 8; i++)
            {
                Console.Write(x[i].ToString() + " ");
            }
            Console.WriteLine();
        }

        Console.WriteLine("\nWallTime: " + solver.WallTime() + "ms ");
        Console.WriteLine("Failures: " + solver.Failures());
        Console.WriteLine("Branches: " + solver.Branches());

        solver.EndSearch();
    }
        public void doWork()
        {
            Solver solver = new Solver("Cryptogram");

            // One decision variable for each character:
            IntVar S = solver.MakeIntVar(0, 9);
            IntVar E = solver.MakeIntVar(0, 9);
            IntVar N = solver.MakeIntVar(0, 9);
            IntVar D = solver.MakeIntVar(0, 9);
            IntVar M = solver.MakeIntVar(0, 9);
            IntVar O = solver.MakeIntVar(0, 9);
            IntVar R = solver.MakeIntVar(0, 9);
            IntVar Y = solver.MakeIntVar(0, 9);

            IntVar[] vars = new IntVar[] { S, E, N, D, M, O, R, Y };

            // SEND + MORE = MONEY:
            IntVar send  = (S * 1000 + E * 100 + N * 10 + D).Var();
            IntVar more  = (M * 1000 + O * 100 + R * 10 + E).Var();
            IntVar money = (M * 10000 + O * 1000 + N * 100 + E * 10 + Y).Var();

            solver.Add(send + more == money);

            //Leading characters must not be zero:
            solver.Add(S != 0);
            solver.Add(M != 0);

            // Part B: All characters must take different values:
            // Otherwise we get 155 possible solutions!
            solver.Add(vars.AllDifferent());

            DecisionBuilder db = solver.MakePhase(
                vars,                               // Decision variables to resolve
                Solver.INT_VAR_SIMPLE,              // Variable selection policy for search
                Solver.INT_VALUE_SIMPLE);           // Value selection policy for search

            solver.NewSearch(db);

            while (solver.NextSolution())
            {
                Console.WriteLine("    SEND   |      " + send.Value());
                Console.WriteLine(" +  MORE   |   +  " + more.Value());
                Console.WriteLine(" -------   |   -------");
                Console.WriteLine("   MONEY   |     " + money.Value() + "\n");
            }

            solver.EndSearch();

            // Display the number of solutions found:
            Console.WriteLine("Total solution(s): " + solver.Solutions());
        }
예제 #7
0
  /**
   *
   * Solve the SEND+MORE=MONEY problem
   *
   */
  private static void Solve()
  {
    Solver solver = new Solver("SendMoreMoney");

    //
    // Decision variables
    //
    IntVar S = solver.MakeIntVar(0, 9, "S");
    IntVar E = solver.MakeIntVar(0, 9, "E");
    IntVar N = solver.MakeIntVar(0, 9, "N");
    IntVar D = solver.MakeIntVar(0, 9, "D");
    IntVar M = solver.MakeIntVar(0, 9, "M");
    IntVar O = solver.MakeIntVar(0, 9, "O");
    IntVar R = solver.MakeIntVar(0, 9, "R");
    IntVar Y = solver.MakeIntVar(0, 9, "Y");

    // for AllDifferent()
    IntVar[] x = new IntVar[] {S,E,N,D,M,O,R,Y};

    //
    // Constraints
    //
    solver.Add(x.AllDifferent());
    solver.Add(S*1000 + E*100 + N*10 + D + M*1000 + O*100 + R*10 + E ==
               M*10000 + O*1000 + N*100 + E*10 + Y);

    solver.Add(S > 0);
    solver.Add(M > 0);

    //
    // Search
    //
    DecisionBuilder db = solver.MakePhase(x,
                                          Solver.CHOOSE_FIRST_UNBOUND,
                                          Solver.ASSIGN_MIN_VALUE);

    solver.NewSearch(db);
    while (solver.NextSolution()) {
      for(int i = 0; i < 8; i++) {
        Console.Write(x[i].ToString() + " ");
      }
      Console.WriteLine();
    }

    Console.WriteLine("\nWallTime: " + solver.WallTime() + "ms ");
    Console.WriteLine("Failures: " + solver.Failures());
    Console.WriteLine("Branches: " + solver.Branches());

    solver.EndSearch();

  }
예제 #8
0
  /**
   * circuit(solver, x, z)
   *
   * A decomposition of the global constraint circuit, based
   * on some observation of the orbits in an array.
   *
   * This version also exposes z (the path) to the public.
   *
   * Note: The domain of x must be 0..n-1 (not 1..n)
   * since C# is 0-based.
   */
  public static void circuit(Solver solver, IntVar[] x, IntVar[] z) {

    int n = x.Length;

    solver.Add(x.AllDifferent());
    solver.Add(z.AllDifferent());

    // put the orbit of x[0] in z[0..n-1]
    solver.Add(z[0] == x[0]);
    for(int i = 1; i < n-1; i++) {
      solver.Add(z[i] == x.Element(z[i-1]));
    }

    // z may not be 0 for i < n-1
    for(int i = 1; i < n - 1; i++) {
      solver.Add(z[i] != 0);
    }

    // when i = n-1 it must be 0
    solver.Add(z[n - 1] == 0);

  }
예제 #9
0
    //  We don't need helper functions here
    //  Csharp syntax is easier than C++ syntax!

    private static void CPisFun()
    {
        //  Constraint Programming engine
        Solver solver = new Solver("CP is fun!");

        const int kBase = 10;

        // Decision variables
        IntVar c = solver.MakeIntVar(1, kBase - 1, "C");
        IntVar p = solver.MakeIntVar(0, kBase - 1, "P");
        IntVar i = solver.MakeIntVar(1, kBase - 1, "I");
        IntVar s = solver.MakeIntVar(0, kBase - 1, "S");
        IntVar f = solver.MakeIntVar(1, kBase - 1, "F");
        IntVar u = solver.MakeIntVar(0, kBase - 1, "U");
        IntVar n = solver.MakeIntVar(0, kBase - 1, "N");
        IntVar t = solver.MakeIntVar(1, kBase - 1, "T");
        IntVar r = solver.MakeIntVar(0, kBase - 1, "R");
        IntVar e = solver.MakeIntVar(0, kBase - 1, "E");

        // We need to group variables in a vector to be able to use
        // the global constraint AllDifferent
        IntVar[] letters = new IntVar[] { c, p, i, s, f, u, n, t, r, e };

        // Check if we have enough digits
        if (kBase < letters.Length)
        {
            throw new Exception("kBase < letters.Length");
        }

        //  Constraints
        solver.Add(letters.AllDifferent());

        // CP + IS + FUN = TRUE
        solver.Add(p + s + n + kBase * (c + i + u) + kBase * kBase * f ==
                   e + kBase * u + kBase * kBase * r + kBase * kBase * kBase * t);

        //  Decision Builder: hot to scour the search tree
        DecisionBuilder db = solver.MakePhase(letters,
                                              Solver.CHOOSE_FIRST_UNBOUND,
                                              Solver.ASSIGN_MIN_VALUE);

        solver.NewSearch(db);

        if (solver.NextSolution())
        {
            Console.WriteLine("Solution found:");
            Console.Write("C=" + c.Value() + " P=" + p.Value());
            Console.Write(" I=" + i.Value() + " S=" + s.Value());
            Console.Write(" F=" + f.Value() + " U=" + u.Value());
            Console.Write(" N=" + n.Value() + " T=" + t.Value());
            Console.Write(" R=" + r.Value() + " E=" + e.Value());
            Console.WriteLine();

            // Is CP + IS + FUN = TRUE?
            if (p.Value() + s.Value() + n.Value() +
                kBase * (c.Value() + i.Value() + u.Value()) +
                kBase * kBase * f.Value() !=
                e.Value() + kBase * u.Value() +
                kBase * kBase * r.Value() +
                kBase * kBase * kBase * t.Value())
            {
                throw new Exception("CP + IS + FUN != TRUE");
            }
        }
        else
        {
            Console.WriteLine("Cannot solve problem.");
        }  //  if (solver.NextSolution())

        solver.EndSearch();
    }
예제 #10
0
  /**
   *
   * Solve the SEND+MORE=MONEY problem
   * using scalar product.
   *
   */
  private static void Solve()
  {
    Solver solver = new Solver("SendMoreMoney");

    //
    // Decision variables
    //
    IntVar S = solver.MakeIntVar(0, 9, "S");
    IntVar E = solver.MakeIntVar(0, 9, "E");
    IntVar N = solver.MakeIntVar(0, 9, "N");
    IntVar D = solver.MakeIntVar(0, 9, "D");
    IntVar M = solver.MakeIntVar(0, 9, "M");
    IntVar O = solver.MakeIntVar(0, 9, "O");
    IntVar R = solver.MakeIntVar(0, 9, "R");
    IntVar Y = solver.MakeIntVar(0, 9, "Y");

    // for AllDifferent()
    IntVar[] x = new IntVar[] {S,E,N,D,M,O,R,Y};

    //
    // Constraints
    //
    solver.Add(x.AllDifferent());

    /*
    solver.Add(S*1000 + E*100 + N*10 + D + M*1000 + O*100 + R*10 + E ==
               M*10000 + O*1000 + N*100 + E*10 + Y);
    */

    // Here we use scalar product instead.
    int[] s1 = new int[] {1000,100,10,1};
    int[] s2 = new int[] {10000,1000,100,10,1};
    solver.Add(new IntVar[] {S,E,N,D}.ScalProd(s1) +
               new IntVar[] {M,O,R,E}.ScalProd(s1) ==
               new IntVar[] {M,O,N,E,Y}.ScalProd(s2));

    solver.Add(S > 0);
    solver.Add(M > 0);

    //
    // Search
    //
    DecisionBuilder db = solver.MakePhase(x,
                                          Solver.CHOOSE_FIRST_UNBOUND,
                                          Solver.ASSIGN_MIN_VALUE);

    solver.NewSearch(db);
    while (solver.NextSolution()) {
      for(int i = 0; i < 8; i++) {
        Console.Write(x[i].Value() + " ");
      }
      Console.WriteLine();
    }

    Console.WriteLine("\nSolutions: {0}", solver.Solutions());
    Console.WriteLine("WallTime: {0}ms", solver.WallTime());
    Console.WriteLine("Failures: {0}", solver.Failures());
    Console.WriteLine("Branches: {0}", solver.Branches());

    solver.EndSearch();

  }
예제 #11
0
  /**
   *
   * This is a port of Charles Prud'homme's Java model
   * Partition.java
   * """
   * Partition n numbers into two groups, so that
   * - the sum of the first group equals the sum of the second,
   * - and the sum of the squares of the first group equals the sum of
   *   the squares of the second
   * """
   *
   */
  private static void Solve(int m)
  {

    Solver solver = new Solver("Partition");


    //
    // Decision variables
    //
    IntVar[] x = solver.MakeIntVarArray(m, 1, 2 * m, "x");
    IntVar[] y = solver.MakeIntVarArray(m, 1, 2 * m, "y");


    //
    // Constraints
    //
       // break symmetries
    for (int i = 0; i < m - 1; i++) {
      solver.Add(x[i] < x[i + 1]);
      solver.Add(y[i] < y[i + 1]);
    }
    solver.Add(x[0] < y[0]);

    IntVar[] xy = new IntVar[2 * m];
    for (int i = m - 1; i >= 0; i--) {
      xy[i] = x[i];
      xy[m + i] = y[i];
    }

    solver.Add(xy.AllDifferent());

    int[] coeffs = new int[2 * m];
    for (int i = m - 1; i >= 0; i--) {
      coeffs[i] = 1;
      coeffs[m + i] = -1;
    }
    solver.Add(xy.ScalProd(coeffs) == 0);

    IntVar[] sxy, sx, sy;
    sxy = new IntVar[2 * m];
    sx = new IntVar[m];
    sy = new IntVar[m];
    for (int i = m - 1; i >= 0; i--) {
      sx[i] = x[i].Square().Var();
      sxy[i] = sx[i];
      sy[i] = y[i].Square().Var();
      sxy[m + i] = sy[i];
    }
    solver.Add(sxy.ScalProd(coeffs) == 0);

    solver.Add(x.Sum() == 2 * m * (2 * m + 1) / 4);
    solver.Add(y.Sum() == 2 * m * (2 * m + 1) / 4);
    solver.Add(sx.Sum() == 2 * m * (2 * m + 1) * (4 * m + 1) / 12);
    solver.Add(sy.Sum() == 2 * m * (2 * m + 1) * (4 * m + 1) / 12);

    //
    // Search
    //
    DecisionBuilder db = solver.MakeDefaultPhase(xy);

    SearchMonitor log = solver.MakeSearchLog(10000);
    solver.NewSearch(db, log);

    while (solver.NextSolution()) {
      for(int i = 0; i < m; i++) {
        Console.Write("[" + xy[i].Value() + "] ");
      }
      Console.WriteLine();
      for(int i = 0; i < m; i++) {
        Console.Write("[" + xy[m+i].Value() + "] ");
      }
      Console.WriteLine("\n");
    }

    Console.WriteLine("\nSolutions: {0}", solver.Solutions());
    Console.WriteLine("WallTime: {0}ms", solver.WallTime());
    Console.WriteLine("Failures: {0}", solver.Failures());
    Console.WriteLine("Branches: {0} ", solver.Branches());

    solver.EndSearch();

  }
예제 #12
0
    /**
     *
     * Solve the SEND+MOST=MONEY problem
     * where the object is to maximize MONEY
     * See http://www.hakank.org/google_or_tools/send_most_money.py
     *
     */
    private static long Solve(long MONEY)
    {
        Solver solver = new Solver("SendMostMoney");

        //
        // Decision variables
        //
        IntVar S = solver.MakeIntVar(0, 9, "S");
        IntVar E = solver.MakeIntVar(0, 9, "E");
        IntVar N = solver.MakeIntVar(0, 9, "N");
        IntVar D = solver.MakeIntVar(0, 9, "D");
        IntVar M = solver.MakeIntVar(0, 9, "M");
        IntVar O = solver.MakeIntVar(0, 9, "O");
        IntVar T = solver.MakeIntVar(0, 9, "T");
        IntVar Y = solver.MakeIntVar(0, 9, "Y");

        // for AllDifferent()
        IntVar[] x = new IntVar[] { S, E, N, D, M, O, T, Y };

        IntVar[] eq     = { S, E, N, D, M, O, S, T, M, O, N, E, Y };
        int[]    coeffs =
        {
            1000,     100,   10,   1,    //    S E N D +
            1000,     100,   10,   1,    //    M O S T
            -10000, -1000, -100, -10, -1 // == M O N E Y
        };
        solver.Add(eq.ScalProd(coeffs) == 0);

        // IntVar money = solver.MakeScalProd(new IntVar[] {M, O, N, E, Y},
        //                                    new int[] {10000, 1000, 100, 10,
        //                                    1}).Var();
        IntVar money =
            (new IntVar[] { M, O, N, E, Y }).ScalProd(new int[] { 10000, 1000, 100, 10, 1 }).Var();

        //
        // Constraints
        //
        solver.Add(x.AllDifferent());
        solver.Add(S > 0);
        solver.Add(M > 0);

        if (MONEY > 0)
        {
            solver.Add(money == MONEY);
        }

        //
        // Search
        //
        DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);

        if (MONEY == 0)
        {
            OptimizeVar obj = money.Maximize(1);
            solver.NewSearch(db, obj);
        }
        else
        {
            solver.NewSearch(db);
        }

        long money_ret = 0;

        while (solver.NextSolution())
        {
            money_ret = money.Value();
            Console.WriteLine("money: {0}", money.Value());
            for (int i = 0; i < x.Length; i++)
            {
                Console.Write(x[i].Value() + " ");
            }
            Console.WriteLine();
        }

        Console.WriteLine("\nSolutions: {0}", solver.Solutions());
        Console.WriteLine("WallTime: {0}ms", solver.WallTime());
        Console.WriteLine("Failures: {0}", solver.Failures());
        Console.WriteLine("Branches: {0} ", solver.Branches());

        solver.EndSearch();

        return(money_ret);
    }
예제 #13
0
    //  We don't need helper functions here
    //  Csharp syntax is easier than C++ syntax!

    private static void CPisFun ()
    {
        //  Constraint Programming engine
        Solver solver = new Solver ("CP is fun!");

        const int kBase = 10;

        // Decision variables
        IntVar c = solver.MakeIntVar (1, kBase - 1, "C");
        IntVar p = solver.MakeIntVar (0, kBase - 1, "P");
        IntVar i = solver.MakeIntVar (1, kBase - 1, "I");
        IntVar s = solver.MakeIntVar (0, kBase - 1, "S");
        IntVar f = solver.MakeIntVar (1, kBase - 1, "F");
        IntVar u = solver.MakeIntVar (0, kBase - 1, "U");
        IntVar n = solver.MakeIntVar (0, kBase - 1, "N");
        IntVar t = solver.MakeIntVar (1, kBase - 1, "T");
        IntVar r = solver.MakeIntVar (0, kBase - 1, "R");
        IntVar e = solver.MakeIntVar (0, kBase - 1, "E");

        // We need to group variables in a vector to be able to use
        // the global constraint AllDifferent
        IntVar[] letters = new IntVar[] { c, p, i, s, f, u, n, t, r, e};

        // Check if we have enough digits
        if (kBase < letters.Length) {
          throw new Exception("kBase < letters.Length");
        }

        //  Constraints
        solver.Add (letters.AllDifferent ());

        // CP + IS + FUN = TRUE
        solver.Add (p + s + n + kBase * (c + i + u) + kBase * kBase * f ==
               e + kBase * u + kBase * kBase * r + kBase * kBase * kBase * t);

        //  Decision Builder: hot to scour the search tree
        DecisionBuilder db = solver.MakePhase (letters,
                                               Solver.CHOOSE_FIRST_UNBOUND,
                                               Solver.ASSIGN_MIN_VALUE);
        solver.NewSearch (db);

        if (solver.NextSolution ()) {
            Console.WriteLine ("Solution found:");
            Console.Write ("C=" + c.Value () + " P=" + p.Value ());
            Console.Write (" I=" + i.Value () + " S=" + s.Value ());
            Console.Write (" F=" + f.Value () + " U=" + u.Value ());
            Console.Write (" N=" + n.Value () + " T=" + t.Value ());
            Console.Write (" R=" + r.Value () + " E=" + e.Value ());
            Console.WriteLine ();

            // Is CP + IS + FUN = TRUE?
            if (p.Value () + s.Value () + n.Value() +
                kBase * (c.Value () + i.Value () + u.Value()) +
                kBase * kBase * f.Value () !=
                e.Value () + kBase * u.Value () +
                kBase * kBase * r.Value () +
                kBase * kBase * kBase * t.Value ()) {
              throw new Exception("CP + IS + FUN != TRUE");
            }
        } else {
            Console.WriteLine ("Cannot solve problem.");
        }  //  if (solver.NextSolution())

        solver.EndSearch ();

    }
예제 #14
0
    //  We don't need helper functions here
    //  Csharp syntax is easier than C++ syntax!

    private static void CPisFun(int kBase, int time_limit_param, bool print)
    {
        // Use some profiling and change the default parameters of the solver
        SolverParameters solver_params = new SolverParameters();

        // Change the profile level
        solver_params.profile_level = SolverParameters.NORMAL_PROFILING;

        //  Constraint Programming engine
        Solver solver = new Solver("CP is fun!", solver_params);

        // Decision variables
        IntVar c = solver.MakeIntVar(1, kBase - 1, "C");
        IntVar p = solver.MakeIntVar(0, kBase - 1, "P");
        IntVar i = solver.MakeIntVar(1, kBase - 1, "I");
        IntVar s = solver.MakeIntVar(0, kBase - 1, "S");
        IntVar f = solver.MakeIntVar(1, kBase - 1, "F");
        IntVar u = solver.MakeIntVar(0, kBase - 1, "U");
        IntVar n = solver.MakeIntVar(0, kBase - 1, "N");
        IntVar t = solver.MakeIntVar(1, kBase - 1, "T");
        IntVar r = solver.MakeIntVar(0, kBase - 1, "R");
        IntVar e = solver.MakeIntVar(0, kBase - 1, "E");

        // We need to group variables in a vector to be able to use
        // the global constraint AllDifferent
        IntVar[] letters = new IntVar[] { c, p, i, s, f, u, n, t, r, e };

        // Check if we have enough digits
        if (kBase < letters.Length)
        {
            throw new Exception("kBase < letters.Length");
        }

        //  Constraints
        solver.Add(letters.AllDifferent());

        // CP + IS + FUN = TRUE
        solver.Add(p + s + n + kBase * (c + i + u) + kBase * kBase * f ==
                   e + kBase * u + kBase * kBase * r + kBase * kBase * kBase * t);

        SolutionCollector all_solutions = solver.MakeAllSolutionCollector();

        //  Add the interesting variables to the SolutionCollector
        all_solutions.Add(letters);

        //  Decision Builder: hot to scour the search tree
        DecisionBuilder db = solver.MakePhase(letters,
                                              Solver.CHOOSE_FIRST_UNBOUND,
                                              Solver.ASSIGN_MIN_VALUE);

        // Add some time limit
        SearchLimit time_limit = solver.MakeTimeLimit(time_limit_param);

        solver.Solve(db, all_solutions, time_limit);

        //  Retrieve the solutions
        int numberSolutions = all_solutions.SolutionCount();

        Console.WriteLine("Number of solutions: " + numberSolutions);

        if (print)
        {
            for (int index = 0; index < numberSolutions; ++index)
            {
                Console.Write("C=" + all_solutions.Value(index, c));
                Console.Write(" P=" + all_solutions.Value(index, p));
                Console.Write(" I=" + all_solutions.Value(index, i));
                Console.Write(" S=" + all_solutions.Value(index, s));
                Console.Write(" F=" + all_solutions.Value(index, f));
                Console.Write(" U=" + all_solutions.Value(index, u));
                Console.Write(" N=" + all_solutions.Value(index, n));
                Console.Write(" T=" + all_solutions.Value(index, t));
                Console.Write(" R=" + all_solutions.Value(index, r));
                Console.Write(" E=" + all_solutions.Value(index, e));
                Console.WriteLine();
            }
        }

        // Save profile in file
        solver.ExportProfilingOverview("profile.txt");
    }
예제 #15
0
    /**
     *
     * This is a port of Charles Prud'homme's Java model
     * Partition.java
     * """
     * Partition n numbers into two groups, so that
     * - the sum of the first group equals the sum of the second,
     * - and the sum of the squares of the first group equals the sum of
     *   the squares of the second
     * """
     *
     */
    private static void Solve(int m)
    {
        Solver solver = new Solver("Partition");


        //
        // Decision variables
        //
        IntVar[] x = solver.MakeIntVarArray(m, 1, 2 * m, "x");
        IntVar[] y = solver.MakeIntVarArray(m, 1, 2 * m, "y");


        //
        // Constraints
        //
        // break symmetries
        for (int i = 0; i < m - 1; i++)
        {
            solver.Add(x[i] < x[i + 1]);
            solver.Add(y[i] < y[i + 1]);
        }
        solver.Add(x[0] < y[0]);

        IntVar[] xy = new IntVar[2 * m];
        for (int i = m - 1; i >= 0; i--)
        {
            xy[i]     = x[i];
            xy[m + i] = y[i];
        }

        solver.Add(xy.AllDifferent());

        int[] coeffs = new int[2 * m];
        for (int i = m - 1; i >= 0; i--)
        {
            coeffs[i]     = 1;
            coeffs[m + i] = -1;
        }
        solver.Add(xy.ScalProd(coeffs) == 0);

        IntVar[] sxy, sx, sy;
        sxy = new IntVar[2 * m];
        sx  = new IntVar[m];
        sy  = new IntVar[m];
        for (int i = m - 1; i >= 0; i--)
        {
            sx[i]      = x[i].Square().Var();
            sxy[i]     = sx[i];
            sy[i]      = y[i].Square().Var();
            sxy[m + i] = sy[i];
        }
        solver.Add(sxy.ScalProd(coeffs) == 0);

        solver.Add(x.Sum() == 2 * m * (2 * m + 1) / 4);
        solver.Add(y.Sum() == 2 * m * (2 * m + 1) / 4);
        solver.Add(sx.Sum() == 2 * m * (2 * m + 1) * (4 * m + 1) / 12);
        solver.Add(sy.Sum() == 2 * m * (2 * m + 1) * (4 * m + 1) / 12);

        //
        // Search
        //
        DecisionBuilder db = solver.MakeDefaultPhase(xy);

        SearchMonitor log = solver.MakeSearchLog(10000);

        solver.NewSearch(db, log);

        while (solver.NextSolution())
        {
            for (int i = 0; i < m; i++)
            {
                Console.Write("[" + xy[i].Value() + "] ");
            }
            Console.WriteLine();
            for (int i = 0; i < m; i++)
            {
                Console.Write("[" + xy[m + i].Value() + "] ");
            }
            Console.WriteLine("\n");
        }

        Console.WriteLine("\nSolutions: {0}", solver.Solutions());
        Console.WriteLine("WallTime: {0}ms", solver.WallTime());
        Console.WriteLine("Failures: {0}", solver.Failures());
        Console.WriteLine("Branches: {0} ", solver.Branches());

        solver.EndSearch();
    }
예제 #16
0
    /**
     *
     * Cryptarithmetic puzzle.
     *
     * Prolog benchmark problem GNU Prolog (crypta.pl)
     * """
     * Name           : crypta.pl
     * Title          : crypt-arithmetic
     * Original Source: P. Van Hentenryck's book
     * Adapted by     : Daniel Diaz - INRIA France
     * Date           : September 1992
     *
     * Solve the operation:
     *
     *    B A I J J A J I I A H F C F E B B J E A
     *  + D H F G A B C D I D B I F F A G F E J E
     *  -----------------------------------------
     *  = G J E G A C D D H F A F J B F I H E E F
     * """
     *
     *
     * Also see http://hakank.org/or-tools/crypta.py
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("Crypta");

        //
        // Decision variables
        //
        IntVar A = solver.MakeIntVar(0, 9, "A");
        IntVar B = solver.MakeIntVar(0, 9, "B");
        IntVar C = solver.MakeIntVar(0, 9, "C");
        IntVar D = solver.MakeIntVar(0, 9, "D");
        IntVar E = solver.MakeIntVar(0, 9, "E");
        IntVar F = solver.MakeIntVar(0, 9, "F");
        IntVar G = solver.MakeIntVar(0, 9, "G");
        IntVar H = solver.MakeIntVar(0, 9, "H");
        IntVar I = solver.MakeIntVar(0, 9, "I");
        IntVar J = solver.MakeIntVar(0, 9, "J");

        IntVar[] LD = new IntVar[] { A, B, C, D, E, F, G, H, I, J };

        IntVar Sr1 = solver.MakeIntVar(0, 1, "Sr1");
        IntVar Sr2 = solver.MakeIntVar(0, 1, "Sr2");

        //
        // Constraints
        //
        solver.Add(LD.AllDifferent());
        solver.Add(B >= 1);
        solver.Add(D >= 1);
        solver.Add(G >= 1);

        solver.Add((A + 10 * E + 100 * J + 1000 * B + 10000 * B + 100000 * E + 1000000 * F + E + 10 * J + 100 * E +
                    1000 * F + 10000 * G + 100000 * A + 1000000 * F) ==
                   (F + 10 * E + 100 * E + 1000 * H + 10000 * I + 100000 * F + 1000000 * B + 10000000 * Sr1));

        solver.Add((C + 10 * F + 100 * H + 1000 * A + 10000 * I + 100000 * I + 1000000 * J + F + 10 * I + 100 * B +
                    1000 * D + 10000 * I + 100000 * D + 1000000 * C + Sr1) ==
                   (J + 10 * F + 100 * A + 1000 * F + 10000 * H + 100000 * D + 1000000 * D + 10000000 * Sr2));

        solver.Add((A + 10 * J + 100 * J + 1000 * I + 10000 * A + 100000 * B + B + 10 * A + 100 * G + 1000 * F +
                    10000 * H + 100000 * D + Sr2) == (C + 10 * A + 100 * G + 1000 * E + 10000 * J + 100000 * G));

        //
        // Search
        //
        DecisionBuilder db = solver.MakePhase(LD, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);

        solver.NewSearch(db);

        while (solver.NextSolution())
        {
            for (int i = 0; i < 10; i++)
            {
                Console.Write(LD[i].ToString() + " ");
            }
            Console.WriteLine();
        }

        Console.WriteLine("\nWallTime: " + solver.WallTime() + "ms ");
        Console.WriteLine("Failures: " + solver.Failures());
        Console.WriteLine("Branches: " + solver.Branches());

        solver.EndSearch();
    }
예제 #17
0
    public static void Main(String[] args)
    {
        // Instantiate the solver.
        // [START solver]
        Solver solver = new Solver("N-Queens");
        // [END solver]

        // [START variables]
        const int BoardSize = 8;

        IntVar[] queens = new IntVar[BoardSize];
        for (int i = 0; i < BoardSize; ++i)
        {
            queens[i] = solver.MakeIntVar(0, BoardSize - 1, $"x{i}");
        }
        // [END variables]

        // Define constraints.
        // [START constraints]
        // All rows must be different.
        solver.Add(queens.AllDifferent());

        // All columns must be different because the indices of queens are all different.
        // No two queens can be on the same diagonal.
        IntVar[] diag1 = new IntVar[BoardSize];
        IntVar[] diag2 = new IntVar[BoardSize];
        for (int i = 0; i < BoardSize; ++i)
        {
            diag1[i] = solver.MakeSum(queens[i], i).Var();
            diag2[i] = solver.MakeSum(queens[i], -i).Var();
        }

        solver.Add(diag1.AllDifferent());
        solver.Add(diag2.AllDifferent());
        // [END constraints]

        // [START db]
        // Create the decision builder to search for solutions.
        DecisionBuilder db = solver.MakePhase(queens, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);
        // [END db]

        // [START solve]
        // Iterates through the solutions, displaying each.
        int SolutionCount = 0;

        solver.NewSearch(db);
        while (solver.NextSolution())
        {
            Console.WriteLine("Solution " + SolutionCount);
            for (int i = 0; i < BoardSize; ++i)
            {
                for (int j = 0; j < BoardSize; ++j)
                {
                    if (queens[j].Value() == i)
                    {
                        Console.Write("Q");
                    }
                    else
                    {
                        Console.Write("_");
                    }
                    if (j != BoardSize - 1)
                    {
                        Console.Write(" ");
                    }
                }
                Console.WriteLine("");
            }
            SolutionCount++;
        }
        solver.EndSearch();
        // [END solve]

        // Statistics.
        // [START statistics]
        Console.WriteLine("Statistics");
        Console.WriteLine($"  failures: {solver.Failures()}");
        Console.WriteLine($"  branches: {solver.Branches()}");
        Console.WriteLine($"  wall time: {solver.WallTime()} ms");
        Console.WriteLine($"  Solutions found: {SolutionCount}");
        // [END statistics]
    }
예제 #18
0
    /**
     *
     * Solves a Strimko problem.
     * See http://www.hakank.org/google_or_tools/strimko2.py
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("Strimko2");

        //
        // data
        //
        int[,] streams = { { 1, 1, 2, 2, 2, 2, 2 }, { 1, 1, 2, 3, 3, 3, 2 }, { 1, 4, 1, 3, 3, 5, 5 },
                           { 4, 4, 3, 1, 3, 5, 5 }, { 4, 6, 6, 6, 7, 7, 5 }, { 6, 4, 6, 4, 5, 5, 7 },
                           { 6, 6, 4, 7, 7, 7, 7 } };

        // Note: This is 1-based
        int[,] placed = { { 2, 1, 1 }, { 2, 3, 7 }, { 2, 5, 6 }, { 2, 7, 4 }, { 3, 2, 7 },
                          { 3, 6, 1 }, { 4, 1, 4 }, { 4, 7, 5 }, { 5, 2, 2 }, { 5, 6, 6 } };

        int n          = streams.GetLength(0);
        int num_placed = placed.GetLength(0);

        //
        // Decision variables
        //
        IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, n, "x");
        IntVar[] x_flat = x.Flatten();

        //
        // Constraints
        //
        // all rows and columns must be unique, i.e. a Latin Square
        for (int i = 0; i < n; i++)
        {
            IntVar[] row = new IntVar[n];
            IntVar[] col = new IntVar[n];
            for (int j = 0; j < n; j++)
            {
                row[j] = x[i, j];
                col[j] = x[j, i];
            }

            solver.Add(row.AllDifferent());
            solver.Add(col.AllDifferent());
        }

        // streams
        for (int s = 1; s <= n; s++)
        {
            IntVar[] tmp =
                (from i in Enumerable.Range(0, n) from j in Enumerable.Range(0, n)
                 where streams[i, j] == s select x[i, j])
                .ToArray();
            solver.Add(tmp.AllDifferent());
        }

        // placed
        for (int i = 0; i < num_placed; i++)
        {
            // note: also adjust to 0-based
            solver.Add(x[placed[i, 0] - 1, placed[i, 1] - 1] == placed[i, 2]);
        }

        //
        // Search
        //
        DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);

        solver.NewSearch(db);

        while (solver.NextSolution())
        {
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    Console.Write(x[i, j].Value() + " ");
                }
                Console.WriteLine();
            }
            Console.WriteLine();
        }

        Console.WriteLine("\nSolutions: {0}", solver.Solutions());
        Console.WriteLine("WallTime: {0}ms", solver.WallTime());
        Console.WriteLine("Failures: {0}", solver.Failures());
        Console.WriteLine("Branches: {0} ", solver.Branches());

        solver.EndSearch();
    }
예제 #19
0
    public static void Main(String[] args)
    {
        // Instantiate the solver.
        // [START solver]
        Solver solver = new Solver("CP is fun!");
        // [END solver]

        // [START variables]
        const int kBase = 10;

        // Decision variables.
        IntVar c = solver.MakeIntVar(1, kBase - 1, "C");
        IntVar p = solver.MakeIntVar(0, kBase - 1, "P");
        IntVar i = solver.MakeIntVar(1, kBase - 1, "I");
        IntVar s = solver.MakeIntVar(0, kBase - 1, "S");
        IntVar f = solver.MakeIntVar(1, kBase - 1, "F");
        IntVar u = solver.MakeIntVar(0, kBase - 1, "U");
        IntVar n = solver.MakeIntVar(0, kBase - 1, "N");
        IntVar t = solver.MakeIntVar(1, kBase - 1, "T");
        IntVar r = solver.MakeIntVar(0, kBase - 1, "R");
        IntVar e = solver.MakeIntVar(0, kBase - 1, "E");

        // Group variables in a vector so that we can use AllDifferent.
        IntVar[] letters = new IntVar[] { c, p, i, s, f, u, n, t, r, e };

        // Verify that we have enough digits.
        if (kBase < letters.Length)
        {
            throw new Exception("kBase < letters.Length");
        }
        // [END variables]

        // Define constraints.
        // [START constraints]
        solver.Add(letters.AllDifferent());

        // CP + IS + FUN = TRUE
        solver.Add(p + s + n + kBase * (c + i + u) + kBase * kBase * f ==
                   e + kBase * u + kBase * kBase * r + kBase * kBase * kBase * t);
        // [END constraints]

        // [START solve]
        int SolutionCount = 0;
        // Create the decision builder to search for solutions.
        DecisionBuilder db = solver.MakePhase(letters, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);

        solver.NewSearch(db);
        while (solver.NextSolution())
        {
            Console.Write("C=" + c.Value() + " P=" + p.Value());
            Console.Write(" I=" + i.Value() + " S=" + s.Value());
            Console.Write(" F=" + f.Value() + " U=" + u.Value());
            Console.Write(" N=" + n.Value() + " T=" + t.Value());
            Console.Write(" R=" + r.Value() + " E=" + e.Value());
            Console.WriteLine();

            // Is CP + IS + FUN = TRUE?
            if (p.Value() + s.Value() + n.Value() + kBase * (c.Value() + i.Value() + u.Value()) +
                kBase * kBase * f.Value() !=
                e.Value() + kBase * u.Value() + kBase * kBase * r.Value() + kBase * kBase * kBase * t.Value())
            {
                throw new Exception("CP + IS + FUN != TRUE");
            }
            SolutionCount++;
        }
        solver.EndSearch();
        Console.WriteLine($"Number of solutions found: {SolutionCount}");
        // [END solve]
    }
예제 #20
0
  /**
   *
   * Solves the Quasigroup Completion problem.
   * See http://www.hakank.org/or-tools/quasigroup_completion.py
   *
   */
  private static void Solve()
  {
    Solver solver = new Solver("QuasigroupCompletion");

    //
    // data
    //
    Console.WriteLine("Problem:");
    for(int i = 0; i < n; i++) {
      for(int j = 0; j < n; j++) {
        Console.Write(problem[i,j] + " ");
      }
      Console.WriteLine();
    }
    Console.WriteLine();


    //
    // Decision variables
    //
    IntVar[,] x =  solver.MakeIntVarMatrix(n, n, 1, n, "x");
    IntVar[] x_flat = x.Flatten();

    //
    // Constraints
    //  
   for(int i = 0; i < n; i++) {
      for(int j = 0; j < n; j++) {
        if (problem[i,j] > X) {
          solver.Add(x[i,j] == problem[i,j]);
        }
      }
    }

    //
    // rows and columns must be different
    //

    // rows
    for(int i = 0; i < n; i++) {
      IntVar[] row = new IntVar[n];
      for(int j = 0; j < n; j++) {
        row[j] = x[i,j];
      }
      solver.Add(row.AllDifferent());
    }

    // columns
    for(int j = 0; j < n; j++) {
      IntVar[] col = new IntVar[n];
      for(int i = 0; i < n; i++) {
        col[i] = x[i,j];
      }
      solver.Add(col.AllDifferent());
    }


    //
    // Search
    //
    DecisionBuilder db = solver.MakePhase(x_flat,
                                          Solver.INT_VAR_SIMPLE,
                                          Solver.ASSIGN_MIN_VALUE);

    solver.NewSearch(db);

    int sol = 0;
    while (solver.NextSolution()) {
      sol++;
      Console.WriteLine("Solution #{0} ", sol + " ");
      for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++){ 
          Console.Write("{0} ", x[i,j].Value());
        }
        Console.WriteLine();
      }
      
      Console.WriteLine();
    }

    Console.WriteLine("\nSolutions: {0}", solver.Solutions());
    Console.WriteLine("WallTime: {0}ms", solver.WallTime());
    Console.WriteLine("Failures: {0}", solver.Failures());
    Console.WriteLine("Branches: {0} ", solver.Branches());

    solver.EndSearch();

  }
예제 #21
0
  /**
   *
   * Solve the SEND+MOST=MONEY problem
   * where the object is to maximize MONEY
   * See http://www.hakank.org/google_or_tools/send_most_money.py
   *
   */
  private static long Solve(long MONEY)
  {

    Solver solver = new Solver("SendMostMoney");

    //
    // Decision variables
    //
    IntVar S = solver.MakeIntVar(0, 9, "S");
    IntVar E = solver.MakeIntVar(0, 9, "E");
    IntVar N = solver.MakeIntVar(0, 9, "N");
    IntVar D = solver.MakeIntVar(0, 9, "D");
    IntVar M = solver.MakeIntVar(0, 9, "M");
    IntVar O = solver.MakeIntVar(0, 9, "O");
    IntVar T = solver.MakeIntVar(0, 9, "T");
    IntVar Y = solver.MakeIntVar(0, 9, "Y");

    // for AllDifferent()
    IntVar[] x = new IntVar[] {S,E,N,D,M,O,T,Y};

    IntVar[] eq = {S,E,N,D,  M,O,S,T, M,O,N,E,Y};
    int[] coeffs = {  1000, 100, 10, 1,        //    S E N D +
                      1000, 100, 10, 1,        //    M O S T
                    -10000,-1000, -100,-10,-1  // == M O N E Y
                    };
    solver.Add(eq.ScalProd(coeffs) == 0);

    // IntVar money = solver.MakeScalProd(new IntVar[] {M, O, N, E, Y},
    //                                    new int[] {10000, 1000, 100, 10, 1}).Var();
    IntVar money = (new IntVar[] {M, O, N, E, Y}).
                          ScalProd(new int[] {10000, 1000, 100, 10, 1}).Var();

    //
    // Constraints
    //
    solver.Add(x.AllDifferent());
    solver.Add(S > 0);
    solver.Add(M > 0);

    if (MONEY > 0) {
      solver.Add(money == MONEY);
    }

    //
    // Search
    //
    DecisionBuilder db = solver.MakePhase(x,
                                          Solver.CHOOSE_FIRST_UNBOUND,
                                          Solver.ASSIGN_MIN_VALUE);

    if (MONEY == 0) {
      OptimizeVar obj = money.Maximize(1);
      solver.NewSearch(db, obj);
    } else {
      solver.NewSearch(db);
    }

    long money_ret = 0;
    while (solver.NextSolution()) {
      money_ret = money.Value();
      Console.WriteLine("money: {0}", money.Value() );
      for(int i = 0; i < x.Length; i++) {
        Console.Write(x[i].Value() + " ");
      }
      Console.WriteLine();
    }

    Console.WriteLine("\nSolutions: {0}", solver.Solutions());
    Console.WriteLine("WallTime: {0}ms", solver.WallTime());
    Console.WriteLine("Failures: {0}", solver.Failures());
    Console.WriteLine("Branches: {0} ", solver.Branches());

    solver.EndSearch();

    return money_ret;

  }
예제 #22
0
파일: nqueens.cs 프로젝트: 9thbit/csplib
  /**
   *
   * Solves the N-Queens problem.
   *
   * Syntax: nqueens.exe n num print
   * where 
   *    n    : size of board
   *    num  : number of solutions to calculate
   *    print: print the results (if > 0)
   *
   */
  private static void Solve(int n=8, int num=0, int print=1)
  {
    Solver solver = new Solver("N-Queens");

    //
    // Decision variables
    //
    IntVar[] q = solver.MakeIntVarArray(n, 0, n-1, "q");


    //
    // Constraints
    //  
    solver.Add(q.AllDifferent());

    IntVar[] q1 = new IntVar[n];
    IntVar[] q2 = new IntVar[n];
    for(int i = 0; i < n; i++) {
      q1[i] = (q[i] + i).Var();
      q2[i] = (q[i] - i).Var();
    }
    solver.Add(q1.AllDifferent());
    solver.Add(q2.AllDifferent());

    // Alternative version: it works as well but are not that clear
    /*
    solver.Add((from i in Enumerable.Range(0, n)
                select (q[i] + i).Var()).ToArray().AllDifferent());

    solver.Add((from i in Enumerable.Range(0, n)
                select (q[i] - i).Var()).ToArray().AllDifferent());
    */

    //
    // Search
    //
    DecisionBuilder db = solver.MakePhase(q,
                                          Solver.CHOOSE_MIN_SIZE_LOWEST_MAX,
                                          Solver.ASSIGN_CENTER_VALUE);

    solver.NewSearch(db);
    int c = 0;
    while (solver.NextSolution()) {
      if (print > 0) {
        for(int i = 0; i < n; i++) {
          Console.Write("{0} ", q[i].Value());
        }
      
        Console.WriteLine();
      }
      c++;
      if (num > 0 && c >= num) {
        break;
      }
    }

    Console.WriteLine("\nSolutions: {0}", solver.Solutions());
    Console.WriteLine("WallTime: {0}ms", solver.WallTime());
    Console.WriteLine("Failures: {0}", solver.Failures());
    Console.WriteLine("Branches: {0} ", solver.Branches());

    solver.EndSearch();

  }
예제 #23
0
  /**
   *
   * Golomb Ruler problem.
   *
   * This C# implementation is based on Charles Prud'homme's
   * or-tools/Java model:
   * http://code.google.com/p/or-tools/source/browse/trunk/com/google/ortools/constraintsolver/samples/GolombRuler.java
   *
   */
  private static void Solve(int m = 8)
  {
    Solver solver = new Solver("GolombRuler");


    //
    // Decision variables
    //
    IntVar[] ticks =  solver.MakeIntVarArray(m,
                                             0,
                                             ((m < 31) ? (1 << (m + 1)) - 1 : 9999),
                                             "ticks");

    IntVar[] diff = new IntVar[(m * m - m) / 2];


    //
    // Constraints
    //
    solver.Add(ticks[0] == 0);

    for(int i = 0; i < ticks.Length - 1; i++) {
      solver.Add(ticks[i] < ticks[i+1]);
    }


    for (int k = 0, i = 0; i < m - 1; i++) {
      for (int j = i + 1; j < m; j++, k++) {
        diff[k] = (ticks[j]-ticks[i]).Var();
        solver.Add(diff[k] >= (j - i) * (j - i + 1) / 2);
      }
    }

    solver.Add(diff.AllDifferent());

    // break symetries
    if (m > 2) {
      solver.Add(diff[0] < diff[diff.Length - 1]);
    }


    //
    // Optimization
    //
    OptimizeVar opt = ticks[m - 1].Minimize(1);


    //
    // Search
    //
    DecisionBuilder db = solver.MakePhase(ticks,
                                          Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
                                          Solver.ASSIGN_MIN_VALUE);

    // We just want the debug info for larger instances.
    if (m >= 11) {

      SearchMonitor log = solver.MakeSearchLog(10000, opt);
      solver.NewSearch(db, opt, log);

    } else {

      solver.NewSearch(db, opt);
    }


    while (solver.NextSolution()) {
      Console.Write("opt: {0}  [ ", ticks[m-1].Value());
      for(int i = 0; i < m; i++) {
          Console.Write("{0} ", ticks[i].Value());
      }
      Console.WriteLine("]");
    }

    Console.WriteLine("\nSolutions: {0}", solver.Solutions());
    Console.WriteLine("WallTime: {0}ms", solver.WallTime());
    Console.WriteLine("Failures: {0}", solver.Failures());
    Console.WriteLine("Branches: {0} ", solver.Branches());

    solver.EndSearch();

  }
예제 #24
0
    /**
     *
     * Solves the Quasigroup Completion problem.
     * See http://www.hakank.org/or-tools/quasigroup_completion.py
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("QuasigroupCompletion");

        //
        // data
        //
        Console.WriteLine("Problem:");
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                Console.Write(problem[i, j] + " ");
            }
            Console.WriteLine();
        }
        Console.WriteLine();

        //
        // Decision variables
        //
        IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, n, "x");
        IntVar[] x_flat = x.Flatten();

        //
        // Constraints
        //
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                if (problem[i, j] > X)
                {
                    solver.Add(x[i, j] == problem[i, j]);
                }
            }
        }

        //
        // rows and columns must be different
        //

        // rows
        for (int i = 0; i < n; i++)
        {
            IntVar[] row = new IntVar[n];
            for (int j = 0; j < n; j++)
            {
                row[j] = x[i, j];
            }
            solver.Add(row.AllDifferent());
        }

        // columns
        for (int j = 0; j < n; j++)
        {
            IntVar[] col = new IntVar[n];
            for (int i = 0; i < n; i++)
            {
                col[i] = x[i, j];
            }
            solver.Add(col.AllDifferent());
        }

        //
        // Search
        //
        DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_SIMPLE, Solver.ASSIGN_MIN_VALUE);

        solver.NewSearch(db);

        int sol = 0;

        while (solver.NextSolution())
        {
            sol++;
            Console.WriteLine("Solution #{0} ", sol + " ");
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    Console.Write("{0} ", x[i, j].Value());
                }
                Console.WriteLine();
            }

            Console.WriteLine();
        }

        Console.WriteLine("\nSolutions: {0}", solver.Solutions());
        Console.WriteLine("WallTime: {0}ms", solver.WallTime());
        Console.WriteLine("Failures: {0}", solver.Failures());
        Console.WriteLine("Branches: {0} ", solver.Branches());

        solver.EndSearch();
    }
예제 #25
0
    /**
     *
     * Solves the N-Queens problem.
     *
     * Syntax: nqueens.exe n num print
     * where
     *    n    : size of board
     *    num  : number of solutions to calculate
     *    print: print the results (if > 0)
     *
     */
    private static void Solve(int n = 8, int num = 0, int print = 1)
    {
        Solver solver = new Solver("N-Queens");

        //
        // Decision variables
        //
        IntVar[] q = solver.MakeIntVarArray(n, 0, n - 1, "q");


        //
        // Constraints
        //
        solver.Add(q.AllDifferent());

        IntVar[] q1 = new IntVar[n];
        IntVar[] q2 = new IntVar[n];
        for (int i = 0; i < n; i++)
        {
            q1[i] = (q[i] + i).Var();
            q2[i] = (q[i] - i).Var();
        }
        solver.Add(q1.AllDifferent());
        solver.Add(q2.AllDifferent());

        // Alternative version: it works as well but are not that clear

        /*
         * solver.Add((from i in Enumerable.Range(0, n)
         *          select (q[i] + i).Var()).ToArray().AllDifferent());
         *
         * solver.Add((from i in Enumerable.Range(0, n)
         *          select (q[i] - i).Var()).ToArray().AllDifferent());
         */

        //
        // Search
        //
        DecisionBuilder db = solver.MakePhase(q,
                                              Solver.CHOOSE_MIN_SIZE_LOWEST_MAX,
                                              Solver.ASSIGN_CENTER_VALUE);

        solver.NewSearch(db);
        int c = 0;

        while (solver.NextSolution())
        {
            if (print > 0)
            {
                for (int i = 0; i < n; i++)
                {
                    Console.Write("{0} ", q[i].Value());
                }

                Console.WriteLine();
            }
            c++;
            if (num > 0 && c >= num)
            {
                break;
            }
        }

        Console.WriteLine("\nSolutions: {0}", solver.Solutions());
        Console.WriteLine("WallTime: {0}ms", solver.WallTime());
        Console.WriteLine("Failures: {0}", solver.Failures());
        Console.WriteLine("Branches: {0} ", solver.Branches());

        solver.EndSearch();
    }
예제 #26
0
    //  We don't need helper functions here
    //  Csharp syntax is easier than C++ syntax!

    private static void CPisFun(int kBase)
    {
        //  Constraint Programming engine
        Solver solver = new Solver("CP is fun!");

        // Decision variables
        IntVar c = solver.MakeIntVar(1, kBase - 1, "C");
        IntVar p = solver.MakeIntVar(0, kBase - 1, "P");
        IntVar i = solver.MakeIntVar(1, kBase - 1, "I");
        IntVar s = solver.MakeIntVar(0, kBase - 1, "S");
        IntVar f = solver.MakeIntVar(1, kBase - 1, "F");
        IntVar u = solver.MakeIntVar(0, kBase - 1, "U");
        IntVar n = solver.MakeIntVar(0, kBase - 1, "N");
        IntVar t = solver.MakeIntVar(1, kBase - 1, "T");
        IntVar r = solver.MakeIntVar(0, kBase - 1, "R");
        IntVar e = solver.MakeIntVar(0, kBase - 1, "E");

        // We need to group variables in a vector to be able to use
        // the global constraint AllDifferent
        IntVar[] letters = new IntVar[] { c, p, i, s, f, u, n, t, r, e };

        // Check if we have enough digits
        if (kBase < letters.Length)
        {
            throw new Exception("kBase < letters.Length");
        }

        //  Constraints
        solver.Add(letters.AllDifferent());

        // CP + IS + FUN = TRUE
        solver.Add(p + s + n + kBase * (c + i + u) + kBase * kBase * f ==
                   e + kBase * u + kBase * kBase * r + kBase * kBase * kBase * t);

        SolutionCollector all_solutions = solver.MakeAllSolutionCollector();

        //  Add the interesting variables to the SolutionCollector
        all_solutions.Add(c);
        all_solutions.Add(p);
        //  Create the variable kBase * c + p
        IntVar v1 = solver.MakeSum(solver.MakeProd(c, kBase), p).Var();

        //  Add it to the SolutionCollector
        all_solutions.Add(v1);

        //  Decision Builder: hot to scour the search tree
        DecisionBuilder db = solver.MakePhase(letters,
                                              Solver.CHOOSE_FIRST_UNBOUND,
                                              Solver.ASSIGN_MIN_VALUE);

        solver.Solve(db, all_solutions);

        //  Retrieve the solutions
        int numberSolutions = all_solutions.SolutionCount();

        Console.WriteLine("Number of solutions: " + numberSolutions);

        for (int index = 0; index < numberSolutions; ++index)
        {
            Assignment solution = all_solutions.Solution(index);
            Console.WriteLine("Solution found:");
            Console.WriteLine("v1=" + solution.Value(v1));
        }
    }
예제 #27
0
  /**
   *
   * Solves a Strimko problem.
   * See http://www.hakank.org/google_or_tools/strimko2.py
   *
   */
  private static void Solve()
  {

    Solver solver = new Solver("Strimko2");

    //
    // data
    //
    int[,] streams = {{1,1,2,2,2,2,2},
                      {1,1,2,3,3,3,2},
                      {1,4,1,3,3,5,5},
                      {4,4,3,1,3,5,5},
                      {4,6,6,6,7,7,5},
                      {6,4,6,4,5,5,7},
                      {6,6,4,7,7,7,7}};

    // Note: This is 1-based
    int[,] placed = {{2,1,1},
                     {2,3,7},
                     {2,5,6},
                     {2,7,4},
                     {3,2,7},
                     {3,6,1},
                     {4,1,4},
                     {4,7,5},
                     {5,2,2},
                     {5,6,6}};

    int n = streams.GetLength(0);
    int num_placed = placed.GetLength(0);

    //
    // Decision variables
    //
    IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, n, "x");
    IntVar[] x_flat = x.Flatten();

    //
    // Constraints
    //
    // all rows and columns must be unique, i.e. a Latin Square
    for(int i = 0; i < n; i++) {
      IntVar[] row = new IntVar[n];
      IntVar[] col = new IntVar[n];
      for(int j = 0; j < n; j++) {
        row[j] = x[i,j];
        col[j] = x[j,i];
      }

      solver.Add(row.AllDifferent());
      solver.Add(col.AllDifferent());
    }

    // streams
    for(int s = 1; s <= n; s++) {
      IntVar[] tmp = (from i in Enumerable.Range(0, n)
                      from j in Enumerable.Range(0, n)
                      where streams[i,j] == s
                      select x[i,j]).ToArray();
      solver.Add(tmp.AllDifferent());

    }

    // placed
    for(int i = 0; i <  num_placed; i++) {
      // note: also adjust to 0-based
      solver.Add(x[placed[i,0] - 1,placed[i,1] - 1] ==  placed[i,2]);
    }

    //
    // Search
    //
    DecisionBuilder db = solver.MakePhase(x_flat,
                                          Solver.INT_VAR_DEFAULT,
                                          Solver.INT_VALUE_DEFAULT);

    solver.NewSearch(db);

    while (solver.NextSolution()) {
      for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
          Console.Write(x[i,j].Value() + " ");
        }
        Console.WriteLine();
      }
      Console.WriteLine();
    }

    Console.WriteLine("\nSolutions: {0}", solver.Solutions());
    Console.WriteLine("WallTime: {0}ms", solver.WallTime());
    Console.WriteLine("Failures: {0}", solver.Failures());
    Console.WriteLine("Branches: {0} ", solver.Branches());

    solver.EndSearch();

  }
예제 #28
0
    //  We don't need helper functions here
    //  Csharp syntax is easier than C++ syntax!

    private static void CPisFun (int kBase, int time_limit_param, bool print)
    {

        // Use some profiling and change the default parameters of the solver
        SolverParameters solver_params = new SolverParameters();
        // Change the profile level
        solver_params.profile_level = SolverParameters.NORMAL_PROFILING;

        //  Constraint Programming engine
        Solver solver = new Solver ("CP is fun!", solver_params);

        // Decision variables
        IntVar c = solver.MakeIntVar (1, kBase - 1, "C");
        IntVar p = solver.MakeIntVar (0, kBase - 1, "P");
        IntVar i = solver.MakeIntVar (1, kBase - 1, "I");
        IntVar s = solver.MakeIntVar (0, kBase - 1, "S");
        IntVar f = solver.MakeIntVar (1, kBase - 1, "F");
        IntVar u = solver.MakeIntVar (0, kBase - 1, "U");
        IntVar n = solver.MakeIntVar (0, kBase - 1, "N");
        IntVar t = solver.MakeIntVar (1, kBase - 1, "T");
        IntVar r = solver.MakeIntVar (0, kBase - 1, "R");
        IntVar e = solver.MakeIntVar (0, kBase - 1, "E");

        // We need to group variables in a vector to be able to use
        // the global constraint AllDifferent
        IntVar[] letters = new IntVar[] { c, p, i, s, f, u, n, t, r, e};

        // Check if we have enough digits
        if (kBase < letters.Length) {
          throw new Exception("kBase < letters.Length");
        }

        //  Constraints
        solver.Add (letters.AllDifferent ());

        // CP + IS + FUN = TRUE
        solver.Add (p + s + n + kBase * (c + i + u) + kBase * kBase * f ==
               e + kBase * u + kBase * kBase * r + kBase * kBase * kBase * t);

        SolutionCollector all_solutions = solver.MakeAllSolutionCollector();
        //  Add the interesting variables to the SolutionCollector
        all_solutions.Add(letters);

        //  Decision Builder: hot to scour the search tree
        DecisionBuilder db = solver.MakePhase (letters,
                                               Solver.CHOOSE_FIRST_UNBOUND,
                                               Solver.ASSIGN_MIN_VALUE);

        // Add some time limit
        SearchLimit time_limit = solver.MakeTimeLimit(time_limit_param);

        solver.Solve(db, all_solutions, time_limit);

        //  Retrieve the solutions
        int numberSolutions = all_solutions.SolutionCount();
        Console.WriteLine ("Number of solutions: " + numberSolutions);

        if (print) {
            for (int index = 0; index < numberSolutions; ++index) {
                Console.Write ("C=" + all_solutions.Value(index, c));
                Console.Write (" P=" + all_solutions.Value(index, p));
                Console.Write (" I=" + all_solutions.Value(index, i));
                Console.Write (" S=" + all_solutions.Value(index, s));
                Console.Write (" F=" + all_solutions.Value(index, f));
                Console.Write (" U=" + all_solutions.Value(index, u));
                Console.Write (" N=" + all_solutions.Value(index, n));
                Console.Write (" T=" + all_solutions.Value(index, t));
                Console.Write (" R=" + all_solutions.Value(index, r));
                Console.Write (" E=" + all_solutions.Value(index, e));
                Console.WriteLine ();
            }
        }

        // Save profile in file
        solver.ExportProfilingOverview("profile.txt");
    }
예제 #29
0
    /**
     *
     * Golomb Ruler problem.
     *
     * This C# implementation is based on Charles Prud'homme's
     * or-tools/Java model:
     * http://code.google.com/p/or-tools/source/browse/trunk/com/google/ortools/constraintsolver/samples/GolombRuler.java
     *
     */
    private static void Solve(int m = 8)
    {
        Solver solver = new Solver("GolombRuler");


        //
        // Decision variables
        //
        IntVar[] ticks = solver.MakeIntVarArray(m,
                                                0,
                                                ((m < 31) ? (1 << (m + 1)) - 1 : 9999),
                                                "ticks");

        IntVar[] diff = new IntVar[(m * m - m) / 2];


        //
        // Constraints
        //
        solver.Add(ticks[0] == 0);

        for (int i = 0; i < ticks.Length - 1; i++)
        {
            solver.Add(ticks[i] < ticks[i + 1]);
        }


        for (int k = 0, i = 0; i < m - 1; i++)
        {
            for (int j = i + 1; j < m; j++, k++)
            {
                diff[k] = (ticks[j] - ticks[i]).Var();
                solver.Add(diff[k] >= (j - i) * (j - i + 1) / 2);
            }
        }

        solver.Add(diff.AllDifferent());

        // break symetries
        if (m > 2)
        {
            solver.Add(diff[0] < diff[diff.Length - 1]);
        }


        //
        // Optimization
        //
        OptimizeVar opt = ticks[m - 1].Minimize(1);


        //
        // Search
        //
        DecisionBuilder db = solver.MakePhase(ticks,
                                              Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
                                              Solver.ASSIGN_MIN_VALUE);

        // We just want the debug info for larger instances.
        if (m >= 11)
        {
            SearchMonitor log = solver.MakeSearchLog(10000, opt);
            solver.NewSearch(db, opt, log);
        }
        else
        {
            solver.NewSearch(db, opt);
        }


        while (solver.NextSolution())
        {
            Console.Write("opt: {0}  [ ", ticks[m - 1].Value());
            for (int i = 0; i < m; i++)
            {
                Console.Write("{0} ", ticks[i].Value());
            }
            Console.WriteLine("]");
        }

        Console.WriteLine("\nSolutions: {0}", solver.Solutions());
        Console.WriteLine("WallTime: {0}ms", solver.WallTime());
        Console.WriteLine("Failures: {0}", solver.Failures());
        Console.WriteLine("Branches: {0} ", solver.Branches());

        solver.EndSearch();
    }
예제 #30
0
  /**
   *
   * Cryptarithmetic puzzle.
   * 
   * Prolog benchmark problem GNU Prolog (crypta.pl)
   * """
   * Name           : crypta.pl
   * Title          : crypt-arithmetic
   * Original Source: P. Van Hentenryck's book
   * Adapted by     : Daniel Diaz - INRIA France
   * Date           : September 1992
   *
   * Solve the operation:
   *
   *    B A I J J A J I I A H F C F E B B J E A
   *  + D H F G A B C D I D B I F F A G F E J E
   *  -----------------------------------------
   *  = G J E G A C D D H F A F J B F I H E E F
   * """
   *
   *
   * Also see http://hakank.org/or-tools/crypta.py
   *
   */
  private static void Solve()
  {
    Solver solver = new Solver("Crypta");

    //
    // Decision variables
    //
    IntVar A = solver.MakeIntVar(0, 9, "A");
    IntVar B = solver.MakeIntVar(0, 9, "B");
    IntVar C = solver.MakeIntVar(0, 9, "C");
    IntVar D = solver.MakeIntVar(0, 9, "D");
    IntVar E = solver.MakeIntVar(0, 9, "E");
    IntVar F = solver.MakeIntVar(0, 9, "F");
    IntVar G = solver.MakeIntVar(0, 9, "G");
    IntVar H = solver.MakeIntVar(0, 9, "H");
    IntVar I = solver.MakeIntVar(0, 9, "I");
    IntVar J = solver.MakeIntVar(0, 9, "J");

    IntVar[] LD = new IntVar[] {A,B,C,D,E,F,G,H,I,J};
    
    IntVar Sr1 = solver.MakeIntVar(0, 1, "Sr1");
    IntVar Sr2 = solver.MakeIntVar(0, 1, "Sr2");


    //
    // Constraints
    //
    solver.Add(LD.AllDifferent());
    solver.Add(B >= 1);
    solver.Add(D >= 1);
    solver.Add(G >= 1);

    solver.Add((A+10*E+100*J+1000*B+10000*B+100000*E+1000000*F+
                E+10*J+100*E+1000*F+10000*G+100000*A+1000000*F) ==
               (F+10*E+100*E+1000*H+10000*I+100000*F+1000000*B+10000000*Sr1));


    solver.Add((C+10*F+100*H+1000*A+10000*I+100000*I+1000000*J+
                F+10*I+100*B+1000*D+10000*I+100000*D+1000000*C+Sr1) ==
               (J+10*F+100*A+1000*F+10000*H+100000*D+1000000*D+10000000*Sr2));


    solver.Add((A+10*J+100*J+1000*I+10000*A+100000*B+
                B+10*A+100*G+1000*F+10000*H+100000*D+Sr2) ==
               (C+10*A+100*G+1000*E+10000*J+100000*G));

    //
    // Search
    //
    DecisionBuilder db = solver.MakePhase(LD,
                                          Solver.INT_VAR_DEFAULT,
                                          Solver.INT_VALUE_DEFAULT);

    solver.NewSearch(db);

    while (solver.NextSolution()) {
      for(int i = 0; i < 10; i++) {
        Console.Write(LD[i].ToString() + " ");
      }
      Console.WriteLine();
    }

    Console.WriteLine("\nWallTime: " + solver.WallTime() + "ms ");
    Console.WriteLine("Failures: " + solver.Failures());
    Console.WriteLine("Branches: " + solver.Branches());

    solver.EndSearch();

  }