-1

I am new to Constraint programming and to MiniZinc I want to define the constraints for the following problem. Can you help me

3 Arrays F1,F2 and F3 have child elements (F1a,F1b) ; (F2a,F2b,F2c) ; (F3a,F3b,F3c,F3d) respectively.

I need to define constraints with below rules

*Need to Pick 1 element from each Family F1 and F3 with F2b included in all possible solutions

  • F2b and F1a cannot coexist in a solution
  • F2b and F3b cannot coexist in a solution
  • F1a F2b and F3a cannot coexist in a solution

I need to find possible solutions

Thanks

My Actual Problem has 650 Arrays like F1,F2,... and have 75000 constraints like what i stated. Will I run into performance issue if extend the same logic given below by Alex/Dekker ?. what should be rigth approach to solve problems of this magnitude THanks

2 Answers2

2

This can be expressed using the sum function and a user-defined predicate:

array[1..2] of var bool: F1;
array[1..3] of var bool: F2;
array[1..4] of var bool: F3;

%  assuming that exactly one has to be picked
constraint sum(F1) == 1;  %  same as (F1[1]+F1[2]) == 1
constraint sum(F2) == 1;
constraint sum(F3) == 1;

predicate coexist(array[int] of var bool: x ) =
  sum(x) > 1;
  
constraint not coexist([F1[1], F2[2]]);
constraint not coexist([F2[2], F3[2]]);
constraint not coexist([F1[1], F2[2], F3[1]]);
Axel Kemper
  • 10,544
  • 2
  • 31
  • 54
  • Although this should be a working solution to a `coexists` function. The constraints are linear where they don't have to be. This will be fine for some kinds of solvers, but can be terrible on others. It doesn't matter much in such a small model, but might make a big difference if the model grows. – Dekker1 Jul 27 '20 at 23:11
2

The idea that a certain number of elements has to be picked in an array of elements can be represented in many different ways. If we are forced to pick a certain number, then a constraint using the count global is the best way to do so. (However, picking at least one element is better done using the exists function, which represents a logical or operation.)

The coexistance of elements is also represented by the counting of the number of activated elements. If coexistance is not allowed, then only 1 can be activated at a time. In the situation where we are reasoning about only two elements, there is a unique scenario where we can just exclude the usage of both elements at the same time using the /\ operator.

Your model could thus become:

array[1..2] of var bool: F1;
array[1..3] of var bool: F2;
array[1..4] of var bool: F3;
 
constraint count(F1) == 1; % Pick 1 element from F1
constraint count(F2) == 1; % Pick 1 element from F2
constraint count(F3) == 1; % Pick 1 element from F3
  
constraint not (F1[1] /\ F2[2]); % F2b and F1a cannot coexist in a solution
constraint not (F2[2] /\ F3[2]); % F2b and F3b cannot coexist in a solution
constraint count([F1[1], F2[2], F3[1]]) <= 1; % F1a F2b and F3a cannot coexist in a solution
Dekker1
  • 5,565
  • 25
  • 33
  • Dekker, I had to make a small addtion from Alex code to make your code work the way i want. Constraint SUM(F1)==1; SUM(F2)=1 and SUM(F3)=1 . Without that the solution outputs more than 1 element being True in F2 and F3 – Mahesh Subramaniam Jul 29 '20 at 06:07
  • @MaheshSubramaniam, As I noted in my explanation, it was a bit unclear to me if you meant at least 1 or exactly 1 for these arrays. The idea would then be to use a count constraint. As I commented on Alex' answer, `sum` gives the linearized version of the problem which would not work optimally on various solvers. I'll edit my answer to reflect you comment – Dekker1 Jul 29 '20 at 06:50
  • Dekker , I have stated my actual problem. Need your advice on that – Mahesh Subramaniam Jul 29 '20 at 12:21