简体   繁体   中英

Minizinc : var array with variable size

I want solve this problem: i have a number n and i want to have an array with all pair (i,j) for all i,j in [1,n]

I write this for solve the problem:

include "globals.mzn";
int:n=2;

var 1..:ArrayLenght;
array[1..ArrayLenght,1..2] of var 1..n:X;

constraint forall(i,j in 1..n)(exists(r in 1..ArrayLenght) (X[r,..] == [i,j]));

solve minimize ArrayLenght;

but i have a type error type error: type-inst must be par set but is 'var set of int' on this line array[1..ArrayLenght,1..2] of var 1..size:X

So how i can do to have an array with a variabe size? (i don't see anything about this in the official documentation)

NB: for this specific example, it would be better to set the arrayLenght to n*n but it's a minimal example, I have to add constraints that make the size of array cannot be fixed.

MiniZinc does not support variable length arrays. The dimensions of a all arrays must be known at compile time. One common approach to handle this is to create a multi-dimensional array of dimension - say - nxm (where n and m are the largest possible values in each dimension) and then set 0 (or some other value) as a dummy variable for the "invalid" cells.

However, it seems that what you want here is just to create an array of pairs of numbers. It's quite easy to create this without using any decision variables (ie without var... ).

Here are two different approaches to generate the pairs:

  • pairs1 is the pairs with i < j
  • pairs2 is the all possible pairs

The loop variable k in the list comprehensions is used as a counter to select either the i value or the j in the appropriate places.

int: n = 5;
int: num_pairs1 = n*(n-1) div 2;
int: num_pairs2 = n*n;
        
array[1..num_pairs1,1..2] of int: pairs1 = array2d(1..num_pairs1,1..2, [ if k == 1 then i else j endif | i,j in 1..n, k in 1..2 where i < j]);

array[1..num_pairs2,1..2] of int: pairs2 = array2d(1..num_pairs2,1..2, [ if k == 1 then i else j endif | i,j in 1..n, k in 1..2]);

output ["pairs1:\n", show2d(pairs1)];
output ["\n\npairs2:\n", show2d(pairs2)];

The output is

pairs1:
[| 1, 2
 | 1, 3
 | 1, 4
 | 1, 5
 | 2, 3
 | 2, 4
 | 2, 5
 | 3, 4
 | 3, 5
 | 4, 5
 |]

pairs2:
[| 1, 1
 | 1, 2
 | 1, 3
 | 1, 4
 | 1, 5
 | 2, 1
 | 2, 2
 | 2, 3
 | 2, 4
 | 2, 5
 | 3, 1
 | 3, 2
 | 3, 3
 | 3, 4
 | 3, 5
 | 4, 1
 | 4, 2
 | 4, 3
 | 4, 4
 | 4, 5
 | 5, 1
 | 5, 2
 | 5, 3
 | 5, 4
 | 5, 5
 |]
----------
==========

Hope this helps. If not, please describe in more detail what you are looking for.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM