簡體   English   中英

Minizinc:int數組的成對交集

[英]Minizinc: Pairwise intersection of int arrays

我有一些數組(可能超過10個)的int變量。 我正在尋找一種有效的方法來約束這些數組的成對交叉計數,即每個數組不能有超過x個元素與任何其他數組共同。

偽代碼中的示例:[1,4,4]和[2,2,1]將有一個共同的元素 - >數字1. [4,4,4]和[9,4,4]具有元素4通常,應忽略副本4。

在我當前的實現中,我遍歷所有數組對,並且每個元素檢查每個元素是否也在另一個數組中。 這當然是非常緩慢的,並且副本不會像它們應該那樣被消除。

我的代碼中有趣的部分如下所示:

constraint matches [0] = exists ( i in index_set(values1) ) ( values1[i]==values2[0] );
constraint matches [1] = exists ( i in index_set(values1) ) ( values1[i]==values2[1] );
constraint matches [2] = exists ( i in index_set(values1) ) ( values1[i]==values2[2] );
constraint matches [3] = exists ( i in index_set(values1) ) ( values1[i]==values2[3] );
constraint matches [4] = exists ( i in index_set(values1) ) ( values1[i]==values2[4] );

constraint sum(matches) <  x;

我已經考慮過使用minizinc集,因為它們支持一些set操作,但是我無法使用它們來處理變量。

有任何想法嗎?

也許是這樣的,使用array2set將數組轉換為集合然后cardintersect以計算每對之間的交叉點數。

int: rows = 4; % number of columns
int: cols = 5; % number of rows
array[1..rows,1..cols] of int: a = array2d(1..rows,1..cols, 
               [
               4,6,9,5,6,
               5,3,7,1,3,
               3,8,3,3,1,
               1,1,4,7,2,
               ]);
% convert the arrays to sets
array[1..rows] of set of int: s = [array2set([a[i,j] | j in 1..cols]) | i in 1..rows];

% decision variables
var int: z;

solve satisfy;
constraint
    z = sum(r1,r2 in 1..rows where r1 < r2) (
              card(s[r1] intersect s[r2])
        )
;
output 
[
  "z:\(z)\n"
] ++
[
  show(s[i]) ++ "\n"
  | i in 1..rows 
];

這個模型的輸出是

z:7
{4,5,6,9}
{1,3,5,7}
{1,3,8}
{1,2,4,7}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM