繁体   English   中英

Minizinc建模:以Vars作为坐标集

[英]Minizinc modelling: Vars as coordinate sets

我正在minizinc中建模约束满足程序,其中解决方案是在3D网格上分配点。 约束之一是,只有一个点可以占据任何给定位置,因此,这些点在至少一个坐标中必须成对地不同。

我的点变量建模为NX 3坐标数组:

array[1..N,1..3] of var -N..N: X;

而差异约束是

constraint forall(i in 1..N-1)(forall(j in i+1..N)(not X_eq(i,j))); %extremely slow
predicate X_eq(int: a, int: b)=
 (X[a,1]=X[b,1]/\X[a,2]=X[b,2]/\X[a,3]=X[b,3]);

但是,当我制定这样的约束条件时,问题的解决时间就激增了。 我还有许多其他限制要添加,它已经可以减慢速度以仅查找不同的点。

我试图将点建模为

array[1..N] var set of -N..N

这样我就可以使用内置功能

all_different

但是之后,我看到了如何强制集合具有基数3,并且使用通用大小的集合来建模整数的三元组似乎也不太自然。

我的问题是:对坐标集和所有约束进行建模的一种容易处理且“正确”的方法是什么?

我正在使用minizinc IDE捆绑包中的gecode解算器。 该模型如下所示。 解决时间为24分钟。

array[1..N] of 0..1:  seq=[1,1,0,0,0,0,0,1,1,0,0,0,1,0,0,0,1,0];    
int: N=18;
int: H=6;

array[1..N,1..3] of var -N..N: X;

array [1..H,1..3] of 0..N:c;     


%H are in core
constraint forall(i in 1..N)(  if (seq[i]=1) then exists(j in 1..H)([i,1]=c[j,1] /\ X[i,2]=c[j,2] /\ X[i,3]=c[j,3]   ) else true endif);
%All points different
constraint forall(i in 1..N-1)(forall(j in i+1..N)(not X_eq(i,j))); %extremely slow
predicate X_eq(int: a, int: b)=
 (X[a,1]=X[b,1]/\X[a,2]=X[b,2]/\X[a,3]=X[b,3]);


solve satisfy;
output[show(X[i,j]) ++ " "|i in 1..N,j in 1..3]++["\n"];

c=[|0,0,0|
0,0,1|
0,0,2|
0,1,0|
0,1,1|
0,1,2|];  

注意:我使用Gecode和Git的最新MiniZinc版本在60毫秒(不是24分钟)内运行了第一个解决方案,从而运行了您的模型。 因此,以下内容可能对您没有帮助...

另外,我回答了您的原始问题,即如何对3D数组X( array[1..N, 1..3] )使用all_different 我可能错过了您模型中的某些内容,但这是一个可以在9毫秒内解决可满足性问题的模型。

创建将点转换为整数的数组的想法: (X[I,1]-1)*N*N + (X[I,2]-1)*N + X[I,3] (cf十进制数523是5 * 10 * 10 + 2 * 10 + 3)。 也许必须对此进行调整,但是您可以理解。 另外,我在注释中添加了另一种方法,该方法比较应该比X_eq谓词更快的每对点。

请注意,如果生成的整数非常大(例如,对于大N),则此all_different方法可能会很糟糕。

include "globals.mzn"; 

array[1..N] of 0..1:  seq=[1,1,0,0,0,0,0,1,1,0,0,0,1,0,0,0,1,0];    
int: N=18;
int: H=6;
array [1..H,1..3] of 0..N:c;     
array[1..N,1..3] of var -N..N: X;

solve satisfy;

% hakank: here's my approach of all_different
constraint
   all_different([(X[i,1]-1)*N*N + (X[i,2]-1)*N + X[i,3] | i in 1..N])

   %% another approach (slower than all_different)
   %% for each pair: ensure that there is at least one coordinate differ
   % forall(I in 1..N, J in 1..N where I < J) (
   %   sum([X[I,K] != X[J,K] | K in 1..3]) > 0
   % )

  ;

  % from original model
  constraint
     %H are in core
     forall(i in 1..N)(  
        if (seq[i]=1) then exists(j in 1..H) (
              X[i,1]=c[j,1] /\ X[i,2]=c[j,2] /\ X[i,3]=c[j,3]   
        ) 
        else true endif
    )
  ;

  output 
  [
     show([X[I,J]  | J in 1..3]) ++ "\n"
     | I in 1..N
  ] 
  ;

  c=[|0,0,0|
      0,0,1|
      0,0,2|
      0,1,0|
      0,1,1|
      0,1,2|];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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