Variables and domains
A variable
- is a symbolic representation of an unknown quantity/decision,
- comes with potential values that the solver can assign to it, a.k.a. its domain,
- to be determined/assigned during the problem-solving process.
In a scheduling problem
- Variables : the start time of various tasks
- Domains : the set of possible start time slots
In a packing problem
- Variables : the assignment of items to bins
- Domains : the set of possible bins
In a routing problem
- Variables : the nodes visited on a tour
- Domains : the potential successors of each node
Different types of variables are available:
IntVar
has its values in $\mathbb{Z}^1$IntView
s relies on anIntVar
- like
IntAffineView
- like
BoolVar
(andBoolView
) has its values in {$0,1$}- sub-type of
IntVar
- sub-type of
Task
to manage with task/interval: $s+d = e$SetVar
andSetView
(Un)DirectedGraphVar
andGraphView
- and also
RealVar
Ways to declare integer variables
Model m = new Model();
IntVar x = m.intVar("x", 0, 4);
IntVar y = m.intVar("y", new int[]{1,3,5});
IntVar[] vs = m.intVarArray("v", 4, 1, 3);
IntVar[][] ws = m.intVarMatrix("w", 2, 2, 1, 2);
Ways to declare Boolean variables
Model m = new Model();
BoolVar b = m.boolVar("b");
BoolVar[] bs = m.boolVarArray("bs", 10);
BoolVar[][] bss = m.boolVarMatrix("bss", 4, 3);
Similar APIs for other types of variables.
Some views declaration
Model m = new Model();
IntVar x = m.intVar("x", 0, 5);
IntVar v = m.intView(2, x, -3); // v = 2.x - 3
BoolVar b = m.isEq(x, 2); // b = (x == 2)
BoolVar n = b.not(); // n = !b
And also abs(x), mu(x, 2), neg(x), isLeq(x, 3),
…
Reading a variable
Model m = new Model();
IntVar x = m.intVar("x", 0, 4);
System.out.printf("Variable : %s = [%d, %d]\n",
x.getName(), x.getLB(), x.getUB());
System.out.printf("%s is %s instantiated\n",
x.getName(), x.isInstantiated() ? "" : "not");
outputs
Variable : x = [0, 4]
x is not instantiated
If instantiated, a variable can return its assignment value with x.getValue()
.
ABCDE x 4 = EDCBA
If ABCDE times 4 equals EDCBA, and each letter is a different digit from 0 to 9,
what is the value of each letter?
A Model
-
Variables:
- $\forall i \in \{a,b,c,d,e\}, l_i \in [\![ 0,9]\!]$
-
Constraints :
- $\forall i\neq j \in \{a,b,c,d,e\}, l_i \neq l_j$
- $39999l_a + 3990l_b + 300l_c - 960l_d - 9996l_e = 0$
Choco-solver code
// Create a model
Model model = new Model("ABCDE x 4 = EDCBA");
// Declare the variables with their initial domain
IntVar A = model.intVar("A", 0, 9);
IntVar B = model.intVar("B", 0, 9);
IntVar C = model.intVar("C", 0, 9);
IntVar D = model.intVar("D", 0, 9);
IntVar E = model.intVar("E", 0, 9);
// Constraint 1:
// "each letter is a different digit from 0 to 9"
// the second part of the constraint is defined
// by the domain of each variable
model.allDifferent(A, B, C, D, E).post();
// Constraint 2:
// "org.step1.ABCDE times 4 equals EDCBA"
// 40000 A + 4000 B + 400 C + 40 D + 4 E = 10000 E + 1000 D + 100 C + 10 B + A
// <=> 39999 A + 3990 B + 300 C + -960 D - 9996 E = 0
model.scalar(
new IntVar[]{A, B, C, D, E},
new int[]{39_999, 3_990, 300, -960, -9_996},
"=", 0).post();
// Find a solution and print it
if (model.getSolver().solve()) {
int[] sol = new int[]{A.getValue(), B.getValue(), C.getValue(), D.getValue(), E.getValue()};
System.out.printf(" %d%d%d%d%d\nx 4\n------\n %d%d%d%d%d\n",
sol[0], sol[1], sol[2], sol[3], sol[4],
sol[4], sol[3], sol[2], sol[1], sol[0]);
}else{
System.out.println("No solution found");
}
Output
21978
x 4
------
87912
Can you guess his year of birth?
Someone comes up to you and says:
On my birthday in 2025, my age will be equal to the sum of the digits of my birth year. I am less than 100 years old. What could my birth year be?
Can you model this as a CP problem?
A Model
- Parameters
- $input$: the current year
- Variables
- $\forall i \in \{th,hu,te,on\}, x_i \in [\![0,9]\!]$
- $age \in [\![0,99]\!]$
- Constraints
- $x_{th} + x_{hu} + x_{te} + x_{on} = {age}$
- $1000x_{th} + 100x_{hu} + 10x_{te} + x_{on} + age = input$
Hints
model.sum(IntVar[], String, int)
model.scalar(IntVar[], int[], String, int)
A Choco-solver code
Model model = new Model("Age equals sum of birth year digits");
IntVar th = model.intVar("th", 0, 9);
IntVar hu = model.intVar("hu", 0, 9);
IntVar te = model.intVar("te", 0, 9);
IntVar on = model.intVar("on", 0, 9);
IntVar age = model.intVar("age", 0, 99);
model.sum(new IntVar[]{th, hu, te, on}, "=", age).post();
model.scalar(
new IntVar[]{th, hu, te, on, age},
new int[]{1_000, 100, 10, 1, 1},
"=", 2025).post();
while (model.getSolver().solve()) {
int[] sol = new int[]{th.getValue(), hu.getValue(), te.getValue(), on.getValue()};
System.out.printf("I was born in %d%d%d%d, I am %d years old\n", sol[0], sol[1], sol[2], sol[3], age.getValue());
}
if(model.getSolver().getSolutionCount() == 0) {
System.out.println("No solution found");
}
Output
I was born in 1998, I am 27 years old
I was born in 2016, I am 9 years old