Beispiel #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();
    }
Beispiel #2
0
    /**
     *
     * Implements the all interval problem.
     * See http://www.hakank.org/google_or_tools/all_interval.py
     *
     */
    private static void Solve(int n = 12)
    {
        Solver solver = new Solver("AllInterval");


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

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

        for (int k = 0; k < n - 1; k++)
        {
            // solver.Add(diffs[k] == (x[k + 1] - x[k]).Abs());
            solver.Add(diffs[k] == (x[k + 1] - x[k].Abs()));
        }


        // symmetry breaking
        solver.Add(x[0] < x[n - 1]);
        solver.Add(diffs[0] < diffs[1]);


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

        solver.NewSearch(db);

        while (solver.NextSolution())
        {
            Console.Write("x: ");
            for (int i = 0; i < n; i++)
            {
                Console.Write("{0} ", x[i].Value());
            }
            Console.Write("  diffs: ");
            for (int i = 0; i < n - 1; i++)
            {
                Console.Write("{0} ", diffs[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();
    }
Beispiel #3
0
    /**
     *
     * Olympic puzzle.
     *
     * Benchmark for Prolog (BProlog)
     * """
     * File   : olympic.pl
     * Author : Neng-Fa ZHOU
     * Date   : 1993
     *
     * Purpose: solve a puzzle taken from Olympic Arithmetic Contest
     *
     * Given ten variables with the following configuration:
     *
     *                 X7   X8   X9   X10
     *
     *                    X4   X5   X6
     *
     *                       X2   X3
     *
     *                          X1
     *
     * We already know that X1 is equal to 3 and want to assign each variable
     * with a different integer from {1,2,...,10} such that for any three
     * variables
     *                        Xi   Xj
     *
     *                           Xk
     *
     * the following constraint is satisfied:
     *
     *                      |Xi-Xj| = Xk
     * """
     *
     * Also see http://www.hakank.org/or-tools/olympic.py
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("Olympic");

        //
        // Data
        //
        int n = 10;

        //
        // Decision variables
        //
        IntVar[] x   = solver.MakeIntVarArray(n, 1, n, "x");
        IntVar   X1  = x[0];
        IntVar   X2  = x[1];
        IntVar   X3  = x[2];
        IntVar   X4  = x[3];
        IntVar   X5  = x[4];
        IntVar   X6  = x[5];
        IntVar   X7  = x[6];
        IntVar   X8  = x[7];
        IntVar   X9  = x[8];
        IntVar   X10 = x[9];

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

        solver.Add(X1 == 3);
        minus(solver, X2, X3, X1);
        minus(solver, X4, X5, X2);
        minus(solver, X5, X6, X3);
        minus(solver, X7, X8, X4);
        minus(solver, X8, X9, X5);
        minus(solver, X9, X10, X6);

        //
        // Search
        //
        DecisionBuilder db = solver.MakePhase(x, Solver.INT_VAR_SIMPLE, Solver.INT_VALUE_DEFAULT);

        solver.NewSearch(db);

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

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

        solver.EndSearch();
    }
Beispiel #4
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();

  }
Beispiel #5
0
    /**
     *
     * Place number puzzle.
     *
     * From
     * http://ai.uwaterloo.ca/~vanbeek/Courses/Slides/introduction.pdf
     * """
     * Place numbers 1 through 8 on nodes
     * - each number appears exactly once
     * - no connected nodes have consecutive numbers
     *       2 - 5
     *     / | X |                                \
     *   1 - 3 - 6 - 8
     *     \ | X | /
     *       4 - 7
     * """
     *
     * Also see http://www.hakank.org/or-tools/place_number_puzzle.py
     *
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("PlaceNumberPuzzle");

        //
        // Data
        //
        int m = 32;
        int n = 8;

        // Note: this is 1-based for compatibility (and lazyness)
        int[,] graph = { { 1, 2 }, { 1, 3 }, { 1, 4 }, { 2, 1 }, { 2, 3 }, { 2, 5 }, { 2, 6 },
                         { 3, 2 }, { 3, 4 }, { 3, 6 }, { 3, 7 }, { 4, 1 }, { 4, 3 }, { 4, 6 },
                         { 4, 7 }, { 5, 2 }, { 5, 3 }, { 5, 6 }, { 5, 8 }, { 6, 2 }, { 6, 3 },
                         { 6, 4 }, { 6, 5 }, { 6, 7 }, { 6, 8 }, { 7, 3 }, { 7, 4 }, { 7, 6 },
                         { 7, 8 }, { 8, 5 }, { 8, 6 }, { 8, 7 } };

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

        //
        // Constraints
        //
        solver.Add(x.AllDifferent());
        for (int i = 0; i < m; i++)
        {
            // (also base 0-base)
            solver.Add((x[graph[i, 0] - 1] - x[graph[i, 1] - 1]).Abs() > 1);
        }

        // symmetry breaking
        solver.Add(x[0] < x[n - 1]);

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

        solver.NewSearch(db);

        while (solver.NextSolution())
        {
            Console.Write("x: ");
            for (int i = 0; i < n; 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();
    }
Beispiel #6
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();
    }
Beispiel #7
0
    /**
     *
     * Secret Santa problem in Google CP Solver.
     *
     * From Ruby Quiz Secret Santa
     * http://www.rubyquiz.com/quiz2.html
     * """
     * Honoring a long standing tradition started by my wife's dad, my friends
     * all play a Secret Santa game around Christmas time. We draw names and
     * spend a week sneaking that person gifts and clues to our identity. On the
     * last night of the game, we get together, have dinner, share stories, and,
     * most importantly, try to guess who our Secret Santa was. It's a crazily
     * fun way to enjoy each other's company during the holidays.
     *
     * To choose Santas, we use to draw names out of a hat. This system was
     * tedious, prone to many 'Wait, I got myself...' problems. This year, we
     * made a change to the rules that further complicated picking and we knew
     * the hat draw would not stand up to the challenge. Naturally, to solve
     * this problem, I scripted the process. Since that turned out to be more
     * interesting than I had expected, I decided to share.
     *
     * This weeks Ruby Quiz is to implement a Secret Santa selection script.
     * *  Your script will be fed a list of names on STDIN.
     * ...
     * Your script should then choose a Secret Santa for every name in the list.
     * Obviously, a person cannot be their own Secret Santa. In addition, my
     * friends no longer allow people in the same family to be Santas for each
     * other and your script should take this into account.
     * """
     *
     *  Comment: This model skips the file input and mail parts. We
     *        assume that the friends are identified with a number from 1..n,
     *        and the families is identified with a number 1..num_families.
     *
     * Also see http://www.hakank.org/or-tools/secret_santa.py
     * Also see http://www.hakank.org/or-tools/secret_santa2.cs
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("SecretSanta");

        int[] family = { 1, 1, 1, 1, 2, 3, 3, 3, 3, 3, 4, 4 };
        int   n      = family.Length;

        Console.WriteLine("n = {0}", n);

        IEnumerable <int> RANGE = Enumerable.Range(0, n);

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

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

        // Can't be one own"s Secret Santa
        // (i.e. ensure that there are no fix-point in the array.)
        foreach (int i in RANGE)
        {
            solver.Add(x[i] != i);
        }

        // No Secret Santa to a person in the same family
        foreach (int i in RANGE)
        {
            solver.Add(solver.MakeIntConst(family[i]) != family.Element(x[i]));
        }

        //
        // Search
        //
        DecisionBuilder db = solver.MakePhase(x, Solver.INT_VAR_SIMPLE, Solver.INT_VALUE_SIMPLE);

        solver.NewSearch(db);

        while (solver.NextSolution())
        {
            Console.Write("x:  ");
            foreach (int i in RANGE)
            {
                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();
    }
    /**
     *
     * Scheduling speakers problem
     *
     *  From Rina Dechter, Constraint Processing, page 72
     *  Scheduling of 6 speakers in 6 slots.
     *
     * See http://www.hakank.org/google_or_tools/scheduling_speakers.py
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("SchedulingSpeakers");


        // number of speakers
        int n = 6;

        // slots available to speak
        int[][] available =
        {
            // Reasoning:
            new int[] { 3, 4, 5, 6 }, // 2) the only one with 6 after speaker F -> 1
            new int[] { 3,4 }, // 5) 3 or 4
            new int[] { 2, 3, 4, 5 }, // 3) only with 5 after F -> 1 and A -> 6
            new int[] { 2, 3,4 }, // 4) only with 2 after C -> 5 and F -> 1
            new int[] { 3,4 }, // 5) 3 or 4
            new int[] { 1, 2, 3,4, 5, 6 } // 1) the only with 1
        };


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

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

        for (int i = 0; i < n; i++)
        {
            solver.Add(x[i].Member(available[i]));
        }


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

        solver.NewSearch(db);

        while (solver.NextSolution())
        {
            Console.WriteLine(string.Join(",", (from i in x select i.Value())));
        }

        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();
    }
Beispiel #9
0
  /**
   *
   * Implements the all interval problem.
   * See http://www.hakank.org/google_or_tools/all_interval.py
   *
   */
  private static void Solve(int n=12)
  {
    Solver solver = new Solver("AllInterval");


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

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

    for(int k = 0; k < n - 1; k++) {
      // solver.Add(diffs[k] == (x[k + 1] - x[k]).Abs());
      solver.Add(diffs[k] == (x[k + 1] - x[k].Abs()));
    }


    // symmetry breaking
    solver.Add(x[0] < x[n - 1]);
    solver.Add(diffs[0] < diffs[1]);


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

    solver.NewSearch(db);

    while (solver.NextSolution()) {
      Console.Write("x: ");
      for(int i = 0; i < n; i++) {
          Console.Write("{0} ", x[i].Value());
      }
      Console.Write("  diffs: ");
      for(int i = 0; i < n-1; i++) {
          Console.Write("{0} ", diffs[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();

  }
Beispiel #10
0
    /**
     *
     * Decomposition of alldifferent_except_0
     *
     * See http://www.hakank.org/google_or_tools/map.py
     *
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("AllDifferentExcept0");

        //
        // data
        //
        int n = 6;

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

        //
        // Constraints
        //
        AllDifferentExcept0(solver, x);

        // we also require at least 2 0's
        IntVar[] z_tmp = new IntVar[n];
        for (int i = 0; i < n; i++)
        {
            z_tmp[i] = x[i] == 0;
        }
        IntVar z = z_tmp.Sum().VarWithName("z");

        solver.Add(z == 2);


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

        solver.NewSearch(db);
        while (solver.NextSolution())
        {
            Console.Write("z: {0}  x: ", z.Value());
            for (int i = 0; i < n; i++)
            {
                Console.Write("{0} ", 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();
    }
Beispiel #11
0
    private static long Solve(long num_buses_check = 0)
    {
        SolverParameters sPrm = new SolverParameters();

        sPrm.compress_trail = 0;
        sPrm.trace_level    = 0;
        sPrm.profile_level  = 0;
        Solver solver = new Solver("OrTools", sPrm);

        //this works
        // IntVar[,] x = solver.MakeIntVarMatrix(2,2, new int[] {-2,0,1,2}, "x");

        //this doesn't work
        IntVar[,] x = solver.MakeIntVarMatrix(2, 2, new int[] { 0, 1, 2 }, "x");

        for (int w = 0; w < 2; w++)
        {
            IntVar[] b = new IntVar[2];
            for (int i = 0; i < 2; i++)
            {
                b[i] = solver.MakeIsEqualCstVar(x[w, i], 0);
            }
            solver.Add(solver.MakeSumGreaterOrEqual(b, 2));
        }

        IntVar[]        x_flat = x.Flatten();
        DecisionBuilder db     = solver.MakePhase(x_flat,
                                                  Solver.CHOOSE_FIRST_UNBOUND,
                                                  Solver.ASSIGN_MIN_VALUE);

        solver.NewSearch(db);
        while (solver.NextSolution())
        {
            Console.WriteLine("x: ");
            for (int j = 0; j < 2; j++)
            {
                Console.Write("worker" + (j + 1).ToString() + ":");
                for (int i = 0; i < 2; i++)
                {
                    Console.Write(" {0,2} ", x[j, i].Value());
                }
                Console.Write("\n");
            }
            Console.WriteLine("End   at---->" + DateTime.Now);
        }

        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(1);
    }
Beispiel #12
0
        /*
         * Main Method:
         */

        public static void Solve()
        {
            var solver = new Solver("Cryptogram");

            // One 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 = { 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);

            // All characters take different values:
            solver.Add(vars.AllDifferent());

            // Start Solver:

            DecisionBuilder db = solver.MakePhase(vars, Solver.INT_VAR_SIMPLE, Solver.INT_VALUE_SIMPLE);

            solver.NewSearch(db);

            while (solver.NextSolution())
            {
                Console.WriteLine(send.Value() + " + " + more.Value() + " = " + money.Value() + "\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();

            Console.ReadKey();
        }
Beispiel #13
0
    /**
     *
     * Subset sum problem.
     *
     * From Katta G. Murty: 'Optimization Models for Decision Making', page 340
     * http://ioe.engin.umich.edu/people/fac/books/murty/opti_model/junior-7.pdf
     * """
     * Example 7.8.1
     *
     * A bank van had several bags of coins, each containing either
     * 16, 17, 23, 24, 39, or 40 coins. While the van was parked on the
     * street, thieves stole some bags. A total of 100 coins were lost.
     * It is required to find how many bags were stolen.
     * """
     *
     * Also see http://www.hakank.org/or-tools/subset_sum.py
     *
     */
    private static void Solve(int[] coins, int total)
    {
        Solver solver = new Solver("SubsetSum");

        int n = coins.Length;

        Console.Write("Coins: ");
        for (int i = 0; i < n; i++)
        {
            Console.Write(coins[i] + " ");
        }
        Console.WriteLine("\nTotal: {0}", total);

        //
        // Variables
        //
        // number of coins
        IntVar s = solver.MakeIntVar(0, coins.Sum(), "s");


        //
        // Constraints
        //
        IntVar[] x = subset_sum(solver, coins, total);
        solver.Add(x.Sum() == s);


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

        solver.NewSearch(db);

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

        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();
    }
Beispiel #14
0
    /**
     *
     * Magic sequence problem.
     *
     * This is a port of the Python model
     * https://code.google.com/p/or-tools/source/browse/trunk/python/magic_sequence_distribute.py
     * """
     * This models aims at building a sequence of numbers such that the number of
     * occurrences of i in this sequence is equal to the value of the ith number.
     * It uses an aggregated formulation of the count expression called
     * distribute().
     * """
     *
     */
    private static void Solve(int size)
    {
        Solver solver = new Solver("MagicSequence");

        Console.WriteLine("\nSize: {0}", size);

        //
        // data
        //
        int[] all_values = new int[size];
        for (int i = 0; i < size; i++)
        {
            all_values[i] = i;
        }

        //
        // Decision variables
        //
        IntVar[] all_vars = solver.MakeIntVarArray(size, 0, size - 1, "vars");

        //
        // Constraints
        //
        solver.Add(all_vars.Distribute(all_values, all_vars));
        solver.Add(all_vars.Sum() == size);


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

        solver.NewSearch(db);

        while (solver.NextSolution())
        {
            for (int i = 0; i < size; i++)
            {
                Console.Write(all_vars[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();
    }
Beispiel #15
0
    /**
     *
     * Dudeney numbers
     * From Pierre Schaus blog post
     * Dudeney number
     * http://cp-is-fun.blogspot.com/2010/09/test-python.html
     * """
     * I discovered yesterday Dudeney Numbers
     * A Dudeney Numbers is a positive integer that is a perfect cube such that the sum
     * of its decimal digits is equal to the cube root of the number. There are only six
     * Dudeney Numbers and those are very easy to find with CP.
     * I made my first experience with google cp solver so find these numbers (model below)
     * and must say that I found it very convenient to build CP models in python!
     * When you take a close look at the line:
     *     solver.Add(sum([10**(n-i-1)*x[i] for i in range(n)]) == nb)
     * It is difficult to argue that it is very far from dedicated
     * optimization languages!
     * """
     *
     * Also see: http://en.wikipedia.org/wiki/Dudeney_number
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("DudeneyNumbers");

        //
        // data
        //
        int n = 6;

        //
        // Decision variables
        //
        IntVar[] x  = solver.MakeIntVarArray(n, 0, 9, "x");
        IntVar   nb = solver.MakeIntVar(3, (int)Math.Pow(10, n), "nb");
        IntVar   s  = solver.MakeIntVar(1, 9 * n + 1, "s");

        //
        // Constraints
        //
        solver.Add(nb == s * s * s);
        solver.Add(x.Sum() == s);

        // solver.Add(ToNum(x, nb, 10));

        // alternative
        solver.Add((from i in Enumerable.Range(0, n)
                    select(x[i] * (int)Math.Pow(10, n - i - 1)).Var()).
                   ToArray().Sum() == nb);


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


        solver.NewSearch(db);

        while (solver.NextSolution())
        {
            Console.WriteLine(nb.Value());
        }

        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();
    }
Beispiel #16
0
    private static long Solve(long num_buses_check = 0)
    {
        SolverParameters sPrm = new SolverParameters();
        sPrm.compress_trail = 0;
        sPrm.trace_level = 0;
        sPrm.profile_level = 0;
        Solver solver = new Solver("OrTools",sPrm);

        //this works
        // IntVar[,] x = solver.MakeIntVarMatrix(2,2, new int[] {-2,0,1,2}, "x");

        //this doesn't work
        IntVar[,] x = solver.MakeIntVarMatrix(2, 2, new int[] { 0, 1, 2 }, "x");

        for (int w = 0; w < 2; w++)
        {
          IntVar[] b = new IntVar[2];
          for (int i = 0; i < 2; i++)
          {
        b[i] = solver.MakeIsEqualCstVar(x[w, i], 0);
          }
          solver.Add(solver.MakeSumGreaterOrEqual(b, 2));
        }

        IntVar[] x_flat = x.Flatten();
        DecisionBuilder db = solver.MakePhase(x_flat,
                                          Solver.CHOOSE_FIRST_UNBOUND,
                                          Solver.ASSIGN_MIN_VALUE);
        solver.NewSearch(db);
        while (solver.NextSolution())
        {
          Console.WriteLine("x: ");
          for (int j = 0; j < 2; j++)
          {
        Console.Write("worker" + (j + 1).ToString() + ":");
        for (int i = 0; i < 2; i++)
        {
          Console.Write(" {0,2} ", x[j, i].Value());
        }
        Console.Write("\n");
          }
          Console.WriteLine("End   at---->" + DateTime.Now);
        }

        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 1;
    }
Beispiel #17
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();
    }
Beispiel #18
0
  /**
   *
   * Magic sequence problem.
   *
   * This is a port of the Python model
   * https://code.google.com/p/or-tools/source/browse/trunk/python/magic_sequence_distribute.py
   * """
   * This models aims at building a sequence of numbers such that the number of
   * occurrences of i in this sequence is equal to the value of the ith number.
   * It uses an aggregated formulation of the count expression called
   * distribute().
   * """
   *
   */
  private static void Solve(int size)
  {

    Solver solver = new Solver("MagicSequence");

    Console.WriteLine("\nSize: {0}", size);

    //
    // data
    //
    int[] all_values = new int[size];
    for (int i = 0; i < size; i++) {
      all_values[i] = i;
    }

    //
    // Decision variables
    //
    IntVar[] all_vars  = solver.MakeIntVarArray(size, 0, size - 1, "vars");

    //
    // Constraints
    //
    solver.Add(all_vars.Distribute(all_values, all_vars));
    solver.Add(all_vars.Sum() == size);


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

    solver.NewSearch(db);

    while (solver.NextSolution()) {
      for(int i = 0; i < size; i++) {
        Console.Write(all_vars[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();

  }
Beispiel #19
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();

  }
Beispiel #20
0
        /*
         * Create Constraint Model and Solve Coloring Problem:
         */

        public static void SolveAsConstraintProblem(int nbColors, int nbNodes, IEnumerable <Tuple <int, int> > edges)
        {
            var solver = new Solver("Coloring");

            // One Decision Variable per Node:
            IntVar[] nodes = solver.MakeIntVarArray(nbNodes, 0, nbColors - 1);

            foreach (var edge in edges)
            {
                solver.Add(nodes[edge.Item1] != nodes[edge.Item2]);
            }

            // Some Symmetry breaking
            solver.Add(nodes[0] == 0);

            /*
             * Start Solver:
             */

            DecisionBuilder db = solver.MakePhase(nodes, Solver.INT_VAR_SIMPLE, Solver.INT_VALUE_SIMPLE);

            Console.WriteLine("Coloring Problem:\n\n");

            solver.NewSearch(db);

            while (solver.NextSolution())
            {
                for (int i = 0; i < nodes.Length; i++)
                {
                    if (i < Names.Length)
                    {
                        Console.WriteLine("Node " + i + " obtains color " + Names.GetValue(nodes[i].Value()));
                    }
                    else
                    {
                        Console.WriteLine("Node " + i + " obtains color " + nodes[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();

            Console.ReadKey();
        }
Beispiel #21
0
    /**
     *
     * Global constraint contiguity using regular
     *
     * This is a decomposition of the global constraint global contiguity.
     *
     * From Global Constraint Catalogue
     * http://www.emn.fr/x-info/sdemasse/gccat/Cglobal_contiguity.html
     * """
     * Enforce all variables of the VARIABLES collection to be assigned to 0 or 1.
     * In addition, all variables assigned to value 1 appear contiguously.
     *
     * Example:
     * (<0, 1, 1, 0>)
     *
     * The global_contiguity constraint holds since the sequence 0 1 1 0 contains
     * no more than one group of contiguous 1.
     * """
     *
     * Also see http://www.hakank.org/or-tools/contiguity_regular.py
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("ContiguityRegular");

        //
        // Data
        //
        int n = 7; // length of the array


        //
        // Decision variables
        //

        // Note: We use 1..2 (instead of 0..1) and subtract 1 in the solution
        IntVar[] reg_input = solver.MakeIntVarArray(n, 1, 2, "reg_input");


        //
        // Constraints
        //
        MyContiguity(solver, reg_input);


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

        solver.NewSearch(db);

        while (solver.NextSolution())
        {
            for (int i = 0; i < n; i++)
            {
                // Note: here we subtract 1 to get 0..1
                Console.Write((reg_input[i].Value() - 1) + " ");
            }
            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();
    }
Beispiel #22
0
    /**
     *
     * Implements a (decomposition) of the global constraint circuit
     * and extracting the path.
     *
     * One circuit for n = 5 is    3 0 4 2 1
     * Thus the extracted path is  0 -> 3 -> 2 -> 4 -> 1 -> 0
     *
     */
    private static void Solve(int n = 5)
    {
        Solver solver = new Solver("CircuitTest2");


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

        //
        // Constraints
        //
        circuit(solver, x, path);



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


        solver.NewSearch(db);

        while (solver.NextSolution())
        {
            Console.Write("x   : ");
            for (int i = 0; i < n; i++)
            {
                Console.Write("{0} ", x[i].Value());
            }
            Console.Write("\npath: ");
            for (int i = 0; i < n; i++)
            {
                Console.Write("{0} ", path[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();
    }
Beispiel #23
0
    /**
     *
     * Implements toNum: channeling between a number and an array.
     * See http://www.hakank.org/or-tools/toNum.py
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("ToNum");

        int n     = 5;
        int bbase = 10;

        //
        // Decision variables
        //
        IntVar[] x   = solver.MakeIntVarArray(n, 0, bbase - 1, "x");
        IntVar   num = solver.MakeIntVar(0, (int)Math.Pow(bbase, n) - 1, "num");

        //
        // Constraints
        //

        solver.Add(x.AllDifferent());
        solver.Add(ToNum(x, num, bbase));

        // extra constraint (just for fun)
        // second digit should be 7
        // solver.Add(x[1] == 7);

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

        solver.NewSearch(db);

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

        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();
    }
Beispiel #24
0
        /*
         * Xkcd Puzzle as Optimization Problem:
         */

        private static void OptimizationModel(Solver solver, IntVar[] items, int[] prices)
        {
            /*
             * Objective Function:
             */

            IntVar obj = solver.MakeScalProd(items, prices).Var();

            /*
             * Constraints:
             */

            solver.Add(obj < 2000);

            /*
             * Start Solver:
             */

            DecisionBuilder db = solver.MakePhase(items, Solver.INT_VAR_SIMPLE, Solver.INT_VALUE_SIMPLE);

            SolutionCollector col = solver.MakeBestValueSolutionCollector(true);

            col.AddObjective(obj);
            col.Add(items);

            Console.WriteLine("Xkcd Optimization Problem:\n");

            if (solver.Solve(db, col))
            {
                Assignment sol = col.Solution(0);
                Console.WriteLine("Maximum value found: " + sol.ObjectiveValue() + "\n");

                for (int i = 0; i < items.Length; i++)
                {
                    Console.WriteLine("Appetizer " + items[i].Name() + " is ordered " + sol.Value(items[i]) + " times.");
                }

                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();

            Console.ReadKey();
        }
        /*
         * Main Method:
         */

        public static void Solve()
        {
            var solver = new Solver("Grocery");

            // One variable for each product:

            IntVar p1 = solver.MakeIntVar(0, 711);
            IntVar p2 = solver.MakeIntVar(0, 711);
            IntVar p3 = solver.MakeIntVar(0, 711);
            IntVar p4 = solver.MakeIntVar(0, 711);

            // Prices add up to 711:

            solver.Add(p1 + p2 + p3 + p4 == 711);

            // Product of individual prices is 711:

            solver.Add(p1 * p2 * p3 * p4 == 711 * 100 * 100 * 100);

            // Symmetry breaking constraint:

            /*solver.Add(p1 <= p2);
            *  solver.Add(p2 <= p3);
            *  solver.Add(p3 <= p4);*/

            // Start Solver:

            DecisionBuilder db = solver.MakePhase(new[] { p1, p2, p3, p4 }, Solver.INT_VAR_SIMPLE, Solver.INT_VALUE_SIMPLE);

            solver.NewSearch(db);

            while (solver.NextSolution())
            {
                Console.WriteLine("Product 1: " + p1.Value());
                Console.WriteLine("Product 2: " + p2.Value());
                Console.WriteLine("Product 3: " + p3.Value());
                Console.WriteLine("Product 4: " + p4.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();

            Console.ReadKey();
        }
Beispiel #26
0
    /**
     *
     * Grocery problem.
     *
     * From  Christian Schulte, Gert Smolka, Finite Domain
     * http://www.mozart-oz.org/documentation/fdt/
     * Constraint Programming in Oz. A Tutorial. 2001.
     * """
     * A kid goes into a grocery store and buys four items. The cashier
     * charges $7.11, the kid pays and is about to leave when the cashier
     * calls the kid back, and says 'Hold on, I multiplied the four items
     * instead of adding them; I'll try again; Hah, with adding them the
     * price still comes to $7.11'. What were the prices of the four items?
     * """
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("Grocery");

        int n = 4;
        int c = 711;

        //
        // Decision variables
        //

        IntVar[] item = solver.MakeIntVarArray(n, 0, c / 2, "item");

        //
        // Constraints
        //
        solver.Add(item.Sum() == c);
        // solver.Add(item[0] * item[1] * item[2] * item[3] == c * 100*100*100);
        // solver.Add(item.Prod() == c * 100*100*100);
        solver.Add(MyProd(item, c * 100 * 100 * 100));


        // Symmetry breaking
        Decreasing(solver, item);

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

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

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

        solver.EndSearch();
    }
Beispiel #27
0
    /**
     *
     * Solve the xkcd problem
     * See http://www.hakank.org/google_or_tools/xkcd.py
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("Xkcd");

        //
        // Constants, inits
        //
        int n = 6;

        // for price and total: multiplied by 100 to be able to use integers
        int[] price = { 215, 275, 335, 355, 420, 580 };
        int   total = 1505;

        //
        // Decision variables
        //
        IntVar[] x = solver.MakeIntVarArray(n, 0, 10, "x");

        //
        // Constraints
        //
        solver.Add(x.ScalProd(price) == total);

        //
        // 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 < n; 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();
    }
Beispiel #28
0
  /**
   *
   * Solve the xkcd problem
   * See http://www.hakank.org/google_or_tools/xkcd.py
   *
   */
  private static void Solve()
  {
    Solver solver = new Solver("Xkcd");

    //
    // Constants, inits
    //
    int n = 6;
    // for price and total: multiplied by 100 to be able to use integers
    int[] price = {215, 275, 335, 355, 420, 580};
    int total = 1505;

    //
    // Decision variables
    //
    IntVar[] x = solver.MakeIntVarArray(n, 0, 10, "x");

    //
    // Constraints
    //
    solver.Add(x.ScalProd(price) == total);

    //
    // 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 < n; 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();

  }
Beispiel #29
0
    /**
     * Solves the rabbits + pheasants problem.  We are seing 20 heads
     * and 56 legs. How many rabbits and how many pheasants are we thus
     * seeing?
     */
    private static void Solve()
    {
        Solver solver    = new Solver("RabbitsPheasants");
        IntVar rabbits   = solver.MakeIntVar(0, 100, "rabbits");
        IntVar pheasants = solver.MakeIntVar(0, 100, "pheasants");

        solver.Add(rabbits + pheasants == 20);
        solver.Add(rabbits * 4 + pheasants * 2 == 56);
        DecisionBuilder db = new AssignFirstUnboundToMin(new IntVar[] { rabbits, pheasants });

        solver.NewSearch(db);
        solver.NextSolution();
        Console.WriteLine("Solved Rabbits + Pheasants in {0} ms, and {1} search tree branches.", solver.WallTime(),
                          solver.Branches());
        Console.WriteLine(rabbits.ToString());
        Console.WriteLine(pheasants.ToString());
        solver.EndSearch();
    }
 /**
  * Solves the rabbits + pheasants problem.  We are seing 20 heads
  * and 56 legs. How many rabbits and how many pheasants are we thus
  * seeing?
  */
 private static void Solve()
 {
   Solver solver = new Solver("RabbitsPheasants");
   IntVar rabbits = solver.MakeIntVar(0, 100, "rabbits");
   IntVar pheasants = solver.MakeIntVar(0, 100, "pheasants");
   solver.Add(rabbits + pheasants == 20);
   solver.Add(rabbits * 4 + pheasants * 2 == 56);
   DecisionBuilder db =
       new AssignFirstUnboundToMin(new IntVar[] {rabbits, pheasants});
   solver.NewSearch(db);
   solver.NextSolution();
   Console.WriteLine(
       "Solved Rabbits + Pheasants in {0} ms, and {1} search tree branches.",
       solver.WallTime(),  solver.Branches());
   Console.WriteLine(rabbits.ToString());
   Console.WriteLine(pheasants.ToString());
   solver.EndSearch();
 }
Beispiel #31
0
        /*
         * Xkcd Puzzle as Constraint Problem:
         */

        private static void ConstraintModel(Solver solver, IntVar[] items, int[] prices)
        {
            /*
             * Constraints:
             */

            solver.Add(solver.MakeScalProd(items, prices) == 1505);

            /*
             * Start Solver:
             */

            DecisionBuilder db = solver.MakePhase(items, Solver.INT_VAR_SIMPLE, Solver.INT_VALUE_SIMPLE);

            Console.WriteLine("XKCD Constraint Problem:\n\n");

            solver.NewSearch(db);

            while (solver.NextSolution())
            {
                for (int i = 0; i < items.Length; i++)
                {
                    Console.WriteLine("Appetizer " + items[i].Name() + " is ordered " + items[i].Value() + " times.");
                }

                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();

            Console.ReadKey();
        }
Beispiel #32
0
    /**
       *
       *
       * Organizing a day.
       *
       * Simple scheduling problem.
       *
       * Problem formulation from ECLiPSe:
       * Slides on (Finite Domain) Constraint Logic Programming, page 38f
       * http://eclipse-clp.org/reports/eclipse.ppt
       *
       *
       * Also see http://www.hakank.org/google_or_tools/organize_day.py
       *
       */
    private static void Solve()
    {
        Solver solver = new Solver("OrganizeDay");

        int n = 4;

        int work = 0;
        int mail = 1;
        int shop = 2;
        int bank = 3;
        int[] tasks = {work, mail, shop, bank};
        int[] durations = {4,1,2,1};

        // task [i,0] must be finished before task [i,1]
        int[,] before_tasks = {
          {bank, shop},
          {mail, work}
        };

        // the valid times of the day
        int begin = 9;
        int end   = 17;

        //
        // Decision variables
        //
        IntVar[] begins = solver.MakeIntVarArray(n, begin, end, "begins");
        IntVar[] ends = solver.MakeIntVarArray(n, begin, end, "ends");

        //
        // Constraints
        //
        foreach(int t in tasks) {
          solver.Add(ends[t] == begins[t] + durations[t]);
        }

        foreach(int i in tasks) {
          foreach(int j in tasks) {
        if (i < j) {
          NoOverlap(solver,
                    begins[i], durations[i],
                    begins[j], durations[j]);
        }
          }
        }

        // specific constraints
        for(int t = 0; t < before_tasks.GetLength(0); t++) {
          solver.Add(ends[before_tasks[t,0]] <= begins[before_tasks[t,1]]);
        }

        solver.Add(begins[work] >= 11);

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

        solver.NewSearch(db);

        while (solver.NextSolution()) {
          foreach(int t in tasks) {
        Console.WriteLine("Task {0}: {1,2} .. ({2}) .. {3,2}",
                          t,
                          begins[t].Value(),
                          durations[t],
                          ends[t].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();
    }
Beispiel #33
0
  /**
   *
   * KenKen puzzle.
   *
   * http://en.wikipedia.org/wiki/KenKen
   * """
   * KenKen or KEN-KEN is a style of arithmetic and logical puzzle sharing
   * several characteristics with sudoku. The name comes from Japanese and
   * is translated as 'square wisdom' or 'cleverness squared'.
   * ...
   * The objective is to fill the grid in with the digits 1 through 6 such that:
   *
   * * Each row contains exactly one of each digit
   * * Each column contains exactly one of each digit
   * * Each bold-outlined group of cells is a cage containing digits which
   *   achieve the specified result using the specified mathematical operation:
   *     addition (+),
   *     subtraction (-),
   *     multiplication (x),
   *     and division (/).
   *    (Unlike in Killer sudoku, digits may repeat within a group.)
   *
   * ...
   * More complex KenKen problems are formed using the principles described
   * above but omitting the symbols +, -, x and /, thus leaving them as
   * yet another unknown to be determined.
   * """
   *
   * The solution is:
   *
   *    5 6 3 4 1 2
   *    6 1 4 5 2 3
   *    4 5 2 3 6 1
   *    3 4 1 2 5 6
   *    2 3 6 1 4 5
   *    1 2 5 6 3 4
   *
   *
   * Also see http://www.hakank.org/or-tools/kenken2.py
   * though this C# model has another representation of
   * the problem instance.
   *
   */
  private static void Solve()
  {

    Solver solver = new Solver("KenKen2");

    // size of matrix
    int n = 6;
    IEnumerable<int> RANGE = Enumerable.Range(0, n);

    // For a better view of the problem, see
    //  http://en.wikipedia.org/wiki/File:KenKenProblem.svg

    // hints
    //  sum, the hints
    // Note: this is 1-based
    int[][] problem =
      {
        new int[] { 11,  1,1, 2,1},
        new int[] {  2,  1,2, 1,3},
        new int[] { 20,  1,4, 2,4},
        new int[] {  6,  1,5, 1,6, 2,6, 3,6},
        new int[] {  3,  2,2, 2,3},
        new int[] {  3,  2,5, 3,5},
        new int[] {240,  3,1, 3,2, 4,1, 4,2},
        new int[] {  6,  3,3, 3,4},
        new int[] {  6,  4,3, 5,3},
        new int[] {  7,  4,4, 5,4, 5,5},
        new int[] { 30,  4,5, 4,6},
        new int[] {  6,  5,1, 5,2},
        new int[] {  9,  5,6, 6,6},
        new int[] {  8,  6,1, 6,2, 6,3},
        new int[] {  2,  6,4, 6,5}
      };


    int num_p = problem.GetLength(0); // Number of segments

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

    //
    // Constraints
    //

    //
    //  alldifferent rows and columns
    foreach(int i in RANGE) {
      // rows
      solver.Add( (from j in RANGE select x[i,j]).ToArray().AllDifferent());

      // cols
      solver.Add( (from j in RANGE select x[j,i]).ToArray().AllDifferent());

    }


    // Calculate the segments
    for(int i = 0; i < num_p; i++) {

      int[] segment = problem[i];

      // Remove the sum from the segment
      int len = segment.Length-1;
      int[] s2 = new int[len];
      Array.Copy(segment, 1, s2, 0, len);

      // sum this segment
      calc(solver, s2, x, segment[0]);

    }

    //
    // 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();

  }
Beispiel #34
0
  /**
   *
   * Crypto problem.
   * 
   * This is the standard benchmark "crypto" problem.
   *
   * From GLPK:s model cryto.mod.
   *
   * """
   * This problem comes from the newsgroup rec.puzzle.
   * The numbers from 1 to 26 are assigned to the letters of the alphabet.
   * The numbers beside each word are the total of the values assigned to
   * the letters in the word (e.g. for LYRE: L, Y, R, E might be to equal
   * 5, 9, 20 and 13, or any other combination that add up to 47).
   * Find the value of each letter under the equations:
   *
   * BALLET  45     GLEE  66     POLKA      59     SONG     61
   * CELLO   43     JAZZ  58     QUARTET    50     SOPRANO  82
   * CONCERT 74     LYRE  47     SAXOPHONE 134     THEME    72
   * FLUTE   30     OBOE  53     SCALE      51     VIOLIN  100
   * FUGUE   50     OPERA 65     SOLO       37     WALTZ    34
   *
   * Solution:
   * A, B,C, D, E,F, G, H, I, J, K,L,M, N, O, P,Q, R, S,T,U, V,W, X, Y, Z
   * 5,13,9,16,20,4,24,21,25,17,23,2,8,12,10,19,7,11,15,3,1,26,6,22,14,18
   *
   * Reference:
   * Koalog Constraint Solver <http://www.koalog.com/php/jcs.php>,
   * Simple problems, the crypto-arithmetic puzzle ALPHACIPHER.
   * """
   *
   * Also see http://hakank.org/or-tools/crypto.py
   *
   */
  private static void Solve()
  {
    Solver solver = new Solver("Crypto");

    int num_letters = 26;

    int BALLET     =  45;
    int CELLO      =  43;
    int CONCERT    =  74;
    int FLUTE      =  30;
    int FUGUE      =  50;
    int GLEE       =  66;
    int JAZZ       =  58;
    int LYRE       =  47;
    int OBOE       =  53;
    int OPERA      =  65;
    int POLKA      =  59;
    int QUARTET    =  50;
    int SAXOPHONE  = 134;
    int SCALE      =  51;
    int SOLO       =  37;
    int SONG       =  61;
    int SOPRANO    =  82;
    int THEME      =  72;
    int VIOLIN     = 100;
    int WALTZ      =  34;


    //
    // Decision variables
    //
    IntVar[] LD = solver.MakeIntVarArray(num_letters, 1, num_letters, "LD");

    // Note D is not used in the constraints below
    IntVar A =  LD[0]; IntVar B =  LD[1]; IntVar C =  LD[2]; // IntVar D =  LD[3];
    IntVar E =  LD[4]; IntVar F =  LD[5]; IntVar G =  LD[6]; IntVar H =  LD[7]; 
    IntVar I =  LD[8]; IntVar J =  LD[9]; IntVar K = LD[10]; IntVar L = LD[11]; 
    IntVar M = LD[12]; IntVar N = LD[13]; IntVar O = LD[14]; IntVar P = LD[15]; 
    IntVar Q = LD[16]; IntVar R = LD[17]; IntVar S = LD[18]; IntVar T = LD[19]; 
    IntVar U = LD[20]; IntVar V = LD[21]; IntVar W = LD[22]; IntVar X = LD[23]; 
    IntVar Y = LD[24]; IntVar Z = LD[25];

    //
    // Constraints
    //
    solver.Add(LD.AllDifferent());
    solver.Add(            B + A + L + L + E + T == BALLET);
    solver.Add(                C + E + L + L + O == CELLO);
    solver.Add(        C + O + N + C + E + R + T == CONCERT);
    solver.Add(                F + L + U + T + E == FLUTE);
    solver.Add(                F + U + G + U + E == FUGUE);
    solver.Add(                    G + L + E + E == GLEE);
    solver.Add(                    J + A + Z + Z == JAZZ);
    solver.Add(                    L + Y + R + E == LYRE);
    solver.Add(                    O + B + O + E == OBOE);
    solver.Add(                O + P + E + R + A == OPERA);
    solver.Add(                P + O + L + K + A == POLKA);
    solver.Add(        Q + U + A + R + T + E + T == QUARTET);
    solver.Add(S + A + X + O + P + H + O + N + E == SAXOPHONE);
    solver.Add(                S + C + A + L + E == SCALE);
    solver.Add(                    S + O + L + O == SOLO);
    solver.Add(                    S + O + N + G == SONG);
    solver.Add(        S + O + P + R + A + N + O == SOPRANO);
    solver.Add(                T + H + E + M + E == THEME);
    solver.Add(            V + I + O + L + I + N == VIOLIN);
    solver.Add(                W + A + L + T + Z == WALTZ);


    //
    // Search
    //
    DecisionBuilder db = solver.MakePhase(LD,
                                          Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
                                          Solver.ASSIGN_CENTER_VALUE);

    solver.NewSearch(db);

    String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    while (solver.NextSolution()) {
      for(int i = 0; i < num_letters; i++) {
        Console.WriteLine("{0}: {1,2}", str[i], LD[i].Value());
      }
      Console.WriteLine();
    }

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

    solver.EndSearch();

  }
Beispiel #35
0
    /**
     *
     * Traffic lights problem.
     *
     * CSPLib problem 16
     * http://www.cs.st-andrews.ac.uk/~ianm/CSPLib/prob/prob016/index.html
     * """
     * Specification:
     * Consider a four way traffic junction with eight traffic lights. Four of the traffic
     * lights are for the vehicles and can be represented by the variables V1 to V4 with domains
     * {r,ry,g,y} (for red, red-yellow, green and yellow). The other four traffic lights are
     * for the pedestrians and can be represented by the variables P1 to P4 with domains {r,g}.
     *
     * The constraints on these variables can be modelled by quaternary constraints on
     * (Vi, Pi, Vj, Pj ) for 1<=i<=4, j=(1+i)mod 4 which allow just the tuples
     * {(r,r,g,g), (ry,r,y,r), (g,g,r,r), (y,r,ry,r)}.
     *
     * It would be interesting to consider other types of junction (e.g. five roads
     * intersecting) as well as modelling the evolution over time of the traffic light sequence.
     * ...
     *
     * Results
     * Only 2^2 out of the 2^12 possible assignments are solutions.
     *
     * (V1,P1,V2,P2,V3,P3,V4,P4) =
     * {(r,r,g,g,r,r,g,g), (ry,r,y,r,ry,r,y,r), (g,g,r,r,g,g,r,r), (y,r,ry,r,y,r,ry,r)}
     * [(1,1,3,3,1,1,3,3), ( 2,1,4,1, 2,1,4,1), (3,3,1,1,3,3,1,1), (4,1, 2,1,4,1, 2,1)}
     * The problem has relative few constraints, but each is very
     * tight. Local propagation appears to be rather ineffective on this
     * problem.
     *
     * """
     * Note: In this model we use only the constraint
     *  solver.AllowedAssignments().
     *
     *
     * See http://www.hakank.org/or-tools/traffic_lights.py
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("TrafficLights");

        //
        // data
        //
        int n = 4;

        int r  = 0;
        int ry = 1;
        int g  = 2;
        int y  = 3;

        string[] lights = { "r", "ry", "g", "y" };

        // The allowed combinations
        IntTupleSet allowed = new IntTupleSet(4);

        allowed.InsertAll(new int[, ] {
            { r, r, g, g },
            { ry, r, y, r },
            { g, g, r, r },
            { y, r, ry, r }
        });
        //
        // Decision variables
        //
        IntVar[] V = solver.MakeIntVarArray(n, 0, n - 1, "V");
        IntVar[] P = solver.MakeIntVarArray(n, 0, n - 1, "P");

        // for search
        IntVar[] VP = new IntVar[2 * n];
        for (int i = 0; i < n; i++)
        {
            VP[i]     = V[i];
            VP[i + n] = P[i];
        }

        //
        // Constraints
        //
        for (int i = 0; i < n; i++)
        {
            int      j   = (1 + i) % n;
            IntVar[] tmp = new IntVar[] { V[i], P[i], V[j], P[j] };
            solver.Add(tmp.AllowedAssignments(allowed));
        }

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


        solver.NewSearch(db);

        while (solver.NextSolution())
        {
            for (int i = 0; i < n; i++)
            {
                Console.Write("{0,2} {1,2} ",
                              lights[V[i].Value()],
                              lights[P[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();
    }
Beispiel #36
0
  /**
   *
   * Solves a set covering problem.
   * See  See http://www.hakank.org/or-tools/set_covering4.py
   *
   */
  private static void Solve(int set_partition)
  {

    Solver solver = new Solver("SetCovering4");

    //
    // data
    //

    // Set partition and set covering problem from
    // Example from the Swedish book
    // Lundgren, Roennqvist, Vaebrand
    // 'Optimeringslaera' (translation: 'Optimization theory'),
    // page 408.
    int num_alternatives = 10;
    int num_objects = 8;

    // costs for the alternatives
    int[] costs = {19, 16, 18, 13, 15, 19, 15, 17, 16, 15};

    // the alternatives, and their objects
    int[,] a = {
      // 1 2 3 4 5 6 7 8    the objects
        {1,0,0,0,0,1,0,0},  // alternative 1
        {0,1,0,0,0,1,0,1},  // alternative 2
        {1,0,0,1,0,0,1,0},  // alternative 3
        {0,1,1,0,1,0,0,0},  // alternative 4
        {0,1,0,0,1,0,0,0},  // alternative 5
        {0,1,1,0,0,0,0,0},  // alternative 6
        {0,1,1,1,0,0,0,0},  // alternative 7
        {0,0,0,1,1,0,0,1},  // alternative 8
        {0,0,1,0,0,1,0,1},  // alternative 9
        {1,0,0,0,0,1,1,0}}; // alternative 10

    //
    // Decision variables
    //
    IntVar[] x = solver.MakeIntVarArray(num_alternatives, 0, 1, "x");
    // number of assigned senators, to be minimized
    IntVar z = x.ScalProd(costs).VarWithName("z");

    //
    // Constraints
    //


    for(int j = 0; j < num_objects; j++) {
      IntVar[] b = new IntVar[num_alternatives];
      for(int i = 0; i < num_alternatives; i++) {
        b[i] = (x[i] * a[i,j]).Var();
      }

      if (set_partition == 1) {
        solver.Add(b.Sum() >= 1);
      } else {
        solver.Add(b.Sum() == 1);
      }
    }


    //
    // objective
    //
    OptimizeVar objective = z.Minimize(1);


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

    solver.NewSearch(db, objective);

    while (solver.NextSolution()) {
      Console.WriteLine("z: " + z.Value());
      Console.Write("Selected alternatives: ");
      for(int i = 0; i < num_alternatives; i++) {
        if (x[i].Value() == 1) {
          Console.Write((i+1) + " ");
        }
      }
      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();

  }
Beispiel #37
0
  /**
   *
   * Lectures problem in Google CP Solver.
   *
   * Biggs: Discrete Mathematics (2nd ed), page 187.
   * """
   * Suppose we wish to schedule six one-hour lectures, v1, v2, v3, v4, v5, v6.
   * Among the the potential audience there are people who wish to hear both
   *
   * - v1 and v2
   * - v1 and v4
   * - v3 and v5
   * - v2 and v6
   * - v4 and v5
   * - v5 and v6
   * - v1 and v6
   *
   * How many hours are necessary in order that the lectures can be given
   * without clashes?
   * """
   *
   * Note: This can be seen as a coloring problem.
   *
   * Also see http://www.hakank.org/or-tools/lectures.py
   * 
   */
  private static void Solve()
  {
    Solver solver = new Solver("Lectures");

    //
    // The schedule requirements:
    // lecture a cannot be held at the same time as b
    // Note: 1-based (compensated in the constraints).
    int[,] g = 
      {
        {1, 2},
        {1, 4},
        {3, 5},
        {2, 6},
        {4, 5},
        {5, 6},
        {1, 6}
      };
    
    // number of nodes
    int n = 6;

    // number of edges
    int edges = g.GetLength(0);

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

    // Maximum color (hour) to minimize.
    // Note: since C# is 0-based, the
    // number of colors is max_c+1.
    IntVar max_c = v.Max().VarWithName("max_c");


    //
    // Constraints
    //

    // Ensure that there are no clashes
    // also, adjust to 0-base.
    for(int i = 0; i < edges; i++) {
      solver.Add(v[g[i,0]-1] != v[g[i,1]-1]);
    }

    // Symmetry breaking:
    // - v0 has the color 0,
    // - v1 has either color 0 or 1
    solver.Add(v[0] == 0);
    solver.Add(v[1] <= 1);


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

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

    solver.NewSearch(db, obj);

    while (solver.NextSolution()) {
      Console.WriteLine("\nmax hours: {0}", max_c.Value()+1);
      Console.WriteLine("v: " +  
                        String.Join(" ", (from i in Enumerable.Range(0, n)
                                          select v[i].Value()).ToArray()));
      for(int i = 0; i < n; i++) {
        Console.WriteLine("Lecture {0} at {1}h", i, v[i].Value());
      }
      Console.WriteLine("\n");
    }

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

    solver.EndSearch();

  }
Beispiel #38
0
  /**
   *
   * Solves a Sudoku problem.
   *
   * This is a very simple 4x4 problem instance:
   * Problem 26: Shidoku from
   * "Taking Sudoku Seriously", page 61
   *   4 _  _ _
   *   3 1  _ _
   *
   *   _ _  4 1
   *   _ _  _ 2
   *
   */
  private static void Solve()
  {
    Solver solver = new Solver("Sudoku");

    //
    // data
    //
    int block_size = 2;
    IEnumerable<int> BLOCK = Enumerable.Range(0, block_size);
    int n = block_size * block_size;
    IEnumerable<int> RANGE = Enumerable.Range(0, n);

    // 0 marks an unknown value
    int[,] initial_grid = {{4, 0,  0, 0},
                           {3, 1,  0, 0},

                           {0, 0,  4, 1},
                           {0, 0,  0, 2}};
    

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

    //
    // Constraints
    //  

    // init
    foreach(int i in RANGE) {
      foreach(int j in RANGE) {
        if (initial_grid[i,j] > 0) {
          solver.Add(grid[i,j] == initial_grid[i,j]);
        }
      }
    }

    
    foreach(int i in RANGE) {

      // rows
      solver.Add( (from j in RANGE
                   select grid[i,j]).ToArray().AllDifferent());

      // cols
      solver.Add( (from j in RANGE
                   select grid[j,i]).ToArray().AllDifferent());

    }

    // blocks
    foreach(int i in BLOCK) {
      foreach(int j in BLOCK) {
        solver.Add( (from di in BLOCK
                     from dj in BLOCK
                     select grid[i*block_size+di, j*block_size+dj]
                     ).ToArray().AllDifferent());
      }
    }        


    //
    // Search
    //
    DecisionBuilder db = solver.MakePhase(grid_flat,
                                          Solver.INT_VAR_SIMPLE,
                                          Solver.INT_VALUE_SIMPLE);

    solver.NewSearch(db);

    while (solver.NextSolution()) {
      for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++){ 
          Console.Write("{0} ", grid[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();

  }
Beispiel #39
0
  /**
   *
   * Labeled dice problem.
   *
   * From Jim Orlin 'Colored letters, labeled dice: a logic puzzle'
   * http://jimorlin.wordpress.com/2009/02/17/colored-letters-labeled-dice-a-logic-puzzle/
   * """
   * My daughter Jenn bough a puzzle book, and showed me a cute puzzle.  There
   * are 13 words as follows:  BUOY, CAVE, CELT, FLUB, FORK, HEMP, JUDY,
   * JUNK, LIMN, QUIP, SWAG, VISA, WISH.
   *
   * There are 24 different letters that appear in the 13 words.  The question
   * is:  can one assign the 24 letters to 4 different cubes so that the
   * four letters of each word appears on different cubes.  (There is one
   * letter from each word on each cube.)  It might be fun for you to try
   * it.  I'll give a small hint at the end of this post. The puzzle was
   * created by Humphrey Dudley.
   * """
   *
   * Jim Orlin's followup 'Update on Logic Puzzle':
   * http://jimorlin.wordpress.com/2009/02/21/update-on-logic-puzzle/
   *
   *
   * Also see http://www.hakank.org/or-tools/labeled_dice.py
   *
   */
  private static void Solve()
  {

    Solver solver = new Solver("LabeledDice");

    //
    // Data
    //
    int n = 4;
    int m = 24;

    int A = 0;
    int B = 1;
    int C = 2;
    int D = 3;
    int E = 4;
    int F = 5;
    int G = 6;
    int H = 7;
    int I = 8;
    int J = 9;
    int K = 10;
    int L = 11;
    int M = 12;
    int N = 13;
    int O = 14;
    int P = 15;
    int Q = 16;
    int R = 17;
    int S = 18;
    int T = 19;
    int U = 20;
    int V = 21;
    int W = 22;
    int Y = 23;


    String[] letters_str = {"A","B","C","D","E","F","G","H","I","J","K","L","M",
                            "N","O","P","Q","R","S","T","U","V","W","Y"};

    int num_words = 13;
    int[,] words =
      {
        {B,U,O,Y},
        {C,A,V,E},
        {C,E,L,T},
        {F,L,U,B},
        {F,O,R,K},
        {H,E,M,P},
        {J,U,D,Y},
        {J,U,N,K},
        {L,I,M,N},
        {Q,U,I,P},
        {S,W,A,G},
        {V,I,S,A},
        {W,I,S,H}
        };


    //
    // Decision variables
    //
    IntVar[] dice =  solver.MakeIntVarArray(m, 0, n-1, "dice");
    IntVar[] gcc =  solver.MakeIntVarArray(n, 6, 6, "gcc");

    //
    // Constraints
    //


    // the letters in a word must be on a different die
    for(int i = 0; i < num_words; i++) {
      solver.Add( (from j in Enumerable.Range(0, n)
                   select dice[words[i,j]]
                   ).ToArray().AllDifferent());
    }

    // there must be exactly 6 letters of each die
    /*
    for(int i = 0; i < n; i++) {
      solver.Add( ( from j in Enumerable.Range(0, m)
                    select (dice[j] == i)
                   ).ToArray().Sum() == 6 );
    }
    */
    // Use Distribute (Global Cardinality Count) instead.
    solver.Add(dice.Distribute(gcc));

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

    solver.NewSearch(db);

    while (solver.NextSolution()) {
      for(int d = 0; d < n; d++) {
        Console.Write("die {0}: ", d);
        for(int i = 0; i < m; i++) {
          if (dice[i].Value() == d) {
            Console.Write(letters_str[i]);
          }
        }
        Console.WriteLine();
      }

      Console.WriteLine("The words with the cube label:");
      for(int i = 0; i < num_words; i++) {
        for(int j = 0; j < n; j++) {
          Console.Write("{0} ({1})", letters_str[words[i,j]], dice[words[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();

  }
Beispiel #40
0
  /**
   *
   * Implements the Who killed Agatha problem.
   * See http://www.hakank.org/google_or_tools/who_killed_agatha.py
   *
   */
  private static void Solve()
  {
    Solver solver = new Solver("WhoKilledAgatha");

    int n = 3;
    int agatha = 0;
    int butler = 1;
    int charles = 2;

    //
    // Decision variables
    //
    IntVar the_killer = solver.MakeIntVar(0, 2, "the_killer");
    IntVar the_victim = solver.MakeIntVar(0, 2, "the_victim");
    IntVar[,] hates = solver.MakeIntVarMatrix(n, n, 0, 1, "hates");
    IntVar[] hates_flat = hates.Flatten();
    IntVar[,] richer = solver.MakeIntVarMatrix(n, n, 0, 1, "richer");
    IntVar[] richer_flat = richer.Flatten();

    IntVar[] all = new IntVar[2 * n * n]; // for branching
    for(int i = 0; i < n*n; i++) {
      all[i] = hates_flat[i];
      all[(n*n)+i] = richer_flat[i]; 
    }

    //
    // Constraints
    //

    // Agatha, the butler, and Charles live in Dreadsbury Mansion, and
    // are the only ones to live there.

    // A killer always hates, and is no richer than his victim.
    //     hates[the_killer, the_victim] == 1
    //     hates_flat[the_killer * n + the_victim] == 1
    solver.Add(hates_flat.Element(the_killer * n + the_victim) == 1);

    //    richer[the_killer, the_victim] == 0
    solver.Add(richer_flat.Element(the_killer * n + the_victim) == 0);

    // define the concept of richer:
    //     no one is richer than him-/herself...
    for(int i = 0; i < n; i++) {
      solver.Add(richer[i,i] == 0);
    }

    // (contd...) if i is richer than j then j is not richer than i
    //   if (i != j) =>
    //       ((richer[i,j] = 1) <=> (richer[j,i] = 0))
    for(int i = 0; i < n; i++) {
      for(int j = 0; j < n; j++) {
        if (i != j) {
          solver.Add((richer[i, j]==1) - (richer[j, i]==0) == 0);
        }
      }
    }

    // Charles hates no one that Agatha hates.
    //    forall i in 0..2:
    //       (hates[agatha, i] = 1) => (hates[charles, i] = 0)
    for(int i = 0; i < n; i++) {
      solver.Add((hates[agatha,i]==1) - (hates[charles,i]==0) <= 0);

    }

    // Agatha hates everybody except the butler.
    solver.Add(hates[agatha,charles] == 1);
    solver.Add(hates[agatha,agatha] == 1);
    solver.Add(hates[agatha,butler] == 0);

    // The butler hates everyone not richer than Aunt Agatha.
    //    forall i in 0..2:
    //       (richer[i, agatha] = 0) => (hates[butler, i] = 1)
    for(int i = 0; i < n; i++) {
      solver.Add((richer[i,agatha] == 0)-(hates[butler,i] == 1)<=0);
    }

    // The butler hates everyone whom Agatha hates.
    //     forall i : 0..2:
    //         (hates[agatha, i] = 1) => (hates[butler, i] = 1)
    for(int i = 0; i < n; i++) {
      solver.Add((hates[agatha,i] == 1)-(hates[butler,i] == 1)<=0);
    }

    // Noone hates everyone.
    //     forall i in 0..2:
    //         (sum j in 0..2: hates[i,j]) <= 2
    for(int i = 0; i < n; i++) {
      solver.Add((from j in Enumerable.Range(0, n)
                  select hates[i,j]
                  ).ToArray().Sum() <= 2 );
    }


    // Who killed Agatha?
    solver.Add(the_victim == agatha);


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

    solver.NewSearch(db);

    while (solver.NextSolution()) {
      Console.WriteLine("the_killer: " + the_killer.Value());
    }

    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();

  }
Beispiel #41
0
  /**
   *
   * Just forgotten puzzle (Enigma 1517) in Google CP Solver.
   *
   * From http://www.f1compiler.com/samples/Enigma 201517.f1.html
   * """
   * Enigma 1517 Bob Walker, New Scientist magazine, October 25, 2008.
   *
   * Joe was furious when he forgot one of his bank account numbers.
   * He remembered that it had all the digits 0 to 9 in some order,
   * so he tried the following four sets without success:
   *
   * 9 4 6 2 1 5 7 8 3 0
   * 8 6 0 4 3 9 1 2 5 7
   * 1 6 4 0 2 9 7 8 5 3
   * 6 8 2 4 3 1 9 0 7 5
   *
   * When Joe finally remembered his account number, he realised that
   * in each set just four of the digits were in their correct position
   * and that, if one knew that, it was possible to work out his
   * account number. What was it?
   * """
   *
   * Also see http://www.hakank.org/google_or_tools/just_forgotten.py
   *
   */
  private static void Solve()
  {
    Solver solver = new Solver("JustForgotten");


    int rows = 4;
    int cols = 10;

    // The four tries
    int[,] a = {{9,4,6,2,1,5,7,8,3,0},
                {8,6,0,4,3,9,1,2,5,7},
                {1,6,4,0,2,9,7,8,5,3},
                {6,8,2,4,3,1,9,0,7,5}};


    //
    // Decision variables
    //
    IntVar[] x = solver.MakeIntVarArray(cols, 0, 9, "x");

    //
    // Constraints
    //
    solver.Add(x.AllDifferent());
    for(int r = 0; r < rows; r++) {
      solver.Add( (from c in Enumerable.Range(0, cols)
                   select x[c] == a[r,c]).ToArray().Sum() == 4);
    }



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

    solver.NewSearch(db);

    while (solver.NextSolution()) {
      Console.WriteLine("Account number:");
      for(int j = 0; j < cols; j++) {
        Console.Write(x[j].Value() + " ");
      }
      Console.WriteLine("\n");
      Console.WriteLine("The four tries, where '!' represents a correct digit:");
      for(int i = 0; i < rows; i++) {
        for(int j = 0; j < cols; j++) {
          String c = " ";
          if (a[i,j] == x[j].Value()) {
            c = "!";
          }
          Console.Write("{0}{1} ", a[i,j], c);
        }
        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();

  }
  /**
   *
   * Solves some stable marriage problems.
   *
   * This version randomize the problem instances.
   *
   * Also, see http://www.hakank.org/or-tools/stable_marriage.cs
   *
   *
   */
  private static void Solve(int n = 10, int sols_to_show = 0)
  {

    Solver solver = new Solver("StableMarriage");

    //
    // data
    //
    int seed = (int)DateTime.Now.Ticks;
    Random generator = new Random(seed);

    int[][] rankMen = new int[n][];
    int[][] rankWomen = new int[n][];
    for (int i = 0; i < n; i++) {
      int[] m = shuffle(n, generator); 
      int[] w = shuffle(n, generator); 
      rankMen[i] = new int[n];
      rankWomen[i] = new int[n];
      for (int j = 0; j < n; j++) {
        rankMen[i][j] = m[j];
        rankWomen[i][j] = w[j];
      }
    } 

    Console.WriteLine("after generating...");

    if (n <= 20) {
      Console.Write("rankMen: ");

      printRank("rankMen", rankMen);
      printRank("rankWomen", rankWomen);

      
    }

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

    //
    // Constraints
    //
    // (The comments below are the Comet code)

    //
    //   forall(m in Men)
    //      cp.post(husband[wife[m]] == m);
    for(int m = 0; m < n; m++) {
      solver.Add(husband.Element(wife[m]) == m);
    }

    //   forall(w in Women)
    //     cp.post(wife[husband[w]] == w);
    for(int w = 0; w < n; w++) {
      solver.Add(wife.Element(husband[w]) == w);
    }


    //   forall(m in Men, o in Women)
    //       cp.post(rankMen[m,o] < rankMen[m, wife[m]] =>
    //               rankWomen[o,husband[o]] < rankWomen[o,m]);
    for(int m = 0; m < n; m++) {
      for(int o = 0; o < n; o++) {
        IntVar b1 = rankMen[m].Element(wife[m]) > rankMen[m][o];
        IntVar b2 = rankWomen[o].Element(husband[o]) < rankWomen[o][m];
        solver.Add(b1 <= b2);
      }

    }

    //   forall(w in Women, o in Men)
    //      cp.post(rankWomen[w,o] < rankWomen[w,husband[w]] =>
    //              rankMen[o,wife[o]] < rankMen[o,w]);
    for(int w = 0; w < n; w++) {
      for(int o = 0; o < n; o++) {
        IntVar b1 = rankWomen[w].Element(husband[w]) > rankWomen[w][o];
        IntVar b2 = rankMen[o].Element(wife[o]) < rankMen[o][w];
        solver.Add(b1 <= b2);
        }
      }


    //
    // Search
    //
    DecisionBuilder db = solver.MakePhase(wife,
                                          // Solver.INT_VAR_DEFAULT,
                                          // Solver.INT_VAR_SIMPLE,
                                          Solver.CHOOSE_FIRST_UNBOUND,
                                          // Solver.CHOOSE_RANDOM,
                                          // Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
                                          // Solver.CHOOSE_MIN_SIZE_HIGHEST_MIN,
                                          // Solver.CHOOSE_MIN_SIZE_LOWEST_MAX,
                                          // Solver.CHOOSE_MIN_SIZE_HIGHEST_MAX,
                                          // Solver.CHOOSE_PATH,
                                          // Solver.CHOOSE_MIN_SIZE,
                                          // Solver.CHOOSE_MAX_SIZE,
                                          // Solver.CHOOSE_MAX_REGRET,
                                        


                                          // Solver.INT_VALUE_DEFAULT
                                          // Solver.INT_VALUE_SIMPLE
                                          Solver.ASSIGN_MIN_VALUE
                                          // Solver.ASSIGN_MAX_VALUE
                                          // Solver.ASSIGN_RANDOM_VALUE
                                          // Solver.ASSIGN_CENTER_VALUE
                                          // Solver.SPLIT_LOWER_HALF
                                          // Solver.SPLIT_UPPER_HALF
                                          );

    solver.NewSearch(db);

    int sols = 0;
    while (solver.NextSolution()) {
      sols += 1;
      Console.Write("wife   : ");
      for(int i = 0; i < n; i++) {
        Console.Write(wife[i].Value() + " ");
      }
      Console.Write("\nhusband: ");
      for(int i = 0; i < n; i++) {
        Console.Write(husband[i].Value() + " ");
      }
      Console.WriteLine("\n");

      if (sols_to_show > 0 && sols >= sols_to_show) {
        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();

  }
Beispiel #43
0
  /**
   *
   * Moving furnitures (scheduling) problem in Google CP Solver.
   *
   * Marriott & Stukey: 'Programming with constraints', page  112f
   *
   * The model implements an decomposition of the global constraint
   * cumulative (see above).
   *
   * Also see http://www.hakank.org/or-tools/furniture_moving.py
   *
   */
  private static void Solve()
  {
    Solver solver = new Solver("FurnitureMoving");

    int n = 4;
    int[] duration    = {30,10,15,15};
    int[] demand      = { 3, 1, 3, 2};
    int upper_limit = 160;


    //
    // Decision variables
    //
    IntVar[] start_times = solver.MakeIntVarArray(n, 0, upper_limit, "start_times");
    IntVar[] end_times = solver.MakeIntVarArray(n, 0, upper_limit * 2, "end_times");
    IntVar end_time = solver.MakeIntVar(0, upper_limit * 2, "end_time");

    // number of needed resources, to be minimized or constrained
    IntVar num_resources  = solver.MakeIntVar(0, 10, "num_resources");


    //
    // Constraints
    //
    for(int i = 0; i < n; i++) {
      solver.Add(end_times[i] == start_times[i] + duration[i]);
    }

    solver.Add(end_time == end_times.Max());
    MyCumulative(solver, start_times, duration, demand, num_resources);


    //
    // Some extra constraints to play with
    //

    // all tasks must end within an hour
    // solver.Add(end_time <= 60);

    // All tasks should start at time 0
    // for(int i = 0; i < n; i++) {
    //   solver.Add(start_times[i] == 0);
    // }


    // limitation of the number of people
    // solver.Add(num_resources <= 3);
    solver.Add(num_resources <= 4);


    //
    // Objective
    //

    // OptimizeVar obj = num_resources.Minimize(1);
    OptimizeVar obj = end_time.Minimize(1);

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

    solver.NewSearch(db, obj);

    while (solver.NextSolution()) {
      Console.WriteLine("num_resources: {0} end_time: {1}",
                        num_resources.Value(), end_time.Value());
      for(int i = 0; i < n; i++) {
        Console.WriteLine("Task {0,1}: {1,2} -> {2,2} -> {3,2} (demand: {4})",
                          i,
                          start_times[i].Value(),
                          duration[i],
                          end_times[i].Value(),
                          demand[i]);
      }
      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();

  }
Beispiel #44
0
  /**
   *
   * Rogo puzzle solver.
   *
   * From http://www.rogopuzzle.co.nz/
   * """
   * The object is to collect the biggest score possible using a given
   * number of steps in a loop around a grid. The best possible score
   * for a puzzle is given with it, so you can easily check that you have
   * solved the puzzle. Rogo puzzles can also include forbidden squares,
   * which must be avoided in your loop.
   * """
   *
   * Also see Mike Trick:
   * "Operations Research, Sudoko, Rogo, and Puzzles"
   * http://mat.tepper.cmu.edu/blog/?p=1302
   *
   *
   * Also see, http://www.hakank.org/or-tools/rogo2.py
   * though this model differs in a couple of central points
   * which makes it much faster:
   *
   * - it use a table (
AllowedAssignments) with the valid connections
   * - instead of two coordinates arrays, it use a single path array
   *
   */
  private static void Solve()
  {

    Solver solver = new Solver("Rogo2");


    Console.WriteLine("\n");
    Console.WriteLine("**********************************************");
    Console.WriteLine("    {0}", problem_name);
    Console.WriteLine("**********************************************\n");

    //
    // Data
    //
    int B = -1;

    Console.WriteLine("Rows: {0} Cols: {1} Max Steps: {2}", rows, cols, max_steps);

    int[] problem_flatten = problem.Cast<int>().ToArray();
    int max_point = problem_flatten.Max();
    int max_sum = problem_flatten.Sum();
    Console.WriteLine("max_point: {0} max_sum: {1} best: {2}", max_point, max_sum, best);

    IEnumerable<int> STEPS = Enumerable.Range(0, max_steps);
    IEnumerable<int> STEPS1 = Enumerable.Range(0, max_steps-1);

    // the valid connections, to be used with AllowedAssignments
    IntTupleSet valid_connections = ValidConnections(rows, cols);


    //
    // Decision variables
    //
    IntVar[] path = solver.MakeIntVarArray(max_steps, 0, rows*cols-1, "path");
    IntVar[] points = solver.MakeIntVarArray(max_steps, 0, best, "points");
    IntVar sum_points = points.Sum().VarWithName("sum_points");


    //
    // Constraints
    //

    foreach(int s in STEPS) {
      // calculate the points (to maximize)
      solver.Add(points[s] == problem_flatten.Element(path[s]));

      // ensure that there are no black cells in
      // the path
      solver.Add(problem_flatten.Element(path[s]) != B);
    }

    solver.Add(path.AllDifferent());


    // valid connections
    foreach(int s in STEPS1) {
      solver.Add(new IntVar[] {path[s], path[s+1]}.
                 AllowedAssignments(valid_connections));
    }
    // around the corner
    solver.Add(new IntVar[] {path[max_steps-1], path[0]}.
               AllowedAssignments(valid_connections));


    // Symmetry breaking
    for(int s = 1; s < max_steps; s++) {
      solver.Add(path[0] < path[s]);
    }


    //
    // Objective
    //
    OptimizeVar obj = sum_points.Maximize(1);


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

    solver.NewSearch(db, obj);

    while (solver.NextSolution()) {
      Console.WriteLine("sum_points: {0}", sum_points.Value());
      Console.Write("path: ");
      foreach(int s in STEPS) {
        Console.Write("{0} ", path[s].Value());
      }
      Console.WriteLine();
      Console.WriteLine("(Adding 1 to coords...)");
      int[,] sol = new int[rows, cols];
      foreach(int s in STEPS) {
        int p = (int) path[s].Value();
        int x = (int) (p / cols);
        int y = (int) (p % cols);
        Console.WriteLine("{0,2},{1,2} ({2} points)", x+1, y+1, points[s].Value());
        sol[x, y] = 1;
      }
      Console.WriteLine("\nThe path is marked by 'X's:");
      for(int i = 0; i < rows; i++) {
        for(int j = 0; j < cols; j++) {
          String p = sol[i,j] == 1 ? "X" : " ";
          String q = problem[i,j] == B ? "B" :
            problem[i,j] == 0 ? "." : problem[i,j].ToString();
          Console.Write("{0,2}{1} ", q, p);
        }
        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();

  }
Beispiel #45
0
  /**
   *
   * P-median problem.
   *
   * Model and data from the OPL Manual, which describes the problem:
   * """
   * The P-Median problem is a well known problem in Operations Research.
   * The problem can be stated very simply, like this: given a set of customers
   * with known amounts of demand, a set of candidate locations for warehouses,
   * and the distance between each pair of customer-warehouse, choose P
   * warehouses to open that minimize the demand-weighted distance of serving
   * all customers from those P warehouses.
   * """
   *
   * Also see http://www.hakank.org/or-tools/p_median.py
   *
   */
  private static void Solve()
  {

    Solver solver = new Solver("PMedian");

    //
    // Data
    //
    int p = 2;
    int num_customers = 4;
    IEnumerable<int> CUSTOMERS = Enumerable.Range(0, num_customers);

    int num_warehouses = 3;
    IEnumerable<int> WAREHOUSES = Enumerable.Range(0, num_warehouses);

    int[] demand = {100,80,80,70};
    int [,] distance = {
      { 2, 10, 50},
      { 2, 10, 52},
      {50, 60,  3},
      {40, 60,  1}
    };

    //
    // Decision variables
    //

    IntVar[] open = solver.MakeIntVarArray(num_warehouses, 0, num_warehouses, "open");
    IntVar[,] ship = solver.MakeIntVarMatrix(num_customers, num_warehouses,
                                             0, 1, "ship");
    IntVar z = solver.MakeIntVar(0, 1000, "z");


    //
    // Constraints
    //

    solver.Add((from c in CUSTOMERS
                from w in WAREHOUSES
                select (demand[c]*distance[c,w]*ship[c,w])
                ).ToArray().Sum() == z);

    solver.Add(open.Sum() == p);

    foreach(int c in CUSTOMERS) {
      foreach(int w in WAREHOUSES) {
        solver.Add(ship[c,w] <= open[w]);
      }

      solver.Add((from w in WAREHOUSES select ship[c,w]).ToArray().Sum() == 1);
    }


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

    //
    // Search
    //
    DecisionBuilder db = solver.MakePhase(open.Concat(ship.Flatten()).ToArray(),
                                          Solver.CHOOSE_FIRST_UNBOUND,
                                          Solver.ASSIGN_MIN_VALUE);

    solver.NewSearch(db, obj);

    while (solver.NextSolution()) {
      Console.WriteLine("z: {0}",z.Value());
      Console.Write("open:");
      foreach(int w in WAREHOUSES) {
        Console.Write(open[w].Value() + " ");
      }
      Console.WriteLine();
      foreach(int c in CUSTOMERS) {
        foreach(int w in WAREHOUSES) {
          Console.Write(ship[c,w].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();

  }
Beispiel #46
0
  /**
   *
   * Implements a (decomposition) of the global constraint circuit.
   * See http://www.hakank.org/google_or_tools/circuit.py
   *
   */
  private static void Solve(int n = 5)
  {
    Solver solver = new Solver("Circuit");


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

    //
    // Constraints
    //
    circuit(solver, x);


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


    solver.NewSearch(db);

    while (solver.NextSolution()) {
      for(int i = 0; i < n; i++) {
          Console.Write("{0} ", 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();

  }
Beispiel #47
0
  /**
   *
   * Hidato puzzle in Google CP Solver.
   *
   * http://www.hidato.com/
   * """
   * Puzzles start semi-filled with numbered tiles.
   * The first and last numbers are circled.
   * Connect the numbers together to win. Consecutive
   * number must touch horizontally, vertically, or
   * diagonally.
   * """
   *
   * This is a port of the Python model hidato_table.py
   * made by Laurent Perron (using AllowedAssignments),
   * based on my (much slower) model hidato.py.
   *
   */
  private static void Solve(int model = 1)
  {
    Solver solver = new Solver("HidatoTable");

    //
    // models, a 0 indicates an open cell which number is not yet known.
    //

    int[,] puzzle = null;
    if (model == 1) {

      // Simple problem

      // Solution 1:
      // 6  7  9
      // 5  2  8
      // 1  4  3
      int[,] puzzle1 = {{6, 0, 9},
                        {0, 2, 8},
                        {1, 0, 0}};
      puzzle = puzzle1;

    } else if (model == 2) {

      int[,] puzzle2 = {{0, 44, 41, 0, 0, 0, 0},
                        {0, 43, 0, 28, 29, 0, 0},
                        {0, 1, 0, 0, 0, 33, 0},
                        {0, 2, 25, 4, 34, 0, 36},
                        {49, 16, 0, 23, 0, 0, 0},
                        {0, 19, 0, 0, 12, 7, 0},
                        {0, 0, 0, 14, 0, 0, 0}};
      puzzle = puzzle2;

    } else if (model == 3) {
      // Problems from the book:
      // Gyora Bededek: "Hidato: 2000 Pure Logic Puzzles"
      // Problem 1 (Practice)
      int[,] puzzle3 = {{0, 0, 20, 0, 0},
                        {0, 0, 0, 16, 18},
                        {22, 0, 15, 0, 0},
                        {23, 0, 1, 14, 11},
                        {0, 25, 0, 0, 12}};
      puzzle = puzzle3;

    } else if (model == 4) {
      // problem 2 (Practice)
      int[,] puzzle4 = {{0, 0, 0, 0, 14},
                        {0, 18, 12, 0, 0},
                        {0, 0, 17, 4, 5},
                        {0, 0, 7, 0, 0},
                        {9, 8, 25, 1, 0}};
      puzzle = puzzle4;

    } else if (model == 5) {
      // problem 3 (Beginner)
      int[,] puzzle5 = {{0, 26, 0, 0, 0, 18},
                        {0, 0, 27, 0, 0, 19},
                        {31, 23, 0, 0, 14, 0},
                        {0, 33, 8, 0, 15, 1},
                        {0, 0, 0, 5, 0, 0},
                        {35, 36, 0, 10, 0, 0}};
      puzzle = puzzle5;

    } else if (model == 6) {
      // Problem 15 (Intermediate)
      int[,] puzzle6 = {{64, 0, 0, 0, 0, 0, 0, 0},
                        {1, 63, 0, 59, 15, 57, 53, 0},
                        {0, 4, 0, 14, 0, 0, 0, 0},
                        {3, 0, 11, 0, 20, 19, 0, 50},
                        {0, 0, 0, 0, 22, 0, 48, 40},
                        {9, 0, 0, 32, 23, 0, 0, 41},
                        {27, 0, 0, 0, 36, 0, 46, 0},
                        {28, 30, 0, 35, 0, 0, 0, 0}};
      puzzle = puzzle6;
    }

    int r = puzzle.GetLength(0);
    int c = puzzle.GetLength(1);

    Console.WriteLine();
    Console.WriteLine("----- Solving problem {0} -----", model);
    Console.WriteLine();

    PrintMatrix(puzzle);

    //
    // Decision variables
    //
    IntVar[] positions = solver.MakeIntVarArray(r*c, 0, r * c - 1, "p");


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

    //
    // Fill in the clues
    //
    for(int i = 0; i < r; i++) {
      for(int j = 0; j < c; j++) {
        if (puzzle[i,j] > 0) {
          solver.Add(positions[puzzle[i,j] - 1] == i * c + j);
        }
      }
    }

    // Consecutive numbers much touch each other in the grid.
    // We use an allowed assignment constraint to model it.
    IntTupleSet close_tuples = BuildPairs(r, c);
    for(int k = 1; k < r * c - 1; k++) {
      IntVar[] tmp = new IntVar[] {positions[k], positions[k + 1]};
      solver.Add(tmp.AllowedAssignments(close_tuples));
    }


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

    solver.NewSearch(db);

    int num_solution = 0;
    while (solver.NextSolution()) {
      num_solution++;
      PrintOneSolution(positions, r, c, num_solution);
    }

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

    solver.EndSearch();

  }
Beispiel #48
0
  /**
   *
   * Solves a set covering problem.
   * See  See http://www.hakank.org/or-tools/set_covering2.py
   *
   */
  private static void Solve()
  {

    Solver solver = new Solver("SetCovering2");

    //
    // data
    //

    // Example 9.1-2 from
    // Taha "Operations Research - An Introduction",
    // page 354ff.
    // Minimize the number of security telephones in street
    // corners on a campus.

    int n = 8;            // maximum number of corners
    int num_streets = 11; // number of connected streets

    // corners of each street
    // Note: 1-based (handled below)
    int[,] corner = {{1,2},
                     {2,3},
                     {4,5},
                     {7,8},
                     {6,7},
                     {2,6},
                     {1,6},
                     {4,7},
                     {2,4},
                     {5,8},
                     {3,5}};

    //
    // Decision variables
    //
    IntVar[] x = solver.MakeIntVarArray(n, 0, 1, "x");
    // number of telephones, to be minimized
    IntVar z = x.Sum().Var();

    //
    // Constraints
    //

    // ensure that all streets are covered
    for(int i = 0; i < num_streets; i++) {
      solver.Add(x[corner[i,0] - 1] + x[corner[i,1] - 1]  >= 1);
    }

    //
    // objective
    //
    OptimizeVar objective = z.Minimize(1);

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

    solver.NewSearch(db, objective);

    while (solver.NextSolution()) {
      Console.WriteLine("z: {0}", z.Value());
      Console.Write("x: ");
      for(int i = 0; i < n; 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();

  }
Beispiel #49
0
  /**
   *
   * Implements Young tableaux and partitions.
   * See http://www.hakank.org/or-tools/young_tableuax.py
   *
   */
  private static void Solve(int n)
  {
    Solver solver = new Solver("YoungTableaux");

    //
    // data
    //
    Console.WriteLine("n: {0}\n", n);

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

    // partition structure
    IntVar[] p = solver.MakeIntVarArray(n, 0, n + 1, "p");

    //
    // Constraints
    //
    // 1..n is used exactly once
    for(int i = 1; i <= n; i++) {
      solver.Add(x_flat.Count(i, 1));
    }

    solver.Add(x[0,0] == 1);

    // row wise
    for(int i = 0; i < n; i++) {
      for(int j = 1; j < n; j++) {
        solver.Add(x[i,j] >= x[i,j - 1]);
      }
    }

    // column wise
    for(int j = 0; j < n; j++) {
      for(int i = 1; i < n; i++) {
        solver.Add(x[i,j] >= x[i - 1, j]);
      }
    }

    // calculate the structure (i.e. the partition)
    for(int i = 0; i < n; i++) {
      IntVar[] b = new IntVar[n];
      for(int j = 0; j < n; j++) {
        b[j] = x[i, j] <= n;
      }
      solver.Add(p[i] == b.Sum());
    }

    solver.Add(p.Sum() == n);

    for(int i = 1; i < n; i++) {
      solver.Add(p[i - 1] >= p[i]);
    }



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

    solver.NewSearch(db);

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

      for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
          long val = x[i,j].Value();
          if (val <= n) {
            Console.Write(val + " ");
          }
        }
        if (p[i].Value() > 0) {
          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();

  }
Beispiel #50
0
  /**
   *
   * A programming puzzle from Einav.
   *
   * From
   * "A programming puzzle from Einav"
   * http://gcanyon.wordpress.com/2009/10/28/a-programming-puzzle-from-einav/
   * """
   * My friend Einav gave me this programming puzzle to work on. Given
   * this array of positive and negative numbers:
   * 33   30  -10 -6  18   7  -11 -23   6
   * ...
   * -25   4  16  30  33 -23  -4   4 -23
   *
   * You can flip the sign of entire rows and columns, as many of them
   * as you like. The goal is to make all the rows and columns sum to positive
   * numbers (or zero), and then to find the solution (there are more than one)
   * that has the smallest overall sum. So for example, for this array:
   * 33  30 -10
   * -16  19   9
   * -17 -12 -14
   * You could flip the sign for the bottom row to get this array:
   * 33  30 -10
   * -16  19   9
   * 17  12  14
   * Now all the rows and columns have positive sums, and the overall total is
   * 108.
   * But you could instead flip the second and third columns, and the second
   * row, to get this array:
   * 33  -30  10
   * 16   19    9
   * -17   12   14
   * All the rows and columns still total positive, and the overall sum is just
   * 66. So this solution is better (I don't know if it's the best)
   * A pure brute force solution would have to try over 30 billion solutions.
   * I wrote code to solve this in J. I'll post that separately.
   * """
   *
   * Note:
   * This is a port of Larent Perrons's Python version of my own einav_puzzle.py.
   * He removed some of the decision variables and made it more efficient.
   * Thanks!
   *
   * Also see http://www.hakank.org/or-tools/einav_puzzle2.py
   *
   */
  private static void Solve()
  {
    Solver solver = new Solver("EinavPuzzle2");

    //
    // Data
    //

    // Small problem
    // int rows = 3;
    // int cols = 3;
    // int[,] data = {
    //   { 33,  30, -10},
    //   {-16,  19,   9},
    //   {-17, -12, -14}
    // };


    // Full problem
    int rows = 27;
    int cols = 9;
    int[,] data = {
      {33,30,10,-6,18,-7,-11,23,-6},
      {16,-19,9,-26,-8,-19,-8,-21,-14},
      {17,12,-14,31,-30,13,-13,19,16},
      {-6,-11,1,17,-12,-4,-7,14,-21},
      {18,-31,34,-22,17,-19,20,24,6},
      {33,-18,17,-15,31,-5,3,27,-3},
      {-18,-20,-18,31,6,4,-2,-12,24},
      {27,14,4,-29,-3,5,-29,8,-12},
      {-15,-7,-23,23,-9,-8,6,8,-12},
      {33,-23,-19,-4,-8,-7,11,-12,31},
      {-20,19,-15,-30,11,32,7,14,-5},
      {-23,18,-32,-2,-31,-7,8,24,16},
      {32,-4,-10,-14,-6,-1,0,23,23},
      {25,0,-23,22,12,28,-27,15,4},
      {-30,-13,-16,-3,-3,-32,-3,27,-31},
      {22,1,26,4,-2,-13,26,17,14},
      {-9,-18,3,-20,-27,-32,-11,27,13},
      {-17,33,-7,19,-32,13,-31,-2,-24},
      {-31,27,-31,-29,15,2,29,-15,33},
      {-18,-23,15,28,0,30,-4,12,-32},
      {-3,34,27,-25,-18,26,1,34,26},
      {-21,-31,-10,-13,-30,-17,-12,-26,31},
      {23,-31,-19,21,-17,-10,2,-23,23},
      {-3,6,0,-3,-32,0,-10,-25,14},
      {-19,9,14,-27,20,15,-5,-27,18},
      {11,-6,24,7,-17,26,20,-31,-25},
      {-25,4,-16,30,33,23,-4,-4,23}
    };


    IEnumerable<int> ROWS = Enumerable.Range(0, rows);
    IEnumerable<int> COLS = Enumerable.Range(0, cols);

    //
    // Decision variables
    //
    IntVar[,] x = solver.MakeIntVarMatrix(rows, cols, -100, 100, "x");
    IntVar[] x_flat = x.Flatten();

    int[] signs_domain = {-1,1};
    // This don't work at the moment...
    IntVar[] row_signs = solver.MakeIntVarArray(rows, signs_domain, "row_signs");
    IntVar[] col_signs = solver.MakeIntVarArray(cols, signs_domain, "col_signs");



    // To optimize
    IntVar total_sum = x_flat.Sum().VarWithName("total_sum");

    //
    // Constraints
    //
    foreach(int i in ROWS) {
      foreach(int j in COLS) {
        solver.Add(x[i,j] == data[i,j] * row_signs[i] * col_signs[j]);
      }
    }

    // row sums
    IntVar[] row_sums = (from i in ROWS
                         select (from j in COLS
                                 select x[i,j]
                                ).ToArray().Sum().Var()).ToArray();

    foreach(int i in ROWS) {
      row_sums[i].SetMin(0);
    }

    // col sums
    IntVar[] col_sums = (from j in COLS
                         select (from i in ROWS
                                 select x[i,j]
                                 ).ToArray().Sum().Var()).ToArray();

    foreach(int j in COLS) {
      col_sums[j].SetMin(0);
    }


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


    //
    // Search
    //
    DecisionBuilder db = solver.MakePhase(col_signs.Concat(row_signs).ToArray(),
                                          Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
                                          Solver.ASSIGN_MAX_VALUE);

    solver.NewSearch(db, obj);

    while (solver.NextSolution()) {
      Console.WriteLine("Sum: {0}",total_sum.Value());
      Console.Write("row_sums: ");
      foreach(int i in ROWS) {
        Console.Write(row_sums[i].Value() + " ");
      }
      Console.Write("\nrow_signs: ");
      foreach(int i in ROWS) {
        Console.Write(row_signs[i].Value() + " ");
      }

      Console.Write("\ncol_sums: ");
      foreach(int j in COLS) {
        Console.Write(col_sums[j].Value() + " ");
      }
      Console.Write("\ncol_signs: ");
      foreach(int j in COLS) {
        Console.Write(col_signs[j].Value() + " ");
      }
      Console.WriteLine("\n");
      foreach(int i in ROWS) {
        foreach(int j in COLS) {
          Console.Write("{0,3} ", 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();

  }
Beispiel #51
0
        private static long Run(int[][] costs, long bestCost = 0)
        {
            bool   finalSearch = bestCost > 0;
            long   result      = 0;
            Solver solver      = new Solver("Assignment");

            int bots  = costs.Length;    // rows
            int tasks = costs[0].Length; // cols

            // Decision variables
            IntVar[,] x = solver.MakeBoolVarMatrix(bots, tasks, "x");
            IntVar[] x_flat = x.Flatten();

            // Dynamic Constraints
            if (bots > tasks)
            {
                // Each bot is assigned to at most 1 task
                for (int i = 0; i < bots; i++)
                {
                    solver.Add((from j in Enumerable.Range(0, tasks)
                                select x[i, j]).ToArray().Sum() <= 1);
                }

                // Each task is assigned to exactly one bot
                for (int j = 0; j < tasks; j++)
                {
                    solver.Add((from i in Enumerable.Range(0, bots)
                                select x[i, j]).ToArray().Sum() == 1);
                }
            }
            else
            {
                // Each task is assigned to exactly one bot
                for (int i = 0; i < bots; i++)
                {
                    solver.Add((from j in Enumerable.Range(0, tasks)
                                select x[i, j]).ToArray().Sum() == 1);
                }

                // Each bot is assigned to at most 1 task
                for (int j = 0; j < tasks; j++)
                {
                    solver.Add((from i in Enumerable.Range(0, bots)
                                select x[i, j]).ToArray().Sum() <= 1);
                }
            }

            // Total cost
            IntVar total_cost = (from i in Enumerable.Range(0, bots)
                                 from j in Enumerable.Range(0, tasks)
                                 select(costs[i][j] * x[i, j])).ToArray().Sum().Var();

            if (bestCost > 0)
            {
                solver.Add(total_cost == bestCost);
            }

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

            if (!finalSearch)
            {
                // Objective
                OptimizeVar objective = total_cost.Minimize(1);
                solver.NewSearch(db, objective);
            }
            else
            {
                solver.NewSearch(db);
            }

            while (solver.NextSolution())
            {
                output.Clear();
                result = total_cost.Value();
                Console.WriteLine($"total_cost: {result}");
                if (finalSearch)
                {
                    for (int i = 0; i < bots; i++)
                    {
                        for (int j = 0; j < tasks; j++)
                        {
                            Console.Write(x[i, j].Value() + " ");
                        }
                        Console.WriteLine();
                    }
                }

                for (int i = 0; i < bots; i++)
                {
                    bool isAssigned = false;
                    for (int j = 0; j < tasks; j++)
                    {
                        if (x[i, j].Value() == 1)
                        {
                            output.Add(new Tuple <int, int>(i, j));
                            isAssigned = true;
                        }
                    }
                    if (!isAssigned)
                    {
                        output.Add(new Tuple <int, int>(i, -1));
                    }
                }
            }

            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());
            Console.WriteLine("Number of constraints = " + solver.Constraints());

            solver.EndSearch();
            return(result);
        }
Beispiel #52
0
  /**
   *
   * Secret Santa problem in Google CP Solver.
   *
   * From Ruby Quiz Secret Santa
   * http://www.rubyquiz.com/quiz2.html
   * """
   * Honoring a long standing tradition started by my wife's dad, my friends
   * all play a Secret Santa game around Christmas time. We draw names and
   * spend a week sneaking that person gifts and clues to our identity. On the
   * last night of the game, we get together, have dinner, share stories, and,
   * most importantly, try to guess who our Secret Santa was. It's a crazily
   * fun way to enjoy each other's company during the holidays.
   *
   * To choose Santas, we use to draw names out of a hat. This system was
   * tedious, prone to many 'Wait, I got myself...' problems. This year, we
   * made a change to the rules that further complicated picking and we knew
   * the hat draw would not stand up to the challenge. Naturally, to solve
   * this problem, I scripted the process. Since that turned out to be more
   * interesting than I had expected, I decided to share.
   *
   * This weeks Ruby Quiz is to implement a Secret Santa selection script.
   * *  Your script will be fed a list of names on STDIN.
   * ...
   * Your script should then choose a Secret Santa for every name in the list.
   * Obviously, a person cannot be their own Secret Santa. In addition, my friends
   * no longer allow people in the same family to be Santas for each other and your
   * script should take this into account.
   * """
   *
   *  Comment: This model skips the file input and mail parts. We
   *        assume that the friends are identified with a number from 1..n,
   *        and the families is identified with a number 1..num_families.
   *
   * Also see http://www.hakank.org/or-tools/secret_santa.py 
   * Also see http://www.hakank.org/or-tools/secret_santa2.cs 
   *
   */
  private static void Solve()
  {

    Solver solver = new Solver("SecretSanta");

    int[] family = {1,1,1,1, 2, 3,3,3,3,3, 4,4};
    int n = family.Length;

    Console.WriteLine("n = {0}", n);

    IEnumerable<int> RANGE = Enumerable.Range(0, n);

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


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

    // Can't be one own"s Secret Santa
    // (i.e. ensure that there are no fix-point in the array.)
    foreach(int i in RANGE) {
      solver.Add(x[i] != i);
    }


    // No Secret Santa to a person in the same family
    foreach(int i in RANGE) {
      solver.Add(solver.MakeIntConst(family[i]) != family.Element(x[i]));
    }

    //
    // Search
    //
    DecisionBuilder db = solver.MakePhase(x,
                                          Solver.INT_VAR_SIMPLE,
                                          Solver.INT_VALUE_SIMPLE);

    solver.NewSearch(db);

    while (solver.NextSolution()) {
      Console.Write("x:  ");
      foreach(int i in RANGE) {
        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();

  }
Beispiel #53
0
    /**
     *
     * P-median problem.
     *
     * Model and data from the OPL Manual, which describes the problem:
     * """
     * The P-Median problem is a well known problem in Operations Research.
     * The problem can be stated very simply, like this: given a set of customers
     * with known amounts of demand, a set of candidate locations for warehouses,
     * and the distance between each pair of customer-warehouse, choose P
     * warehouses to open that minimize the demand-weighted distance of serving
     * all customers from those P warehouses.
     * """
     *
     * Also see http://www.hakank.org/or-tools/p_median.py
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("PMedian");

        //
        // Data
        //
        int p                       = 2;
        int num_customers           = 4;
        IEnumerable <int> CUSTOMERS = Enumerable.Range(0, num_customers);

        int num_warehouses           = 3;
        IEnumerable <int> WAREHOUSES = Enumerable.Range(0, num_warehouses);

        int[] demand = { 100, 80, 80, 70 };
        int[,] distance = { { 2, 10, 50 }, { 2, 10, 52 }, { 50, 60, 3 }, { 40, 60, 1 } };

        //
        // Decision variables
        //

        IntVar[] open = solver.MakeIntVarArray(num_warehouses, 0, num_warehouses, "open");
        IntVar[,] ship = solver.MakeIntVarMatrix(num_customers, num_warehouses, 0, 1, "ship");
        IntVar z = solver.MakeIntVar(0, 1000, "z");

        //
        // Constraints
        //

        solver.Add(
            (from c in CUSTOMERS from w in WAREHOUSES select(demand[c] * distance[c, w] * ship[c, w]))
            .ToArray()
            .Sum() == z);

        solver.Add(open.Sum() == p);

        foreach (int c in CUSTOMERS)
        {
            foreach (int w in WAREHOUSES)
            {
                solver.Add(ship[c, w] <= open[w]);
            }

            solver.Add((from w in WAREHOUSES select ship[c, w]).ToArray().Sum() == 1);
        }

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

        //
        // Search
        //
        DecisionBuilder db = solver.MakePhase(open.Concat(ship.Flatten()).ToArray(),
                                              Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);

        solver.NewSearch(db, obj);

        while (solver.NextSolution())
        {
            Console.WriteLine("z: {0}", z.Value());
            Console.Write("open:");
            foreach (int w in WAREHOUSES)
            {
                Console.Write(open[w].Value() + " ");
            }
            Console.WriteLine();
            foreach (int c in CUSTOMERS)
            {
                foreach (int w in WAREHOUSES)
                {
                    Console.Write(ship[c, w].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();
    }
Beispiel #54
0
  /**
   *
   * Coin application.
   *
   * From "Constraint Logic Programming using ECLiPSe"
   *  pages 99f and 234 ff.
   * The solution in ECLiPSe is at page 236.
   *
   * """
   * What is the minimum number of coins that allows one to pay _exactly_
   * any amount smaller than one Euro? Recall that there are six different
   * euro cents, of denomination 1, 2, 5, 10, 20, 50
   * """

   * Also see http://www.hakank.org/or-tools/coins3.py 
   *
   */
  private static void Solve()
  {

    Solver solver = new Solver("Coins3");

    //
    // Data
    //
    int n = 6; // number of different coins
    int[] variables = {1, 2, 5, 10, 25, 50};

    IEnumerable<int> RANGE = Enumerable.Range(0, n);

    //
    // Decision variables
    //
    IntVar[] x = solver.MakeIntVarArray(n, 0, 99, "x");
    IntVar num_coins = x.Sum().VarWithName("num_coins");


    //
    // Constraints
    //

    // Check that all changes from 1 to 99 can be made.
    for(int j = 1; j < 100; j++) {
      IntVar[] tmp = solver.MakeIntVarArray(n, 0, 99, "tmp");
      solver.Add(tmp.ScalProd(variables) == j);

      foreach(int i in RANGE) {
        solver.Add(tmp[i] <= x[i]);
      }

    }

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

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

    solver.NewSearch(db, obj);

    while (solver.NextSolution()) {
      Console.WriteLine("num_coins: {0}", num_coins.Value());
      Console.Write("x:  ");
      foreach(int i in RANGE) {
        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();

  }
    /**
     *
     * Nurse rostering
     *
     * This is a simple nurse rostering model using a DFA and
     * the built-in TransitionConstraint.
     *
     * The DFA is from MiniZinc Tutorial, Nurse Rostering example:
     * - one day off every 4 days
     * - no 3 nights in a row.
     *
     * Also see:
     *  - http://www.hakank.org/or-tools/nurse_rostering.py
     *  - http://www.hakank.org/or-tools/nurse_rostering_regular.cs
     *    which use (a decomposition of) regular constraint
     *
     */
    private static void Solve(int nurse_multiplier, int week_multiplier)
    {
        Console.WriteLine("Starting Nurse Rostering");
        Console.WriteLine("  - {0} teams of 7 nurses", nurse_multiplier);
        Console.WriteLine("  - {0} blocks of 14 days", week_multiplier);

        Solver solver = new Solver("NurseRostering");

        //
        // Data
        //

        // Note: If you change num_nurses or num_days,
        //       please also change the constraints
        //       on nurse_stat and/or day_stat.
        int num_nurses = 7 * nurse_multiplier;
        int num_days   = 14 * week_multiplier;

        // Note: I had to add a dummy shift.
        int dummy_shift = 0;
        int day_shift   = 1;
        int night_shift = 2;
        int off_shift   = 3;

        int[] shifts       = { dummy_shift, day_shift, night_shift, off_shift };
        int[] valid_shifts = { day_shift, night_shift, off_shift };

        // the DFA (for regular)
        int initial_state = 1;

        int[] accepting_states = { 1, 2, 3, 4, 5, 6 };

        /*
         * // This is the transition function
         * // used in nurse_rostering_regular.cs
         * int[,] transition_fn = {
         * // d,n,o
         * {2,3,1}, // state 1
         * {4,4,1}, // state 2
         * {4,5,1}, // state 3
         * {6,6,1}, // state 4
         * {6,0,1}, // state 5
         * {0,0,1}  // state 6
         * };
         */

        // For TransitionConstraint
        IntTupleSet transition_tuples = new IntTupleSet(3);

        // state, input, next state
        transition_tuples.InsertAll(new long[][] {
            new long[] { 1, 1, 2 },
            new long[] { 1, 2, 3 },
            new long[] { 1, 3, 1 },
            new long[] { 2, 1, 4 },
            new long[] { 2, 2, 4 },
            new long[] { 2, 3, 1 },
            new long[] { 3, 1, 4 },
            new long[] { 3, 2, 5 },
            new long[] { 3, 3, 1 },
            new long[] { 4, 1, 6 },
            new long[] { 4, 2, 6 },
            new long[] { 4, 3, 1 },
            new long[] { 5, 1, 6 },
            new long[] { 5, 3, 1 },
            new long[] { 6, 3, 1 }
        });

        string[] days = { "d", "n", "o" }; // for presentation

        //
        // Decision variables
        //

        //
        // For TransitionConstraint
        //
        IntVar[,] x =
            solver.MakeIntVarMatrix(num_nurses, num_days, valid_shifts, "x");
        IntVar[] x_flat = x.Flatten();

        //
        // summary of the nurses
        //
        IntVar[] nurse_stat = new IntVar[num_nurses];

        //
        // summary of the shifts per day
        //
        int num_shifts = shifts.Length;

        IntVar[,] day_stat = new IntVar[num_days, num_shifts];
        for (int i = 0; i < num_days; i++)
        {
            for (int j = 0; j < num_shifts; j++)
            {
                day_stat[i, j] = solver.MakeIntVar(0, num_nurses, "day_stat");
            }
        }

        //
        // Constraints
        //
        for (int i = 0; i < num_nurses; i++)
        {
            IntVar[] reg_input = new IntVar[num_days];
            for (int j = 0; j < num_days; j++)
            {
                reg_input[j] = x[i, j];
            }

            solver.Add(reg_input.Transition(transition_tuples,
                                            initial_state,
                                            accepting_states));
        }

        //
        // Statistics and constraints for each nurse
        //
        for (int nurse = 0; nurse < num_nurses; nurse++)
        {
            // Number of worked days (either day or night shift)
            IntVar[] nurse_days = new IntVar[num_days];
            for (int day = 0; day < num_days; day++)
            {
                nurse_days[day] =
                    x[nurse, day].IsMember(new int[] { day_shift, night_shift });
            }
            nurse_stat[nurse] = nurse_days.Sum().Var();

            // Each nurse must work between 7 and 10
            // days/nights during this period
            solver.Add(nurse_stat[nurse] >= 7 * week_multiplier / nurse_multiplier);
            solver.Add(nurse_stat[nurse] <= 10 * week_multiplier / nurse_multiplier);
        }

        //
        // Statistics and constraints for each day
        //
        for (int day = 0; day < num_days; day++)
        {
            IntVar[] nurses = new IntVar[num_nurses];
            for (int nurse = 0; nurse < num_nurses; nurse++)
            {
                nurses[nurse] = x[nurse, day];
            }
            IntVar[] stats = new IntVar[num_shifts];
            for (int shift = 0; shift < num_shifts; ++shift)
            {
                stats[shift] = day_stat[day, shift];
            }
            solver.Add(nurses.Distribute(stats));

            //
            // Some constraints for each day:
            //
            // Note: We have a strict requirements of
            //       the number of shifts.
            //       Using atleast constraints is harder
            //       in this model.
            //
            if (day % 7 == 5 || day % 7 == 6)
            {
                // special constraints for the weekends
                solver.Add(day_stat[day, day_shift] == 2 * nurse_multiplier);
                solver.Add(day_stat[day, night_shift] == nurse_multiplier);
                solver.Add(day_stat[day, off_shift] == 4 * nurse_multiplier);
            }
            else
            {
                // for workdays:

                // - exactly 3 on day shift
                solver.Add(day_stat[day, day_shift] == 3 * nurse_multiplier);
                // - exactly 2 on night
                solver.Add(day_stat[day, night_shift] == 2 * nurse_multiplier);
                // - exactly 2 off duty
                solver.Add(day_stat[day, off_shift] == 2 * nurse_multiplier);
            }
        }

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

        SearchMonitor log = solver.MakeSearchLog(1000000);

        solver.NewSearch(db, log);

        int num_solutions = 0;

        while (solver.NextSolution())
        {
            num_solutions++;
            for (int i = 0; i < num_nurses; i++)
            {
                Console.Write("Nurse #{0,-2}: ", i);
                var occ = new Dictionary <int, int>();
                for (int j = 0; j < num_days; j++)
                {
                    int v = (int)x[i, j].Value() - 1;
                    if (!occ.ContainsKey(v))
                    {
                        occ[v] = 0;
                    }
                    occ[v]++;
                    Console.Write(days[v] + " ");
                }

                Console.Write(" #workdays: {0,2}", nurse_stat[i].Value());
                foreach (int s in valid_shifts)
                {
                    int v = 0;
                    if (occ.ContainsKey(s - 1))
                    {
                        v = occ[s - 1];
                    }
                    Console.Write("  {0}:{1}", days[s - 1], v);
                }
                Console.WriteLine();
            }
            Console.WriteLine();

            Console.WriteLine("Statistics per day:\nDay      d n o");
            for (int j = 0; j < num_days; j++)
            {
                Console.Write("Day #{0,2}: ", j);
                foreach (int t in valid_shifts)
                {
                    Console.Write(day_stat[j, t].Value() + " ");
                }
                Console.WriteLine();
            }
            Console.WriteLine();

            // We just show 2 solutions
            if (num_solutions > 1)
            {
                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();
    }
Beispiel #56
0
  /**
   *
   * Olympic puzzle.
   * 
   * Benchmark for Prolog (BProlog)
   * """
   * File   : olympic.pl
   * Author : Neng-Fa ZHOU
   * Date   : 1993
   *
   * Purpose: solve a puzzle taken from Olympic Arithmetic Contest
   *
   * Given ten variables with the following configuration:
   *
   *                 X7   X8   X9   X10
   *
   *                    X4   X5   X6
   *
   *                       X2   X3
   *
   *                          X1
   *
   * We already know that X1 is equal to 3 and want to assign each variable
   * with a different integer from {1,2,...,10} such that for any three
   * variables
   *                        Xi   Xj
   *
   *                           Xk
   *
   * the following constraint is satisfied:
   *
   *                      |Xi-Xj| = Xk
   * """
   *
   * Also see http://www.hakank.org/or-tools/olympic.py
   *
   */
  private static void Solve()
  {
    Solver solver = new Solver("Olympic");

    //
    // Data
    //
    int n = 10;

    //
    // Decision variables
    //
    IntVar[] x = solver.MakeIntVarArray(n, 1, n, "x");
    IntVar X1  = x[0];
    IntVar X2  = x[1];
    IntVar X3  = x[2];
    IntVar X4  = x[3];
    IntVar X5  = x[4];
    IntVar X6  = x[5];
    IntVar X7  = x[6];
    IntVar X8  = x[7];
    IntVar X9  = x[8];
    IntVar X10 = x[9];


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

    solver.Add(X1 == 3);
    minus(solver, X2, X3, X1);
    minus(solver, X4, X5, X2);
    minus(solver, X5, X6, X3);
    minus(solver, X7, X8, X4);
    minus(solver, X8, X9, X5);
    minus(solver, X9, X10, X6);


    //
    // Search
    //
    DecisionBuilder db = solver.MakePhase(x,
                                          Solver.INT_VAR_SIMPLE,
                                          Solver.INT_VALUE_DEFAULT);

    solver.NewSearch(db);

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

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

    solver.EndSearch();

  }
Beispiel #57
0
    /**
     *
     * Solves the Magic Square problem.
     * See http://www.hakank.org/or-tools/magic_square.py
     *
     */
    private static void Solve(int n = 4, int num = 0, int print = 1)
    {
        Solver solver = new Solver("MagicSquare");

        Console.WriteLine("n: {0}", n);

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

        //
        // Constraints
        //
        long s = (n * (n * n + 1)) / 2;

        Console.WriteLine("s: " + s);

        IntVar[] diag1 = new IntVar[n];
        IntVar[] diag2 = new IntVar[n];
        for (int i = 0; i < n; i++)
        {
            IntVar[] row = new IntVar[n];
            for (int j = 0; j < n; j++)
            {
                row[j] = x[i, j];
            }
            // sum row to s
            solver.Add(row.Sum() == s);

            diag1[i] = x[i, i];
            diag2[i] = x[i, n - i - 1];
        }

        // sum diagonals to s
        solver.Add(diag1.Sum() == s);
        solver.Add(diag2.Sum() == s);

        // sum columns to s
        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.Sum() == s);
        }

        // all are different
        solver.Add(x_flat.AllDifferent());

        // symmetry breaking: upper left is 1
        // solver.Add(x[0,0] == 1);

        //
        // Search
        //

        DecisionBuilder db =
            solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_CENTER_VALUE);

        solver.NewSearch(db);

        int c = 0;

        while (solver.NextSolution())
        {
            if (print != 0)
            {
                for (int i = 0; i < n; i++)
                {
                    for (int j = 0; j < n; j++)
                    {
                        Console.Write(x[i, j].Value() + " ");
                    }
                    Console.WriteLine();
                }
                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();
    }
Beispiel #58
0
  /**
   *
   * Solves a simple map coloring problem.
   *
   * Alternative version, using a matrix to represent
   * the neighbours.
   *
   * See http://www.hakank.org/google_or_tools/map.py
   *
   *
   */
  private static void Solve()
  {
    Solver solver = new Solver("Map2");

    //
    // data
    //
    int Belgium     = 0;
    int Denmark     = 1;
    int France      = 2;
    int Germany     = 3;
    int Netherlands = 4;
    int Luxembourg  = 5;

    int n = 6;
    int max_num_colors = 4;

    int[,] neighbours =  {{France,     Belgium},
                         {France,     Luxembourg},
                         {France,     Germany},
                         {Luxembourg, Germany},
                         {Luxembourg, Belgium},
                         {Belgium,    Netherlands},
                         {Belgium,    Germany},
                         {Germany,    Netherlands},
                         {Germany,    Denmark}};



    //
    // Decision variables
    //
    IntVar[] color = solver.MakeIntVarArray(n, 1, max_num_colors, "color");

    //
    // Constraints
    //
    for(int i = 0; i < neighbours.GetLength(0); i++) {
      solver.Add(color[neighbours[i,0]] != color[neighbours[i,1]]);
    }

    // Symmetry breaking
    solver.Add(color[Belgium] == 1);


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

    solver.NewSearch(db);
    while (solver.NextSolution()) {
      Console.Write("colors: ");
      for(int i = 0; i < n; i++) {
        Console.Write("{0} ", color[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();

  }
Beispiel #59
0
    /**
     *
     * Magic squares and cards problem.
     *
     * Martin Gardner (July 1971)
     * """
     * Allowing duplicates values, what is the largest constant sum for an order-3
     * magic square that can be formed with nine cards from the deck.
     * """
     *
     *
     * Also see http://www.hakank.org/or-tools/magic_square_and_cards.py
     *
     */
    private static void Solve(int n = 3)
    {
        Solver solver = new Solver("MagicSquareAndCards");

        IEnumerable <int> RANGE = Enumerable.Range(0, n);

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

        IntVar s = solver.MakeIntVar(1, 13 * 4, "s");

        IntVar[] counts = solver.MakeIntVarArray(14, 0, 4, "counts");

        //
        // Constraints
        //

        solver.Add(x_flat.Distribute(counts));

        // the standard magic square constraints (sans all_different)
        foreach (int i in RANGE)
        {
            // rows
            solver.Add((from j in RANGE select x[i, j]).ToArray().Sum() == s);

            // columns
            solver.Add((from j in RANGE select x[j, i]).ToArray().Sum() == s);
        }

        // diagonals
        solver.Add((from i in RANGE select x[i, i]).ToArray().Sum() == s);
        solver.Add((from i in RANGE select x[i, n - i - 1]).ToArray().Sum() == s);

        // redundant constraint
        solver.Add(counts.Sum() == n * n);

        //
        // Objective
        //
        OptimizeVar obj = s.Maximize(1);

        //
        // Search
        //
        DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MAX_VALUE);

        solver.NewSearch(db, obj);

        while (solver.NextSolution())
        {
            Console.WriteLine("s: {0}", s.Value());
            Console.Write("counts:");
            for (int i = 0; i < 14; i++)
            {
                Console.Write(counts[i].Value() + " ");
            }
            Console.WriteLine();
            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();
    }
Beispiel #60
0
  /**
   *
   * Crew allocation problem  in Google CP Solver.
   *
   * From Gecode example crew
   * examples/crew.cc
   * """
   * Example: Airline crew allocation
   *
   * Assign 20 flight attendants to 10 flights. Each flight needs a certain
   * number of cabin crew, and they have to speak certain languages.
   * Every cabin crew member has two flights off after an attended flight.
   * """
   *
   * Also see http://www.hakank.org/or-tools/crew.pl
   *
   */
  private static void Solve(int sols = 1, int minimize = 0)
  {
    Solver solver = new Solver("Crew");

    //
    // Data
    //
    string[] names = {"Tom",
                      "David",
                      "Jeremy",
                      "Ron",
                      "Joe",
                      "Bill",
                      "Fred",
                      "Bob",
                      "Mario",
                      "Ed",
                      "Carol",
                      "Janet",
                      "Tracy",
                      "Marilyn",
                      "Carolyn",
                      "Cathy",
                      "Inez",
                      "Jean",
                      "Heather",
                      "Juliet"};

    int num_persons = names.Length;


    //
    // Attributes of the crew
    //
    int[,] attributes = {
      // steward, hostess, french, spanish, german
      {1,0,0,0,1},   // Tom     = 0
      {1,0,0,0,0},   // David   = 1
      {1,0,0,0,1},   // Jeremy  = 2
      {1,0,0,0,0},   // Ron     = 3
      {1,0,0,1,0},   // Joe     = 4
      {1,0,1,1,0},   // Bill    = 5
      {1,0,0,1,0},   // Fred    = 6
      {1,0,0,0,0},   // Bob     = 7
      {1,0,0,1,1},   // Mario   = 8
      {1,0,0,0,0},   // Ed      = 9
      {0,1,0,0,0},   // Carol   = 10
      {0,1,0,0,0},   // Janet   = 11
      {0,1,0,0,0},   // Tracy   = 12
      {0,1,0,1,1},   // Marilyn = 13
      {0,1,0,0,0},   // Carolyn = 14
      {0,1,0,0,0},   // Cathy   = 15
      {0,1,1,1,1},   // Inez    = 16
      {0,1,1,0,0},   // Jean    = 17
      {0,1,0,1,1},   // Heather = 18
      {0,1,1,0,0}    // Juliet  = 19
    };


    //
    // Required number of crew members.
    //
    // The columns are in the following order:
    // staff     : Overall number of cabin crew needed
    // stewards  : How many stewards are required
    // hostesses : How many hostesses are required
    // french    : How many French speaking employees are required
    // spanish   : How many Spanish speaking employees are required
    // german    : How many German speaking employees are required
    //
    int[,] required_crew = {
        {4,1,1,1,1,1}, // Flight 1
        {5,1,1,1,1,1}, // Flight 2
        {5,1,1,1,1,1}, // ..
        {6,2,2,1,1,1},
        {7,3,3,1,1,1},
        {4,1,1,1,1,1},
        {5,1,1,1,1,1},
        {6,1,1,1,1,1},
        {6,2,2,1,1,1}, // ...
        {7,3,3,1,1,1}  // Flight 10
        };

    int num_flights = required_crew.GetLength(0);


    //
    // Decision variables
    //
    IntVar[,] crew = solver.MakeIntVarMatrix(num_flights, num_persons,
                                             0, 1, "crew");
    IntVar[] crew_flat = crew.Flatten();

    // number of working persons
    IntVar num_working = solver.MakeIntVar(1, num_persons, "num_working");

    //
    // Constraints
    //

    // number of working persons
    IntVar[] nw = new IntVar[num_persons];
    for(int p = 0; p < num_persons; p++) {
      IntVar[] tmp = new IntVar[num_flights];
      for(int f = 0; f < num_flights; f++) {
        tmp[f] = crew[f,p];
      }
      nw[p] = tmp.Sum() > 0;
    }
    solver.Add(nw.Sum() == num_working);

    for(int f = 0; f < num_flights; f++) {
      // size of crew
      IntVar[] tmp = new IntVar[num_persons];
      for(int p = 0; p < num_persons; p++) {
        tmp[p] = crew[f,p];
      }
      solver.Add(tmp.Sum() == required_crew[f,0]);

      // attributes and requirements
      for(int a = 0; a < 5; a++) {
        IntVar[] tmp2 = new IntVar[num_persons];
        for(int p = 0; p < num_persons; p++) {
          tmp2[p] = (crew[f,p]*attributes[p,a]).Var();
        }
        solver.Add(tmp2.Sum() >= required_crew[f,a+1]);
      }
    }

    // after a flight, break for at least two flights
    for(int f = 0; f < num_flights - 2; f++) {
      for(int i = 0; i < num_persons; i++) {
        solver.Add(crew[f,i] + crew[f+1,i] + crew[f+2,i] <= 1);
      }
    }

    // extra contraint: all must work at least two of the flights
    /*
    for(int p = 0; p < num_persons; p++) {
      IntVar[] tmp = new IntVar[num_flights];
      for(int f = 0; f < num_flights; f++) {
        tmp[f] = crew[f,p];
      }
      solver.Add(tmp.Sum() >= 2);
    }
    */


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

    if (minimize > 0) {
      OptimizeVar obj = num_working.Minimize(1);
      solver.NewSearch(db, obj);
    } else {
      solver.NewSearch(db);
    }

    int num_solutions = 0;
    while (solver.NextSolution()) {
      num_solutions++;
      Console.WriteLine("Solution #{0}", num_solutions);
      Console.WriteLine("Number working: {0}", num_working.Value());

      for(int f = 0; f < num_flights; f++) {
        for(int p = 0; p < num_persons; p++) {
          Console.Write(crew[f,p].Value() + " ");
        }
        Console.WriteLine();
      }
      Console.WriteLine("\nFlights: ");
      for(int f = 0; f < num_flights; f++) {
        Console.Write("Flight #{0}: ", f);
        for(int p = 0; p < num_persons; p++) {
          if (crew[f, p].Value() == 1) {
            Console.Write(names[p] + " ");
          }
        }
        Console.WriteLine();
      }

      Console.WriteLine("\nCrew:");
      for(int p = 0; p < num_persons; p++) {
        Console.Write("{0,-10}", names[p]);
        for(int f = 0; f < num_flights; f++) {
          if (crew[f,p].Value() == 1) {
            Console.Write(f + " ");
          }
        }
        Console.WriteLine();
      }

      Console.WriteLine();

      if (num_solutions >= sols) {
        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();

  }