Search code examples
arrayssetconstraintssubsetminizinc

How to constraint a variable in Minizinc to be part of a set


I am looking for a constraint that will force an array of variables to take the values from a specific set or Array

My constants are: An array of arrays (or array of sets) that are known (calculated using python script)

My decision variables are 3 arrays

I have a constraint: The decision variables should take one of the arrays of the constant array of arrays

%constants 
array [int] of set of int: possible_set;
possible_set= [{1,2,3},
              {4,5,6},
              {3,5,7},
              {7,8,9}];

%decision variables
array[1..3] of var 1..9: loc1;

constraint loc1 subset possible_set;   

 %The expected result is the loc1 will be one of the sets {1,2,3},
 %                 {4,5,6},
 %                 {3,5,7},
 %                {7,8,9}

however, I am getting an error :

MiniZinc: type error: type error in operator application for 'subset'. No matching operator found with left-hand side type array[int] of var int' and right-hand side typearray[int] of set of int` Process finished with non-zero exit code 1


Solution

  • The reason you get an error is that possible_set is not a set, but an array of sets.

    I think you better reformulate the model a bit. Here's a variant which seems to do what you want. My changes are the lines marked hakank.

    %constants 
    array [int] of set of int: possible_set;
    possible_set= [{1,2,3},
                   {4,5,6},
                   {3,5,7},
                   {7,8,9}];
    
    %decision variables
    %% array[1..3] of var 1..9: loc1; % ORIGINAL
    var set of 1..9: loc1_set; % hakank
    var 1..4: loc1; % index of the set that's selected.
    
    % constraint loc1 subset possible_set; %% ORIGINAL 
    constraint loc1_set = possible_set[loc1]; % hakank: set loc1_set to the loc1'th set
    
    solve satisfy;
    

    There are four solutions (as expected):

    loc1_set = 1..3;
    loc1 = 1;
    ----------
    loc1_set = 4..6;
    loc1 = 2;
    ----------
    loc1_set = {3,5,7};
    loc1 = 3;
    ----------
    loc1_set = 7..9;
    loc1 = 4;