Если я правильно понимаю вашу проблему, то вы ищете функцию, которая возвращает массив, который может содержать все возможные чередования двух данных массивов.
Эта проблема, как кажется, более сложная, так какрезультирующий массив не может быть скомпрометирован с теми же переменными, что и аргументы, но должен быть сам по себе переменным.
Боюсь, я не вижу способа сделать это в понимании, но используянесколько глобалов.Рабочая функция может состоять из:
include "globals.mzn";
function array[int] of var int: interleave(array[int] of var int: a, array[int] of var int: b) = let {
array[index_set(a)] of var 1..length(a ++ b): map_a;
array[index_set(b)] of var 1..length(a ++ b): map_b;
array[1..length(a ++ b)] of var dom_bounds_array(a ++ b): c;
constraint all_different(map_a ++ map_b);
constraint forall(i in index_set(a)) (c[map_a[i]] = a[i]);
constraint increasing(map_a);
constraint forall(i in index_set(b)) (c[map_b[i]] = b[i]);
constraint increasing(map_b);
} in c;
Неправильно понятое решение: Выбор элемента 1 на 1:
Решение вашей проблемы состоит в объединении нескольких пониманий:
- Понимание для чередующихся массивов, когда элементы выбираются из каждого массива по одному за раз.
- Понимания для добавления оставшейся части элементов, если один массив длиннее другого.
Результирующая функция будет иметь вид:
function array[int] of var int: interleave(array[int] of var int: a, array[int] of var int: b) = let {
array[int] of int: ai = [ i | i in index_set(a)];
array[int] of int: bi = [ i | i in index_set(b)];
int: share = min(length(a), length(b));
} in [ if x = 1 then a[ai[i]] else b[bi[i]] endif | i in 1..share, x in 1..2]
++ [ a[ai[i]] | i in share+1..length(a) ]
++ [ b[bi[i]] | i in share+1..length(b) ];
Также важно отметить, что в MiniZinc набор индексов не должен быть непрерывным.Поэтому мы используем понимание, чтобы также получить все элементы из набора индексов.Это главным образом для того, чтобы сделать эту функцию пригодной для использования с любым массивом MiniZinc.