/** * * 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(); }
/** * * 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(); }
/** * * 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(); }
// We don't need helper functions here // Csharp syntax is easier than C++ syntax! private static void CPisFun (int kBase) { // Constraint Programming engine Solver solver = new Solver ("CP is fun!"); // Decision variables IntVar c = solver.MakeIntVar (1, kBase - 1, "C"); IntVar p = solver.MakeIntVar (0, kBase - 1, "P"); IntVar i = solver.MakeIntVar (1, kBase - 1, "I"); IntVar s = solver.MakeIntVar (0, kBase - 1, "S"); IntVar f = solver.MakeIntVar (1, kBase - 1, "F"); IntVar u = solver.MakeIntVar (0, kBase - 1, "U"); IntVar n = solver.MakeIntVar (0, kBase - 1, "N"); IntVar t = solver.MakeIntVar (1, kBase - 1, "T"); IntVar r = solver.MakeIntVar (0, kBase - 1, "R"); IntVar e = solver.MakeIntVar (0, kBase - 1, "E"); // We need to group variables in a vector to be able to use // the global constraint AllDifferent IntVar[] letters = new IntVar[] { c, p, i, s, f, u, n, t, r, e}; // Check if we have enough digits if (kBase < letters.Length) { throw new Exception("kBase < letters.Length"); } // Constraints solver.Add (letters.AllDifferent ()); // CP + IS + FUN = TRUE solver.Add (p + s + n + kBase * (c + i + u) + kBase * kBase * f == e + kBase * u + kBase * kBase * r + kBase * kBase * kBase * t); SolutionCollector all_solutions = solver.MakeAllSolutionCollector(); // Add the interesting variables to the SolutionCollector all_solutions.Add(c); all_solutions.Add(p); // Create the variable kBase * c + p IntVar v1 = solver.MakeSum(solver.MakeProd(c, kBase), p).Var(); // Add it to the SolutionCollector all_solutions.Add(v1); // Decision Builder: hot to scour the search tree DecisionBuilder db = solver.MakePhase (letters, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.Solve(db, all_solutions); // Retrieve the solutions int numberSolutions = all_solutions.SolutionCount(); Console.WriteLine ("Number of solutions: " + numberSolutions); for (int index = 0; index < numberSolutions; ++index) { Assignment solution = all_solutions.Solution(index); Console.WriteLine ("Solution found:"); Console.WriteLine ("v1=" + solution.Value(v1)); } }
/** * * Solve the SEND+MORE=MONEY problem * */ private static void Solve() { Solver solver = new Solver("SendMoreMoney"); // // Decision variables // IntVar S = solver.MakeIntVar(0, 9, "S"); IntVar E = solver.MakeIntVar(0, 9, "E"); IntVar N = solver.MakeIntVar(0, 9, "N"); IntVar D = solver.MakeIntVar(0, 9, "D"); IntVar M = solver.MakeIntVar(0, 9, "M"); IntVar O = solver.MakeIntVar(0, 9, "O"); IntVar R = solver.MakeIntVar(0, 9, "R"); IntVar Y = solver.MakeIntVar(0, 9, "Y"); // for AllDifferent() IntVar[] x = new IntVar[] { S, E, N, D, M, O, R, Y }; // // Constraints // solver.Add(x.AllDifferent()); solver.Add(S * 1000 + E * 100 + N * 10 + D + M * 1000 + O * 100 + R * 10 + E == M * 10000 + O * 1000 + N * 100 + E * 10 + Y); solver.Add(S > 0); solver.Add(M > 0); // // Search // DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { for (int i = 0; i < 8; i++) { Console.Write(x[i].ToString() + " "); } Console.WriteLine(); } Console.WriteLine("\nWallTime: " + solver.WallTime() + "ms "); Console.WriteLine("Failures: " + solver.Failures()); Console.WriteLine("Branches: " + solver.Branches()); solver.EndSearch(); }
public void doWork() { Solver solver = new Solver("Cryptogram"); // One decision variable for each character: IntVar S = solver.MakeIntVar(0, 9); IntVar E = solver.MakeIntVar(0, 9); IntVar N = solver.MakeIntVar(0, 9); IntVar D = solver.MakeIntVar(0, 9); IntVar M = solver.MakeIntVar(0, 9); IntVar O = solver.MakeIntVar(0, 9); IntVar R = solver.MakeIntVar(0, 9); IntVar Y = solver.MakeIntVar(0, 9); IntVar[] vars = new IntVar[] { S, E, N, D, M, O, R, Y }; // SEND + MORE = MONEY: IntVar send = (S * 1000 + E * 100 + N * 10 + D).Var(); IntVar more = (M * 1000 + O * 100 + R * 10 + E).Var(); IntVar money = (M * 10000 + O * 1000 + N * 100 + E * 10 + Y).Var(); solver.Add(send + more == money); //Leading characters must not be zero: solver.Add(S != 0); solver.Add(M != 0); // Part B: All characters must take different values: // Otherwise we get 155 possible solutions! solver.Add(vars.AllDifferent()); DecisionBuilder db = solver.MakePhase( vars, // Decision variables to resolve Solver.INT_VAR_SIMPLE, // Variable selection policy for search Solver.INT_VALUE_SIMPLE); // Value selection policy for search solver.NewSearch(db); while (solver.NextSolution()) { Console.WriteLine(" SEND | " + send.Value()); Console.WriteLine(" + MORE | + " + more.Value()); Console.WriteLine(" ------- | -------"); Console.WriteLine(" MONEY | " + money.Value() + "\n"); } solver.EndSearch(); // Display the number of solutions found: Console.WriteLine("Total solution(s): " + solver.Solutions()); }
/** * * 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(); }
/** * circuit(solver, x, z) * * A decomposition of the global constraint circuit, based * on some observation of the orbits in an array. * * This version also exposes z (the path) to the public. * * Note: The domain of x must be 0..n-1 (not 1..n) * since C# is 0-based. */ public static void circuit(Solver solver, IntVar[] x, IntVar[] z) { int n = x.Length; solver.Add(x.AllDifferent()); solver.Add(z.AllDifferent()); // put the orbit of x[0] in z[0..n-1] solver.Add(z[0] == x[0]); for(int i = 1; i < n-1; i++) { solver.Add(z[i] == x.Element(z[i-1])); } // z may not be 0 for i < n-1 for(int i = 1; i < n - 1; i++) { solver.Add(z[i] != 0); } // when i = n-1 it must be 0 solver.Add(z[n - 1] == 0); }
// We don't need helper functions here // Csharp syntax is easier than C++ syntax! private static void CPisFun() { // Constraint Programming engine Solver solver = new Solver("CP is fun!"); const int kBase = 10; // Decision variables IntVar c = solver.MakeIntVar(1, kBase - 1, "C"); IntVar p = solver.MakeIntVar(0, kBase - 1, "P"); IntVar i = solver.MakeIntVar(1, kBase - 1, "I"); IntVar s = solver.MakeIntVar(0, kBase - 1, "S"); IntVar f = solver.MakeIntVar(1, kBase - 1, "F"); IntVar u = solver.MakeIntVar(0, kBase - 1, "U"); IntVar n = solver.MakeIntVar(0, kBase - 1, "N"); IntVar t = solver.MakeIntVar(1, kBase - 1, "T"); IntVar r = solver.MakeIntVar(0, kBase - 1, "R"); IntVar e = solver.MakeIntVar(0, kBase - 1, "E"); // We need to group variables in a vector to be able to use // the global constraint AllDifferent IntVar[] letters = new IntVar[] { c, p, i, s, f, u, n, t, r, e }; // Check if we have enough digits if (kBase < letters.Length) { throw new Exception("kBase < letters.Length"); } // Constraints solver.Add(letters.AllDifferent()); // CP + IS + FUN = TRUE solver.Add(p + s + n + kBase * (c + i + u) + kBase * kBase * f == e + kBase * u + kBase * kBase * r + kBase * kBase * kBase * t); // Decision Builder: hot to scour the search tree DecisionBuilder db = solver.MakePhase(letters, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); if (solver.NextSolution()) { Console.WriteLine("Solution found:"); Console.Write("C=" + c.Value() + " P=" + p.Value()); Console.Write(" I=" + i.Value() + " S=" + s.Value()); Console.Write(" F=" + f.Value() + " U=" + u.Value()); Console.Write(" N=" + n.Value() + " T=" + t.Value()); Console.Write(" R=" + r.Value() + " E=" + e.Value()); Console.WriteLine(); // Is CP + IS + FUN = TRUE? if (p.Value() + s.Value() + n.Value() + kBase * (c.Value() + i.Value() + u.Value()) + kBase * kBase * f.Value() != e.Value() + kBase * u.Value() + kBase * kBase * r.Value() + kBase * kBase * kBase * t.Value()) { throw new Exception("CP + IS + FUN != TRUE"); } } else { Console.WriteLine("Cannot solve problem."); } // if (solver.NextSolution()) solver.EndSearch(); }
/** * * 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(); }
/** * * This is a port of Charles Prud'homme's Java model * Partition.java * """ * Partition n numbers into two groups, so that * - the sum of the first group equals the sum of the second, * - and the sum of the squares of the first group equals the sum of * the squares of the second * """ * */ private static void Solve(int m) { Solver solver = new Solver("Partition"); // // Decision variables // IntVar[] x = solver.MakeIntVarArray(m, 1, 2 * m, "x"); IntVar[] y = solver.MakeIntVarArray(m, 1, 2 * m, "y"); // // Constraints // // break symmetries for (int i = 0; i < m - 1; i++) { solver.Add(x[i] < x[i + 1]); solver.Add(y[i] < y[i + 1]); } solver.Add(x[0] < y[0]); IntVar[] xy = new IntVar[2 * m]; for (int i = m - 1; i >= 0; i--) { xy[i] = x[i]; xy[m + i] = y[i]; } solver.Add(xy.AllDifferent()); int[] coeffs = new int[2 * m]; for (int i = m - 1; i >= 0; i--) { coeffs[i] = 1; coeffs[m + i] = -1; } solver.Add(xy.ScalProd(coeffs) == 0); IntVar[] sxy, sx, sy; sxy = new IntVar[2 * m]; sx = new IntVar[m]; sy = new IntVar[m]; for (int i = m - 1; i >= 0; i--) { sx[i] = x[i].Square().Var(); sxy[i] = sx[i]; sy[i] = y[i].Square().Var(); sxy[m + i] = sy[i]; } solver.Add(sxy.ScalProd(coeffs) == 0); solver.Add(x.Sum() == 2 * m * (2 * m + 1) / 4); solver.Add(y.Sum() == 2 * m * (2 * m + 1) / 4); solver.Add(sx.Sum() == 2 * m * (2 * m + 1) * (4 * m + 1) / 12); solver.Add(sy.Sum() == 2 * m * (2 * m + 1) * (4 * m + 1) / 12); // // Search // DecisionBuilder db = solver.MakeDefaultPhase(xy); SearchMonitor log = solver.MakeSearchLog(10000); solver.NewSearch(db, log); while (solver.NextSolution()) { for(int i = 0; i < m; i++) { Console.Write("[" + xy[i].Value() + "] "); } Console.WriteLine(); for(int i = 0; i < m; i++) { Console.Write("[" + xy[m+i].Value() + "] "); } Console.WriteLine("\n"); } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); Console.WriteLine("WallTime: {0}ms", solver.WallTime()); Console.WriteLine("Failures: {0}", solver.Failures()); Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); }
/** * * Solve the SEND+MOST=MONEY problem * where the object is to maximize MONEY * See http://www.hakank.org/google_or_tools/send_most_money.py * */ private static long Solve(long MONEY) { Solver solver = new Solver("SendMostMoney"); // // Decision variables // IntVar S = solver.MakeIntVar(0, 9, "S"); IntVar E = solver.MakeIntVar(0, 9, "E"); IntVar N = solver.MakeIntVar(0, 9, "N"); IntVar D = solver.MakeIntVar(0, 9, "D"); IntVar M = solver.MakeIntVar(0, 9, "M"); IntVar O = solver.MakeIntVar(0, 9, "O"); IntVar T = solver.MakeIntVar(0, 9, "T"); IntVar Y = solver.MakeIntVar(0, 9, "Y"); // for AllDifferent() IntVar[] x = new IntVar[] { S, E, N, D, M, O, T, Y }; IntVar[] eq = { S, E, N, D, M, O, S, T, M, O, N, E, Y }; int[] coeffs = { 1000, 100, 10, 1, // S E N D + 1000, 100, 10, 1, // M O S T -10000, -1000, -100, -10, -1 // == M O N E Y }; solver.Add(eq.ScalProd(coeffs) == 0); // IntVar money = solver.MakeScalProd(new IntVar[] {M, O, N, E, Y}, // new int[] {10000, 1000, 100, 10, // 1}).Var(); IntVar money = (new IntVar[] { M, O, N, E, Y }).ScalProd(new int[] { 10000, 1000, 100, 10, 1 }).Var(); // // Constraints // solver.Add(x.AllDifferent()); solver.Add(S > 0); solver.Add(M > 0); if (MONEY > 0) { solver.Add(money == MONEY); } // // Search // DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); if (MONEY == 0) { OptimizeVar obj = money.Maximize(1); solver.NewSearch(db, obj); } else { solver.NewSearch(db); } long money_ret = 0; while (solver.NextSolution()) { money_ret = money.Value(); Console.WriteLine("money: {0}", money.Value()); for (int i = 0; i < x.Length; i++) { Console.Write(x[i].Value() + " "); } Console.WriteLine(); } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); Console.WriteLine("WallTime: {0}ms", solver.WallTime()); Console.WriteLine("Failures: {0}", solver.Failures()); Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); return(money_ret); }
// We don't need helper functions here // Csharp syntax is easier than C++ syntax! private static void CPisFun () { // Constraint Programming engine Solver solver = new Solver ("CP is fun!"); const int kBase = 10; // Decision variables IntVar c = solver.MakeIntVar (1, kBase - 1, "C"); IntVar p = solver.MakeIntVar (0, kBase - 1, "P"); IntVar i = solver.MakeIntVar (1, kBase - 1, "I"); IntVar s = solver.MakeIntVar (0, kBase - 1, "S"); IntVar f = solver.MakeIntVar (1, kBase - 1, "F"); IntVar u = solver.MakeIntVar (0, kBase - 1, "U"); IntVar n = solver.MakeIntVar (0, kBase - 1, "N"); IntVar t = solver.MakeIntVar (1, kBase - 1, "T"); IntVar r = solver.MakeIntVar (0, kBase - 1, "R"); IntVar e = solver.MakeIntVar (0, kBase - 1, "E"); // We need to group variables in a vector to be able to use // the global constraint AllDifferent IntVar[] letters = new IntVar[] { c, p, i, s, f, u, n, t, r, e}; // Check if we have enough digits if (kBase < letters.Length) { throw new Exception("kBase < letters.Length"); } // Constraints solver.Add (letters.AllDifferent ()); // CP + IS + FUN = TRUE solver.Add (p + s + n + kBase * (c + i + u) + kBase * kBase * f == e + kBase * u + kBase * kBase * r + kBase * kBase * kBase * t); // Decision Builder: hot to scour the search tree DecisionBuilder db = solver.MakePhase (letters, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch (db); if (solver.NextSolution ()) { Console.WriteLine ("Solution found:"); Console.Write ("C=" + c.Value () + " P=" + p.Value ()); Console.Write (" I=" + i.Value () + " S=" + s.Value ()); Console.Write (" F=" + f.Value () + " U=" + u.Value ()); Console.Write (" N=" + n.Value () + " T=" + t.Value ()); Console.Write (" R=" + r.Value () + " E=" + e.Value ()); Console.WriteLine (); // Is CP + IS + FUN = TRUE? if (p.Value () + s.Value () + n.Value() + kBase * (c.Value () + i.Value () + u.Value()) + kBase * kBase * f.Value () != e.Value () + kBase * u.Value () + kBase * kBase * r.Value () + kBase * kBase * kBase * t.Value ()) { throw new Exception("CP + IS + FUN != TRUE"); } } else { Console.WriteLine ("Cannot solve problem."); } // if (solver.NextSolution()) solver.EndSearch (); }
// We don't need helper functions here // Csharp syntax is easier than C++ syntax! private static void CPisFun(int kBase, int time_limit_param, bool print) { // Use some profiling and change the default parameters of the solver SolverParameters solver_params = new SolverParameters(); // Change the profile level solver_params.profile_level = SolverParameters.NORMAL_PROFILING; // Constraint Programming engine Solver solver = new Solver("CP is fun!", solver_params); // Decision variables IntVar c = solver.MakeIntVar(1, kBase - 1, "C"); IntVar p = solver.MakeIntVar(0, kBase - 1, "P"); IntVar i = solver.MakeIntVar(1, kBase - 1, "I"); IntVar s = solver.MakeIntVar(0, kBase - 1, "S"); IntVar f = solver.MakeIntVar(1, kBase - 1, "F"); IntVar u = solver.MakeIntVar(0, kBase - 1, "U"); IntVar n = solver.MakeIntVar(0, kBase - 1, "N"); IntVar t = solver.MakeIntVar(1, kBase - 1, "T"); IntVar r = solver.MakeIntVar(0, kBase - 1, "R"); IntVar e = solver.MakeIntVar(0, kBase - 1, "E"); // We need to group variables in a vector to be able to use // the global constraint AllDifferent IntVar[] letters = new IntVar[] { c, p, i, s, f, u, n, t, r, e }; // Check if we have enough digits if (kBase < letters.Length) { throw new Exception("kBase < letters.Length"); } // Constraints solver.Add(letters.AllDifferent()); // CP + IS + FUN = TRUE solver.Add(p + s + n + kBase * (c + i + u) + kBase * kBase * f == e + kBase * u + kBase * kBase * r + kBase * kBase * kBase * t); SolutionCollector all_solutions = solver.MakeAllSolutionCollector(); // Add the interesting variables to the SolutionCollector all_solutions.Add(letters); // Decision Builder: hot to scour the search tree DecisionBuilder db = solver.MakePhase(letters, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); // Add some time limit SearchLimit time_limit = solver.MakeTimeLimit(time_limit_param); solver.Solve(db, all_solutions, time_limit); // Retrieve the solutions int numberSolutions = all_solutions.SolutionCount(); Console.WriteLine("Number of solutions: " + numberSolutions); if (print) { for (int index = 0; index < numberSolutions; ++index) { Console.Write("C=" + all_solutions.Value(index, c)); Console.Write(" P=" + all_solutions.Value(index, p)); Console.Write(" I=" + all_solutions.Value(index, i)); Console.Write(" S=" + all_solutions.Value(index, s)); Console.Write(" F=" + all_solutions.Value(index, f)); Console.Write(" U=" + all_solutions.Value(index, u)); Console.Write(" N=" + all_solutions.Value(index, n)); Console.Write(" T=" + all_solutions.Value(index, t)); Console.Write(" R=" + all_solutions.Value(index, r)); Console.Write(" E=" + all_solutions.Value(index, e)); Console.WriteLine(); } } // Save profile in file solver.ExportProfilingOverview("profile.txt"); }
/** * * This is a port of Charles Prud'homme's Java model * Partition.java * """ * Partition n numbers into two groups, so that * - the sum of the first group equals the sum of the second, * - and the sum of the squares of the first group equals the sum of * the squares of the second * """ * */ private static void Solve(int m) { Solver solver = new Solver("Partition"); // // Decision variables // IntVar[] x = solver.MakeIntVarArray(m, 1, 2 * m, "x"); IntVar[] y = solver.MakeIntVarArray(m, 1, 2 * m, "y"); // // Constraints // // break symmetries for (int i = 0; i < m - 1; i++) { solver.Add(x[i] < x[i + 1]); solver.Add(y[i] < y[i + 1]); } solver.Add(x[0] < y[0]); IntVar[] xy = new IntVar[2 * m]; for (int i = m - 1; i >= 0; i--) { xy[i] = x[i]; xy[m + i] = y[i]; } solver.Add(xy.AllDifferent()); int[] coeffs = new int[2 * m]; for (int i = m - 1; i >= 0; i--) { coeffs[i] = 1; coeffs[m + i] = -1; } solver.Add(xy.ScalProd(coeffs) == 0); IntVar[] sxy, sx, sy; sxy = new IntVar[2 * m]; sx = new IntVar[m]; sy = new IntVar[m]; for (int i = m - 1; i >= 0; i--) { sx[i] = x[i].Square().Var(); sxy[i] = sx[i]; sy[i] = y[i].Square().Var(); sxy[m + i] = sy[i]; } solver.Add(sxy.ScalProd(coeffs) == 0); solver.Add(x.Sum() == 2 * m * (2 * m + 1) / 4); solver.Add(y.Sum() == 2 * m * (2 * m + 1) / 4); solver.Add(sx.Sum() == 2 * m * (2 * m + 1) * (4 * m + 1) / 12); solver.Add(sy.Sum() == 2 * m * (2 * m + 1) * (4 * m + 1) / 12); // // Search // DecisionBuilder db = solver.MakeDefaultPhase(xy); SearchMonitor log = solver.MakeSearchLog(10000); solver.NewSearch(db, log); while (solver.NextSolution()) { for (int i = 0; i < m; i++) { Console.Write("[" + xy[i].Value() + "] "); } Console.WriteLine(); for (int i = 0; i < m; i++) { Console.Write("[" + xy[m + i].Value() + "] "); } Console.WriteLine("\n"); } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); Console.WriteLine("WallTime: {0}ms", solver.WallTime()); Console.WriteLine("Failures: {0}", solver.Failures()); Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); }
/** * * Cryptarithmetic puzzle. * * Prolog benchmark problem GNU Prolog (crypta.pl) * """ * Name : crypta.pl * Title : crypt-arithmetic * Original Source: P. Van Hentenryck's book * Adapted by : Daniel Diaz - INRIA France * Date : September 1992 * * Solve the operation: * * B A I J J A J I I A H F C F E B B J E A * + D H F G A B C D I D B I F F A G F E J E * ----------------------------------------- * = G J E G A C D D H F A F J B F I H E E F * """ * * * Also see http://hakank.org/or-tools/crypta.py * */ private static void Solve() { Solver solver = new Solver("Crypta"); // // Decision variables // IntVar A = solver.MakeIntVar(0, 9, "A"); IntVar B = solver.MakeIntVar(0, 9, "B"); IntVar C = solver.MakeIntVar(0, 9, "C"); IntVar D = solver.MakeIntVar(0, 9, "D"); IntVar E = solver.MakeIntVar(0, 9, "E"); IntVar F = solver.MakeIntVar(0, 9, "F"); IntVar G = solver.MakeIntVar(0, 9, "G"); IntVar H = solver.MakeIntVar(0, 9, "H"); IntVar I = solver.MakeIntVar(0, 9, "I"); IntVar J = solver.MakeIntVar(0, 9, "J"); IntVar[] LD = new IntVar[] { A, B, C, D, E, F, G, H, I, J }; IntVar Sr1 = solver.MakeIntVar(0, 1, "Sr1"); IntVar Sr2 = solver.MakeIntVar(0, 1, "Sr2"); // // Constraints // solver.Add(LD.AllDifferent()); solver.Add(B >= 1); solver.Add(D >= 1); solver.Add(G >= 1); solver.Add((A + 10 * E + 100 * J + 1000 * B + 10000 * B + 100000 * E + 1000000 * F + E + 10 * J + 100 * E + 1000 * F + 10000 * G + 100000 * A + 1000000 * F) == (F + 10 * E + 100 * E + 1000 * H + 10000 * I + 100000 * F + 1000000 * B + 10000000 * Sr1)); solver.Add((C + 10 * F + 100 * H + 1000 * A + 10000 * I + 100000 * I + 1000000 * J + F + 10 * I + 100 * B + 1000 * D + 10000 * I + 100000 * D + 1000000 * C + Sr1) == (J + 10 * F + 100 * A + 1000 * F + 10000 * H + 100000 * D + 1000000 * D + 10000000 * Sr2)); solver.Add((A + 10 * J + 100 * J + 1000 * I + 10000 * A + 100000 * B + B + 10 * A + 100 * G + 1000 * F + 10000 * H + 100000 * D + Sr2) == (C + 10 * A + 100 * G + 1000 * E + 10000 * J + 100000 * G)); // // Search // DecisionBuilder db = solver.MakePhase(LD, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { for (int i = 0; i < 10; i++) { Console.Write(LD[i].ToString() + " "); } Console.WriteLine(); } Console.WriteLine("\nWallTime: " + solver.WallTime() + "ms "); Console.WriteLine("Failures: " + solver.Failures()); Console.WriteLine("Branches: " + solver.Branches()); solver.EndSearch(); }
public static void Main(String[] args) { // Instantiate the solver. // [START solver] Solver solver = new Solver("N-Queens"); // [END solver] // [START variables] const int BoardSize = 8; IntVar[] queens = new IntVar[BoardSize]; for (int i = 0; i < BoardSize; ++i) { queens[i] = solver.MakeIntVar(0, BoardSize - 1, $"x{i}"); } // [END variables] // Define constraints. // [START constraints] // All rows must be different. solver.Add(queens.AllDifferent()); // All columns must be different because the indices of queens are all different. // No two queens can be on the same diagonal. IntVar[] diag1 = new IntVar[BoardSize]; IntVar[] diag2 = new IntVar[BoardSize]; for (int i = 0; i < BoardSize; ++i) { diag1[i] = solver.MakeSum(queens[i], i).Var(); diag2[i] = solver.MakeSum(queens[i], -i).Var(); } solver.Add(diag1.AllDifferent()); solver.Add(diag2.AllDifferent()); // [END constraints] // [START db] // Create the decision builder to search for solutions. DecisionBuilder db = solver.MakePhase(queens, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); // [END db] // [START solve] // Iterates through the solutions, displaying each. int SolutionCount = 0; solver.NewSearch(db); while (solver.NextSolution()) { Console.WriteLine("Solution " + SolutionCount); for (int i = 0; i < BoardSize; ++i) { for (int j = 0; j < BoardSize; ++j) { if (queens[j].Value() == i) { Console.Write("Q"); } else { Console.Write("_"); } if (j != BoardSize - 1) { Console.Write(" "); } } Console.WriteLine(""); } SolutionCount++; } solver.EndSearch(); // [END solve] // Statistics. // [START statistics] Console.WriteLine("Statistics"); Console.WriteLine($" failures: {solver.Failures()}"); Console.WriteLine($" branches: {solver.Branches()}"); Console.WriteLine($" wall time: {solver.WallTime()} ms"); Console.WriteLine($" Solutions found: {SolutionCount}"); // [END statistics] }
/** * * Solves a Strimko problem. * See http://www.hakank.org/google_or_tools/strimko2.py * */ private static void Solve() { Solver solver = new Solver("Strimko2"); // // data // int[,] streams = { { 1, 1, 2, 2, 2, 2, 2 }, { 1, 1, 2, 3, 3, 3, 2 }, { 1, 4, 1, 3, 3, 5, 5 }, { 4, 4, 3, 1, 3, 5, 5 }, { 4, 6, 6, 6, 7, 7, 5 }, { 6, 4, 6, 4, 5, 5, 7 }, { 6, 6, 4, 7, 7, 7, 7 } }; // Note: This is 1-based int[,] placed = { { 2, 1, 1 }, { 2, 3, 7 }, { 2, 5, 6 }, { 2, 7, 4 }, { 3, 2, 7 }, { 3, 6, 1 }, { 4, 1, 4 }, { 4, 7, 5 }, { 5, 2, 2 }, { 5, 6, 6 } }; int n = streams.GetLength(0); int num_placed = placed.GetLength(0); // // Decision variables // IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, n, "x"); IntVar[] x_flat = x.Flatten(); // // Constraints // // all rows and columns must be unique, i.e. a Latin Square for (int i = 0; i < n; i++) { IntVar[] row = new IntVar[n]; IntVar[] col = new IntVar[n]; for (int j = 0; j < n; j++) { row[j] = x[i, j]; col[j] = x[j, i]; } solver.Add(row.AllDifferent()); solver.Add(col.AllDifferent()); } // streams for (int s = 1; s <= n; s++) { IntVar[] tmp = (from i in Enumerable.Range(0, n) from j in Enumerable.Range(0, n) where streams[i, j] == s select x[i, j]) .ToArray(); solver.Add(tmp.AllDifferent()); } // placed for (int i = 0; i < num_placed; i++) { // note: also adjust to 0-based solver.Add(x[placed[i, 0] - 1, placed[i, 1] - 1] == placed[i, 2]); } // // Search // DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { Console.Write(x[i, j].Value() + " "); } Console.WriteLine(); } Console.WriteLine(); } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); Console.WriteLine("WallTime: {0}ms", solver.WallTime()); Console.WriteLine("Failures: {0}", solver.Failures()); Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); }
public static void Main(String[] args) { // Instantiate the solver. // [START solver] Solver solver = new Solver("CP is fun!"); // [END solver] // [START variables] const int kBase = 10; // Decision variables. IntVar c = solver.MakeIntVar(1, kBase - 1, "C"); IntVar p = solver.MakeIntVar(0, kBase - 1, "P"); IntVar i = solver.MakeIntVar(1, kBase - 1, "I"); IntVar s = solver.MakeIntVar(0, kBase - 1, "S"); IntVar f = solver.MakeIntVar(1, kBase - 1, "F"); IntVar u = solver.MakeIntVar(0, kBase - 1, "U"); IntVar n = solver.MakeIntVar(0, kBase - 1, "N"); IntVar t = solver.MakeIntVar(1, kBase - 1, "T"); IntVar r = solver.MakeIntVar(0, kBase - 1, "R"); IntVar e = solver.MakeIntVar(0, kBase - 1, "E"); // Group variables in a vector so that we can use AllDifferent. IntVar[] letters = new IntVar[] { c, p, i, s, f, u, n, t, r, e }; // Verify that we have enough digits. if (kBase < letters.Length) { throw new Exception("kBase < letters.Length"); } // [END variables] // Define constraints. // [START constraints] solver.Add(letters.AllDifferent()); // CP + IS + FUN = TRUE solver.Add(p + s + n + kBase * (c + i + u) + kBase * kBase * f == e + kBase * u + kBase * kBase * r + kBase * kBase * kBase * t); // [END constraints] // [START solve] int SolutionCount = 0; // Create the decision builder to search for solutions. DecisionBuilder db = solver.MakePhase(letters, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { Console.Write("C=" + c.Value() + " P=" + p.Value()); Console.Write(" I=" + i.Value() + " S=" + s.Value()); Console.Write(" F=" + f.Value() + " U=" + u.Value()); Console.Write(" N=" + n.Value() + " T=" + t.Value()); Console.Write(" R=" + r.Value() + " E=" + e.Value()); Console.WriteLine(); // Is CP + IS + FUN = TRUE? if (p.Value() + s.Value() + n.Value() + kBase * (c.Value() + i.Value() + u.Value()) + kBase * kBase * f.Value() != e.Value() + kBase * u.Value() + kBase * kBase * r.Value() + kBase * kBase * kBase * t.Value()) { throw new Exception("CP + IS + FUN != TRUE"); } SolutionCount++; } solver.EndSearch(); Console.WriteLine($"Number of solutions found: {SolutionCount}"); // [END solve] }
/** * * Solves the Quasigroup Completion problem. * See http://www.hakank.org/or-tools/quasigroup_completion.py * */ private static void Solve() { Solver solver = new Solver("QuasigroupCompletion"); // // data // Console.WriteLine("Problem:"); for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { Console.Write(problem[i,j] + " "); } Console.WriteLine(); } Console.WriteLine(); // // Decision variables // IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, n, "x"); IntVar[] x_flat = x.Flatten(); // // Constraints // for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { if (problem[i,j] > X) { solver.Add(x[i,j] == problem[i,j]); } } } // // rows and columns must be different // // rows for(int i = 0; i < n; i++) { IntVar[] row = new IntVar[n]; for(int j = 0; j < n; j++) { row[j] = x[i,j]; } solver.Add(row.AllDifferent()); } // columns for(int j = 0; j < n; j++) { IntVar[] col = new IntVar[n]; for(int i = 0; i < n; i++) { col[i] = x[i,j]; } solver.Add(col.AllDifferent()); } // // Search // DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_SIMPLE, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); int sol = 0; while (solver.NextSolution()) { sol++; Console.WriteLine("Solution #{0} ", sol + " "); for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++){ Console.Write("{0} ", x[i,j].Value()); } Console.WriteLine(); } Console.WriteLine(); } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); Console.WriteLine("WallTime: {0}ms", solver.WallTime()); Console.WriteLine("Failures: {0}", solver.Failures()); Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); }
/** * * Solve the SEND+MOST=MONEY problem * where the object is to maximize MONEY * See http://www.hakank.org/google_or_tools/send_most_money.py * */ private static long Solve(long MONEY) { Solver solver = new Solver("SendMostMoney"); // // Decision variables // IntVar S = solver.MakeIntVar(0, 9, "S"); IntVar E = solver.MakeIntVar(0, 9, "E"); IntVar N = solver.MakeIntVar(0, 9, "N"); IntVar D = solver.MakeIntVar(0, 9, "D"); IntVar M = solver.MakeIntVar(0, 9, "M"); IntVar O = solver.MakeIntVar(0, 9, "O"); IntVar T = solver.MakeIntVar(0, 9, "T"); IntVar Y = solver.MakeIntVar(0, 9, "Y"); // for AllDifferent() IntVar[] x = new IntVar[] {S,E,N,D,M,O,T,Y}; IntVar[] eq = {S,E,N,D, M,O,S,T, M,O,N,E,Y}; int[] coeffs = { 1000, 100, 10, 1, // S E N D + 1000, 100, 10, 1, // M O S T -10000,-1000, -100,-10,-1 // == M O N E Y }; solver.Add(eq.ScalProd(coeffs) == 0); // IntVar money = solver.MakeScalProd(new IntVar[] {M, O, N, E, Y}, // new int[] {10000, 1000, 100, 10, 1}).Var(); IntVar money = (new IntVar[] {M, O, N, E, Y}). ScalProd(new int[] {10000, 1000, 100, 10, 1}).Var(); // // Constraints // solver.Add(x.AllDifferent()); solver.Add(S > 0); solver.Add(M > 0); if (MONEY > 0) { solver.Add(money == MONEY); } // // Search // DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); if (MONEY == 0) { OptimizeVar obj = money.Maximize(1); solver.NewSearch(db, obj); } else { solver.NewSearch(db); } long money_ret = 0; while (solver.NextSolution()) { money_ret = money.Value(); Console.WriteLine("money: {0}", money.Value() ); for(int i = 0; i < x.Length; i++) { Console.Write(x[i].Value() + " "); } Console.WriteLine(); } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); Console.WriteLine("WallTime: {0}ms", solver.WallTime()); Console.WriteLine("Failures: {0}", solver.Failures()); Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); return money_ret; }
/** * * Solves the N-Queens problem. * * Syntax: nqueens.exe n num print * where * n : size of board * num : number of solutions to calculate * print: print the results (if > 0) * */ private static void Solve(int n=8, int num=0, int print=1) { Solver solver = new Solver("N-Queens"); // // Decision variables // IntVar[] q = solver.MakeIntVarArray(n, 0, n-1, "q"); // // Constraints // solver.Add(q.AllDifferent()); IntVar[] q1 = new IntVar[n]; IntVar[] q2 = new IntVar[n]; for(int i = 0; i < n; i++) { q1[i] = (q[i] + i).Var(); q2[i] = (q[i] - i).Var(); } solver.Add(q1.AllDifferent()); solver.Add(q2.AllDifferent()); // Alternative version: it works as well but are not that clear /* solver.Add((from i in Enumerable.Range(0, n) select (q[i] + i).Var()).ToArray().AllDifferent()); solver.Add((from i in Enumerable.Range(0, n) select (q[i] - i).Var()).ToArray().AllDifferent()); */ // // Search // DecisionBuilder db = solver.MakePhase(q, Solver.CHOOSE_MIN_SIZE_LOWEST_MAX, Solver.ASSIGN_CENTER_VALUE); solver.NewSearch(db); int c = 0; while (solver.NextSolution()) { if (print > 0) { for(int i = 0; i < n; i++) { Console.Write("{0} ", q[i].Value()); } Console.WriteLine(); } c++; if (num > 0 && c >= num) { break; } } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); Console.WriteLine("WallTime: {0}ms", solver.WallTime()); Console.WriteLine("Failures: {0}", solver.Failures()); Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); }
/** * * Golomb Ruler problem. * * This C# implementation is based on Charles Prud'homme's * or-tools/Java model: * http://code.google.com/p/or-tools/source/browse/trunk/com/google/ortools/constraintsolver/samples/GolombRuler.java * */ private static void Solve(int m = 8) { Solver solver = new Solver("GolombRuler"); // // Decision variables // IntVar[] ticks = solver.MakeIntVarArray(m, 0, ((m < 31) ? (1 << (m + 1)) - 1 : 9999), "ticks"); IntVar[] diff = new IntVar[(m * m - m) / 2]; // // Constraints // solver.Add(ticks[0] == 0); for(int i = 0; i < ticks.Length - 1; i++) { solver.Add(ticks[i] < ticks[i+1]); } for (int k = 0, i = 0; i < m - 1; i++) { for (int j = i + 1; j < m; j++, k++) { diff[k] = (ticks[j]-ticks[i]).Var(); solver.Add(diff[k] >= (j - i) * (j - i + 1) / 2); } } solver.Add(diff.AllDifferent()); // break symetries if (m > 2) { solver.Add(diff[0] < diff[diff.Length - 1]); } // // Optimization // OptimizeVar opt = ticks[m - 1].Minimize(1); // // Search // DecisionBuilder db = solver.MakePhase(ticks, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_MIN_VALUE); // We just want the debug info for larger instances. if (m >= 11) { SearchMonitor log = solver.MakeSearchLog(10000, opt); solver.NewSearch(db, opt, log); } else { solver.NewSearch(db, opt); } while (solver.NextSolution()) { Console.Write("opt: {0} [ ", ticks[m-1].Value()); for(int i = 0; i < m; i++) { Console.Write("{0} ", ticks[i].Value()); } Console.WriteLine("]"); } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); Console.WriteLine("WallTime: {0}ms", solver.WallTime()); Console.WriteLine("Failures: {0}", solver.Failures()); Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); }
/** * * Solves the Quasigroup Completion problem. * See http://www.hakank.org/or-tools/quasigroup_completion.py * */ private static void Solve() { Solver solver = new Solver("QuasigroupCompletion"); // // data // Console.WriteLine("Problem:"); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { Console.Write(problem[i, j] + " "); } Console.WriteLine(); } Console.WriteLine(); // // Decision variables // IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, n, "x"); IntVar[] x_flat = x.Flatten(); // // Constraints // for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (problem[i, j] > X) { solver.Add(x[i, j] == problem[i, j]); } } } // // rows and columns must be different // // rows for (int i = 0; i < n; i++) { IntVar[] row = new IntVar[n]; for (int j = 0; j < n; j++) { row[j] = x[i, j]; } solver.Add(row.AllDifferent()); } // columns for (int j = 0; j < n; j++) { IntVar[] col = new IntVar[n]; for (int i = 0; i < n; i++) { col[i] = x[i, j]; } solver.Add(col.AllDifferent()); } // // Search // DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_SIMPLE, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); int sol = 0; while (solver.NextSolution()) { sol++; Console.WriteLine("Solution #{0} ", sol + " "); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { Console.Write("{0} ", x[i, j].Value()); } Console.WriteLine(); } Console.WriteLine(); } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); Console.WriteLine("WallTime: {0}ms", solver.WallTime()); Console.WriteLine("Failures: {0}", solver.Failures()); Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); }
/** * * Solves the N-Queens problem. * * Syntax: nqueens.exe n num print * where * n : size of board * num : number of solutions to calculate * print: print the results (if > 0) * */ private static void Solve(int n = 8, int num = 0, int print = 1) { Solver solver = new Solver("N-Queens"); // // Decision variables // IntVar[] q = solver.MakeIntVarArray(n, 0, n - 1, "q"); // // Constraints // solver.Add(q.AllDifferent()); IntVar[] q1 = new IntVar[n]; IntVar[] q2 = new IntVar[n]; for (int i = 0; i < n; i++) { q1[i] = (q[i] + i).Var(); q2[i] = (q[i] - i).Var(); } solver.Add(q1.AllDifferent()); solver.Add(q2.AllDifferent()); // Alternative version: it works as well but are not that clear /* * solver.Add((from i in Enumerable.Range(0, n) * select (q[i] + i).Var()).ToArray().AllDifferent()); * * solver.Add((from i in Enumerable.Range(0, n) * select (q[i] - i).Var()).ToArray().AllDifferent()); */ // // Search // DecisionBuilder db = solver.MakePhase(q, Solver.CHOOSE_MIN_SIZE_LOWEST_MAX, Solver.ASSIGN_CENTER_VALUE); solver.NewSearch(db); int c = 0; while (solver.NextSolution()) { if (print > 0) { for (int i = 0; i < n; i++) { Console.Write("{0} ", q[i].Value()); } Console.WriteLine(); } c++; if (num > 0 && c >= num) { break; } } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); Console.WriteLine("WallTime: {0}ms", solver.WallTime()); Console.WriteLine("Failures: {0}", solver.Failures()); Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); }
// We don't need helper functions here // Csharp syntax is easier than C++ syntax! private static void CPisFun(int kBase) { // Constraint Programming engine Solver solver = new Solver("CP is fun!"); // Decision variables IntVar c = solver.MakeIntVar(1, kBase - 1, "C"); IntVar p = solver.MakeIntVar(0, kBase - 1, "P"); IntVar i = solver.MakeIntVar(1, kBase - 1, "I"); IntVar s = solver.MakeIntVar(0, kBase - 1, "S"); IntVar f = solver.MakeIntVar(1, kBase - 1, "F"); IntVar u = solver.MakeIntVar(0, kBase - 1, "U"); IntVar n = solver.MakeIntVar(0, kBase - 1, "N"); IntVar t = solver.MakeIntVar(1, kBase - 1, "T"); IntVar r = solver.MakeIntVar(0, kBase - 1, "R"); IntVar e = solver.MakeIntVar(0, kBase - 1, "E"); // We need to group variables in a vector to be able to use // the global constraint AllDifferent IntVar[] letters = new IntVar[] { c, p, i, s, f, u, n, t, r, e }; // Check if we have enough digits if (kBase < letters.Length) { throw new Exception("kBase < letters.Length"); } // Constraints solver.Add(letters.AllDifferent()); // CP + IS + FUN = TRUE solver.Add(p + s + n + kBase * (c + i + u) + kBase * kBase * f == e + kBase * u + kBase * kBase * r + kBase * kBase * kBase * t); SolutionCollector all_solutions = solver.MakeAllSolutionCollector(); // Add the interesting variables to the SolutionCollector all_solutions.Add(c); all_solutions.Add(p); // Create the variable kBase * c + p IntVar v1 = solver.MakeSum(solver.MakeProd(c, kBase), p).Var(); // Add it to the SolutionCollector all_solutions.Add(v1); // Decision Builder: hot to scour the search tree DecisionBuilder db = solver.MakePhase(letters, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.Solve(db, all_solutions); // Retrieve the solutions int numberSolutions = all_solutions.SolutionCount(); Console.WriteLine("Number of solutions: " + numberSolutions); for (int index = 0; index < numberSolutions; ++index) { Assignment solution = all_solutions.Solution(index); Console.WriteLine("Solution found:"); Console.WriteLine("v1=" + solution.Value(v1)); } }
/** * * Solves a Strimko problem. * See http://www.hakank.org/google_or_tools/strimko2.py * */ private static void Solve() { Solver solver = new Solver("Strimko2"); // // data // int[,] streams = {{1,1,2,2,2,2,2}, {1,1,2,3,3,3,2}, {1,4,1,3,3,5,5}, {4,4,3,1,3,5,5}, {4,6,6,6,7,7,5}, {6,4,6,4,5,5,7}, {6,6,4,7,7,7,7}}; // Note: This is 1-based int[,] placed = {{2,1,1}, {2,3,7}, {2,5,6}, {2,7,4}, {3,2,7}, {3,6,1}, {4,1,4}, {4,7,5}, {5,2,2}, {5,6,6}}; int n = streams.GetLength(0); int num_placed = placed.GetLength(0); // // Decision variables // IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, n, "x"); IntVar[] x_flat = x.Flatten(); // // Constraints // // all rows and columns must be unique, i.e. a Latin Square for(int i = 0; i < n; i++) { IntVar[] row = new IntVar[n]; IntVar[] col = new IntVar[n]; for(int j = 0; j < n; j++) { row[j] = x[i,j]; col[j] = x[j,i]; } solver.Add(row.AllDifferent()); solver.Add(col.AllDifferent()); } // streams for(int s = 1; s <= n; s++) { IntVar[] tmp = (from i in Enumerable.Range(0, n) from j in Enumerable.Range(0, n) where streams[i,j] == s select x[i,j]).ToArray(); solver.Add(tmp.AllDifferent()); } // placed for(int i = 0; i < num_placed; i++) { // note: also adjust to 0-based solver.Add(x[placed[i,0] - 1,placed[i,1] - 1] == placed[i,2]); } // // Search // DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { Console.Write(x[i,j].Value() + " "); } Console.WriteLine(); } Console.WriteLine(); } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); Console.WriteLine("WallTime: {0}ms", solver.WallTime()); Console.WriteLine("Failures: {0}", solver.Failures()); Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); }
// We don't need helper functions here // Csharp syntax is easier than C++ syntax! private static void CPisFun (int kBase, int time_limit_param, bool print) { // Use some profiling and change the default parameters of the solver SolverParameters solver_params = new SolverParameters(); // Change the profile level solver_params.profile_level = SolverParameters.NORMAL_PROFILING; // Constraint Programming engine Solver solver = new Solver ("CP is fun!", solver_params); // Decision variables IntVar c = solver.MakeIntVar (1, kBase - 1, "C"); IntVar p = solver.MakeIntVar (0, kBase - 1, "P"); IntVar i = solver.MakeIntVar (1, kBase - 1, "I"); IntVar s = solver.MakeIntVar (0, kBase - 1, "S"); IntVar f = solver.MakeIntVar (1, kBase - 1, "F"); IntVar u = solver.MakeIntVar (0, kBase - 1, "U"); IntVar n = solver.MakeIntVar (0, kBase - 1, "N"); IntVar t = solver.MakeIntVar (1, kBase - 1, "T"); IntVar r = solver.MakeIntVar (0, kBase - 1, "R"); IntVar e = solver.MakeIntVar (0, kBase - 1, "E"); // We need to group variables in a vector to be able to use // the global constraint AllDifferent IntVar[] letters = new IntVar[] { c, p, i, s, f, u, n, t, r, e}; // Check if we have enough digits if (kBase < letters.Length) { throw new Exception("kBase < letters.Length"); } // Constraints solver.Add (letters.AllDifferent ()); // CP + IS + FUN = TRUE solver.Add (p + s + n + kBase * (c + i + u) + kBase * kBase * f == e + kBase * u + kBase * kBase * r + kBase * kBase * kBase * t); SolutionCollector all_solutions = solver.MakeAllSolutionCollector(); // Add the interesting variables to the SolutionCollector all_solutions.Add(letters); // Decision Builder: hot to scour the search tree DecisionBuilder db = solver.MakePhase (letters, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); // Add some time limit SearchLimit time_limit = solver.MakeTimeLimit(time_limit_param); solver.Solve(db, all_solutions, time_limit); // Retrieve the solutions int numberSolutions = all_solutions.SolutionCount(); Console.WriteLine ("Number of solutions: " + numberSolutions); if (print) { for (int index = 0; index < numberSolutions; ++index) { Console.Write ("C=" + all_solutions.Value(index, c)); Console.Write (" P=" + all_solutions.Value(index, p)); Console.Write (" I=" + all_solutions.Value(index, i)); Console.Write (" S=" + all_solutions.Value(index, s)); Console.Write (" F=" + all_solutions.Value(index, f)); Console.Write (" U=" + all_solutions.Value(index, u)); Console.Write (" N=" + all_solutions.Value(index, n)); Console.Write (" T=" + all_solutions.Value(index, t)); Console.Write (" R=" + all_solutions.Value(index, r)); Console.Write (" E=" + all_solutions.Value(index, e)); Console.WriteLine (); } } // Save profile in file solver.ExportProfilingOverview("profile.txt"); }
/** * * Golomb Ruler problem. * * This C# implementation is based on Charles Prud'homme's * or-tools/Java model: * http://code.google.com/p/or-tools/source/browse/trunk/com/google/ortools/constraintsolver/samples/GolombRuler.java * */ private static void Solve(int m = 8) { Solver solver = new Solver("GolombRuler"); // // Decision variables // IntVar[] ticks = solver.MakeIntVarArray(m, 0, ((m < 31) ? (1 << (m + 1)) - 1 : 9999), "ticks"); IntVar[] diff = new IntVar[(m * m - m) / 2]; // // Constraints // solver.Add(ticks[0] == 0); for (int i = 0; i < ticks.Length - 1; i++) { solver.Add(ticks[i] < ticks[i + 1]); } for (int k = 0, i = 0; i < m - 1; i++) { for (int j = i + 1; j < m; j++, k++) { diff[k] = (ticks[j] - ticks[i]).Var(); solver.Add(diff[k] >= (j - i) * (j - i + 1) / 2); } } solver.Add(diff.AllDifferent()); // break symetries if (m > 2) { solver.Add(diff[0] < diff[diff.Length - 1]); } // // Optimization // OptimizeVar opt = ticks[m - 1].Minimize(1); // // Search // DecisionBuilder db = solver.MakePhase(ticks, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_MIN_VALUE); // We just want the debug info for larger instances. if (m >= 11) { SearchMonitor log = solver.MakeSearchLog(10000, opt); solver.NewSearch(db, opt, log); } else { solver.NewSearch(db, opt); } while (solver.NextSolution()) { Console.Write("opt: {0} [ ", ticks[m - 1].Value()); for (int i = 0; i < m; i++) { Console.Write("{0} ", ticks[i].Value()); } Console.WriteLine("]"); } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); Console.WriteLine("WallTime: {0}ms", solver.WallTime()); Console.WriteLine("Failures: {0}", solver.Failures()); Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); }
/** * * Cryptarithmetic puzzle. * * Prolog benchmark problem GNU Prolog (crypta.pl) * """ * Name : crypta.pl * Title : crypt-arithmetic * Original Source: P. Van Hentenryck's book * Adapted by : Daniel Diaz - INRIA France * Date : September 1992 * * Solve the operation: * * B A I J J A J I I A H F C F E B B J E A * + D H F G A B C D I D B I F F A G F E J E * ----------------------------------------- * = G J E G A C D D H F A F J B F I H E E F * """ * * * Also see http://hakank.org/or-tools/crypta.py * */ private static void Solve() { Solver solver = new Solver("Crypta"); // // Decision variables // IntVar A = solver.MakeIntVar(0, 9, "A"); IntVar B = solver.MakeIntVar(0, 9, "B"); IntVar C = solver.MakeIntVar(0, 9, "C"); IntVar D = solver.MakeIntVar(0, 9, "D"); IntVar E = solver.MakeIntVar(0, 9, "E"); IntVar F = solver.MakeIntVar(0, 9, "F"); IntVar G = solver.MakeIntVar(0, 9, "G"); IntVar H = solver.MakeIntVar(0, 9, "H"); IntVar I = solver.MakeIntVar(0, 9, "I"); IntVar J = solver.MakeIntVar(0, 9, "J"); IntVar[] LD = new IntVar[] {A,B,C,D,E,F,G,H,I,J}; IntVar Sr1 = solver.MakeIntVar(0, 1, "Sr1"); IntVar Sr2 = solver.MakeIntVar(0, 1, "Sr2"); // // Constraints // solver.Add(LD.AllDifferent()); solver.Add(B >= 1); solver.Add(D >= 1); solver.Add(G >= 1); solver.Add((A+10*E+100*J+1000*B+10000*B+100000*E+1000000*F+ E+10*J+100*E+1000*F+10000*G+100000*A+1000000*F) == (F+10*E+100*E+1000*H+10000*I+100000*F+1000000*B+10000000*Sr1)); solver.Add((C+10*F+100*H+1000*A+10000*I+100000*I+1000000*J+ F+10*I+100*B+1000*D+10000*I+100000*D+1000000*C+Sr1) == (J+10*F+100*A+1000*F+10000*H+100000*D+1000000*D+10000000*Sr2)); solver.Add((A+10*J+100*J+1000*I+10000*A+100000*B+ B+10*A+100*G+1000*F+10000*H+100000*D+Sr2) == (C+10*A+100*G+1000*E+10000*J+100000*G)); // // Search // DecisionBuilder db = solver.MakePhase(LD, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { for(int i = 0; i < 10; i++) { Console.Write(LD[i].ToString() + " "); } Console.WriteLine(); } Console.WriteLine("\nWallTime: " + solver.WallTime() + "ms "); Console.WriteLine("Failures: " + solver.Failures()); Console.WriteLine("Branches: " + solver.Branches()); solver.EndSearch(); }