Files
ortools-clone/documentation/tutorials/csharp/chap2/cp_is_fun4.cs
nikolaj.van.omme@gmail.com 6679ac364b Doc automatic update
2012-04-20 15:37:05 +00:00

133 lines
4.8 KiB
C#

/*
Copyright 2012 Google
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Cryptoarithmetic puzzle
First attempt to solve equation CP + IS + FUN = TRUE
where each letter represents a unique digit.
This problem has 72 different solutions in base 10.
Use of SolutionCollectors.
Use of Solve().
Change the time limit of the solver.
Use of ExportProfilingOverview().
*/
using System;
using Google.OrTools.ConstraintSolver;
public class cp_is_fun1
{
// 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");
}
public static void Main (String[] args)
{
int kBase = 10;
int kTimeLimit = 10000;
bool kPrintAllSolutions = false;
if (args.Length > 0) {
kBase = Convert.ToInt32(args[0]);
if (args.Length > 1) {
kTimeLimit = Convert.ToInt32(args[1]);
if (args.Length > 2) {
kPrintAllSolutions = Convert.ToBoolean(args[2]);
}
}
}
CPisFun(kBase, kTimeLimit, kPrintAllSolutions);
}
}