[英]k consecutive integers constraint
如何在約束編程中聲明以下約束? (最好是在Gurobi或Comet中)。
S是大小為n的整數數組。 我可以用來填充數組的整數集在1-k范圍內。 每個可以使用的整數都有一個約束ci 。 ci表示連續整數i的最小數量。
例如,如果c1 = 3,c2 = 2,則1112211112111不是有效序列,因為必須有兩個連續的2,而1112211122111是有效序列。
也許使用常規約束(Comet中的自動機)將是最好的方法。
但是,這是MiniZinc中的一個直接解決方案,它使用了大量的改進方法。 至少應該有可能將其翻譯成Comet(我不認為Gurobi支持修訂)。
決策變量(序列)在數組“ x”中。 它還使用一個輔助數組(“ starts”),其中包含每個序列的起始位置。 這使得更容易推斷“ x”中的序列。 序列數為“ z”(例如,針對優化問題)。
根據x的大小和其他約束,可以在可能存在的序列數等上添加更多(冗余)約束。但是,這里不做此操作。
這是模型: http : //www.hakank.org/minizinc/k_consecutive_integers.mzn
它也在下面顯示。
int: n;
int: k;
% number of consecutive integers for each integer 1..k
array[1..k] of int: c;
% decision variables
array[1..n] of var 1..k: x;
% starts[i] = 1 -> x[i] starts a new sequence
% starts[i] = 0 -> x[i] is in a sequence
array[1..n] of var 0..k: starts;
% sum of sequences
var 1..n: z = sum([bool2int(starts[i] > 0) | i in 1..n]);
solve :: int_search(x, first_fail, indomain_min, complete) satisfy;
constraint
forall(a in 1..n, b in 1..k) (
(starts[a] = b ) ->
(
forall(d in 0..c[b]-1) (x[a+d] = b )
/\
forall(d in 1..c[b]-1) (starts[a+d] = 0 )
/\
(if a > 1 then x[a-1] != b else true endif) % before
/\
(if a <= n-c[b] then x[a+c[b]] != b else true endif) % after
)
)
/\
% more on starts
starts[1] > 0 /\
forall(i in 2..n) (
starts[i] > 0 <-> ( x[i]!=x[i-1] )
)
/\
forall(i in 1..n) (
starts[i] > 0 -> x[i] = starts[i]
)
;
output [
"z : " ++ show(z) ++ "\n" ++
"starts: " ++ show(starts) ++ "\n" ++
"x : " ++ show(x) ++ "\n"
];
%
% data
%
%% From the question above:
%% It's a unique solution.
n = 13;
k = 2;
c = [3,2];
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.