Optimization k连续整数约束

Optimization k连续整数约束,optimization,constraint-programming,gurobi,Optimization,Constraint Programming,Gurobi,如何在约束编程中声明以下约束?(最好是在古罗比或彗星中) S是大小为n的整数数组。我可以用来填充数组的整数集在1-k范围内。对于可以使用的每个整数,都有一个约束条件cici表示连续整数i的最小数目 例如,如果c1=3,c2=2,那么11122111111不是一个有效序列,因为必须有两个连续的2,而111221111是一个有效序列。也许使用常规约束(Comet中的自动机)是最好的方法 然而,这里有一个简单的解决方案,它使用了许多具体化。至少可以将其转换为Comet(我认为Gurobi不支持具体化)

如何在约束编程中声明以下约束?(最好是在古罗比或彗星中)

S是大小为n的整数数组。我可以用来填充数组的整数集在1-k范围内。对于可以使用的每个整数,都有一个约束条件cici表示连续整数i的最小数目


例如,如果c1=3,c2=2,那么11122111111不是一个有效序列,因为必须有两个连续的2,而111221111是一个有效序列。

也许使用常规约束(Comet中的自动机)是最好的方法

然而,这里有一个简单的解决方案,它使用了许多具体化。至少可以将其转换为Comet(我认为Gurobi不支持具体化)

决策变量(序列)在数组“x”中。它还使用一个助手数组(“开始”),其中包含每个序列的开始位置;这使得对“x”中的序列进行推理变得更容易。序列的数量以“z”为单位(例如,用于优化问题)

根据x的大小和其他约束,可能会添加更多(冗余)约束,以确定可以有多少个序列等。不过,这里没有这样做

模型如下:

它也显示在下面

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];
int:n;
int:k;
%每个整数1..k的连续整数数
int:c的数组[1..k];
%决策变量
变量1..k:x的数组[1..n];
%开始[i]=1->x[i]开始一个新序列
%开始[i]=0->x[i]在一个序列中
变量0..k的数组[1..n]:开始;
%序列和
变量1..n:z=和([bool2int(开始[i]>0)| i在1..n中];
求解::int_搜索(x,第一次失败,indomain_min,完成)满足;
约束
forall(1..n中的a,1..k中的b)(
(开始[a]=b)->
(
forall(0..c[b]-1中的d)(x[a+d]=b)
/\
forall(1..c[b]-1中的d)(开始[a+d]=0)
/\
(如果a>1,则x[a-1]!=b否则为真endif)%
/\
(如果是0/\
forall(2..n中的i)(
开始[i]>0(x[i]!=x[i-1])
)
/\
forall(1..n中的i)(
开始[i]>0->x[i]=开始[i]
)
;
产出[
z:“++显示(z)+”\n”++
开始:“++显示(开始)+”\n++
x:“++显示(x)+”\n
];
%
%资料
%
%%根据上述问题:
%%这是一个独特的解决方案。
n=13;
k=2;
c=[3,2];