检查 n*n 矩阵中每个元素的邻居的 minizinc 函数
A minizinc function that checks the neighbors for every element in an n*n matrix
我试图在 minizinc 中搜索 n*n 矩阵元素的每个邻居。到目前为止,我使用非常有效的方式,我对整个矩阵使用 if-else,并使用单独的条件来处理边界变量。我对 minizinc 有点陌生,我希望是否有一种有效的方法来做到这一点。也许有功能或其他东西。
int: size; % Enter the size lads
set of int: board = 0..size-1;
array[board,board] of var 0..1: grid;
var int: z = sum(r in board, c in board) (grid[r,c]);
% solve maximize z;
solve :: int_search(
[grid[i,j] | i,j in board],
smallest,
indomain_max,
complete)
maximize z;
constraint
forall(r in board,c in board,x in board) (
if (r==0/\c==0) then %corner 1
(
if ( (grid[r,c+1] + grid[r+1,c+1]+grid[r,c+1])==3) then (grid[r,c] = 1)
elseif(
(grid[r,c+1] + grid[r+1,c+1]+grid[r,c+1]) ==2)then(grid[r,c] = grid[r,c])
else grid[r,c]=0 endif
)
elseif (r==size-1/\c==size-1) then %corner2
( if ((grid[r-1,c]+grid[r,c-1]+grid[r-1,c-1])==3) then (grid[r,c] = 1)
elseif((grid[r-1,c]+grid[r,c-1]+grid[r-1,c-1]) ==2) then (grid[r,c] = grid[r,c])
else (grid[r,c] = 0) endif
)
elseif (r==0/\c==size-1) then %corner3
( if( (grid[r,c-1]+grid[r+1,c]+grid[r+1,c-1])==3) then (grid[r,c] = 1)
elseif((grid[r,c-1]+grid[r+1,c]+grid[r+1,c-1]) ==2)then (grid[r,c] = grid[r,c])
else(grid[r,c] = 0) endif
)
elseif (r==size-1/\c==0) then %corner4
( if((grid[r-1,c]+grid[r,c+1]+grid[r-1,c+1])==3) then (grid[r,c] = 1)
elseif((grid[r-1,c]+grid[r,c+1]+grid[r-1,c+1]) ==2) then (grid[r,c] = grid[r,c])
else(grid[r,c] = 0) endif
)
elseif (r==0/\c==x/\c!=0/\c!=size-1) then %top row
( if((grid[r,c-1]+grid[r+1,c-1]+grid[r+1,c]+grid[r+1,c+1]+grid[r,c+1])==3) then (grid[r,c] = 1)
elseif((grid[r,c-1]+grid[r+1,c-1]+grid[r+1,c]+grid[r+1,c+1]+grid[r,c+1])==2 ) then (grid[r,c] = grid[r,c])
else(grid[r,c] = 0) endif
)
elseif (r==size-1/\c==x/\c!=0/\c!=size-1) then %last row
( if((grid[r,c-1]+grid[r-1,c-1]+grid[r-1,c]+grid[r-1,c+1]+grid[r,c+1])==3) then (grid[r,c] = 1)
elseif((grid[r,c-1]+grid[r-1,c-1]+grid[r-1,c]+grid[r-1,c+1]+grid[r,c+1]) ==2 ) then (grid[r,c] = grid[r,c])
else(grid[r,c] = 0) endif
)
elseif (r==x/\c==0/\r!=0/\r!=size-1) then %first col
( if ((grid[r-1,c]+grid[r-1,c+1]+grid[r,c+1]+grid[r+1,c+1]+grid[r+1,c])==3) then (grid[r,c] = 1)
elseif((grid[r-1,c]+grid[r-1,c+1]+grid[r,c+1]+grid[r+1,c+1]+grid[r+1,c]) ==2) then (grid[r,c] = grid[r,c])
else (grid[r,c] = 0) endif
)
elseif (r==x/\c==0/\r!=0/\r!=size-1) then %last col
( if((grid[r-1,c]+grid[r-1,c-1]+grid[r,c-1]+grid[r+1,c-1]+grid[r+1,c])==3) then (grid[r,c] = 1)
elseif((grid[r-1,c]+grid[r-1,c-1]+grid[r,c-1]+grid[r+1,c-1]+grid[r+1,c]) ==2)then(grid[r,c] = grid[r,c])
else(grid[r,c] = 0) endif
)
elseif (r!=0 /\ c!=x) /\ (r!=size-1/\c!=x)/\(r!=x/\c!=0)/\(r!=x/\c!=size-1) then %rest
(if(( grid[r-1,c-1] + grid[r-1,c] + grid[r-1,c+1] +
grid[r,c-1] + grid[r,c+1] +
grid[r+1,c-1] + grid[r+1,c] + grid[r+1,c+1]
)==3)then(grid[r,c] = 1)
elseif (( grid[r-1,c-1] + grid[r-1,c] + grid[r-1,c+1] +
grid[r,c-1] + grid[r,c+1] +
grid[r+1,c-1] + grid[r+1,c] + grid[r+1,c+1]
)==2 )then (grid[r,c] = grid[r,c])
else(grid[r,c] = 0)
endif
) /\ %endif
if (grid[r,0]==1 /\ grid[r+1,0]==1) then grid[r+2,0]=0 endif /\
if (grid[0,c]==1 /\ grid[0,c+1]==1) then grid[0,c+2]=0 endif /\
if (grid[size-1,c]==1 /\ grid[size-1,c+1]==1) then grid[size-1,c+2]=0 endif /\
if (grid[r,size-1]==1 /\ grid[r+1,size-1]==1) then grid[r+2,size-1]=0 endif
else r=r/\c=c
endif
)
/\
forall(r in board,c in board)(
if (grid[r,0]==1 /\ grid[r+1,0]==1) then grid[r+2,0]=0 endif /\
if (grid[0,c]==1 /\ grid[0,c+1]==1) then grid[0,c+2]=0 endif /\
if (grid[size,c]==1 /\ grid[size,c+1]==1/\ c<size-2/\c>1) then grid[size-1,c+2]=0 endif /\
if (grid[r,size]==1 /\ grid[r+1,size]==1 /\ r<size-2/\r>1) then grid[r+2,size-1]=0 endif
)
;
output [
if j = 0 then "\n" else " " endif ++
show(grid[i,j])
| i,j in board
]
;
这是对单元格(不包括“此”单元格)的邻居求和的一般方法。对于每个单元格,它定义了一个临时变量 (t
),用于对相邻单元格的值求和。然后,您必须为 t
.
的不同值添加逻辑
int: r = 4; % rows
int: c = 4; % column
array[1..r, 1..c] of var 0..1: x;
constraint
forall(i in 1..r, j in 1..c) (
let {
var 0..r*c: t
}
in
t = sum(a,b in {-1,0,1} where
i+a in 1..r /\ j+b in 1..c % ensure we are in the matrix
/\ (a != 0 \/ b != 0) % don't include "this" cell
) (x[i+a,j+b])
)
;
solve satisfy;
更新:这是具有函数 sum_neighbors
的同一模型,该函数计算特定单元格的邻居数。
int: r = 4; % rows
int: c = 4; % column
array[1..r, 1..c] of var 0..1: x;
function var int: sum_neighbors(int: i,int: j) =
sum(a,b in {-1,0,1} where
i+a in 1..r /\ j+b in 1..c /\ (a != 0 \/ b != 0)
) (x[i+a,j+b])
;
constraint
forall(i in 1..r, j in 1..c) (
let {
var 0..r*c: t
}
in
t = sum_neighbors(r,c)
)
;
solve satisfy;
您不必使用临时 t
变量,我添加它只是为了能够测试模型。您现在可以写
constraint
forall(i in 1..r, j in 1..c) (
if sum_neighbors(r,c) == 2 then
% ...
else
% ...
endif
)
;
我试图在 minizinc 中搜索 n*n 矩阵元素的每个邻居。到目前为止,我使用非常有效的方式,我对整个矩阵使用 if-else,并使用单独的条件来处理边界变量。我对 minizinc 有点陌生,我希望是否有一种有效的方法来做到这一点。也许有功能或其他东西。
int: size; % Enter the size lads
set of int: board = 0..size-1;
array[board,board] of var 0..1: grid;
var int: z = sum(r in board, c in board) (grid[r,c]);
% solve maximize z;
solve :: int_search(
[grid[i,j] | i,j in board],
smallest,
indomain_max,
complete)
maximize z;
constraint
forall(r in board,c in board,x in board) (
if (r==0/\c==0) then %corner 1
(
if ( (grid[r,c+1] + grid[r+1,c+1]+grid[r,c+1])==3) then (grid[r,c] = 1)
elseif(
(grid[r,c+1] + grid[r+1,c+1]+grid[r,c+1]) ==2)then(grid[r,c] = grid[r,c])
else grid[r,c]=0 endif
)
elseif (r==size-1/\c==size-1) then %corner2
( if ((grid[r-1,c]+grid[r,c-1]+grid[r-1,c-1])==3) then (grid[r,c] = 1)
elseif((grid[r-1,c]+grid[r,c-1]+grid[r-1,c-1]) ==2) then (grid[r,c] = grid[r,c])
else (grid[r,c] = 0) endif
)
elseif (r==0/\c==size-1) then %corner3
( if( (grid[r,c-1]+grid[r+1,c]+grid[r+1,c-1])==3) then (grid[r,c] = 1)
elseif((grid[r,c-1]+grid[r+1,c]+grid[r+1,c-1]) ==2)then (grid[r,c] = grid[r,c])
else(grid[r,c] = 0) endif
)
elseif (r==size-1/\c==0) then %corner4
( if((grid[r-1,c]+grid[r,c+1]+grid[r-1,c+1])==3) then (grid[r,c] = 1)
elseif((grid[r-1,c]+grid[r,c+1]+grid[r-1,c+1]) ==2) then (grid[r,c] = grid[r,c])
else(grid[r,c] = 0) endif
)
elseif (r==0/\c==x/\c!=0/\c!=size-1) then %top row
( if((grid[r,c-1]+grid[r+1,c-1]+grid[r+1,c]+grid[r+1,c+1]+grid[r,c+1])==3) then (grid[r,c] = 1)
elseif((grid[r,c-1]+grid[r+1,c-1]+grid[r+1,c]+grid[r+1,c+1]+grid[r,c+1])==2 ) then (grid[r,c] = grid[r,c])
else(grid[r,c] = 0) endif
)
elseif (r==size-1/\c==x/\c!=0/\c!=size-1) then %last row
( if((grid[r,c-1]+grid[r-1,c-1]+grid[r-1,c]+grid[r-1,c+1]+grid[r,c+1])==3) then (grid[r,c] = 1)
elseif((grid[r,c-1]+grid[r-1,c-1]+grid[r-1,c]+grid[r-1,c+1]+grid[r,c+1]) ==2 ) then (grid[r,c] = grid[r,c])
else(grid[r,c] = 0) endif
)
elseif (r==x/\c==0/\r!=0/\r!=size-1) then %first col
( if ((grid[r-1,c]+grid[r-1,c+1]+grid[r,c+1]+grid[r+1,c+1]+grid[r+1,c])==3) then (grid[r,c] = 1)
elseif((grid[r-1,c]+grid[r-1,c+1]+grid[r,c+1]+grid[r+1,c+1]+grid[r+1,c]) ==2) then (grid[r,c] = grid[r,c])
else (grid[r,c] = 0) endif
)
elseif (r==x/\c==0/\r!=0/\r!=size-1) then %last col
( if((grid[r-1,c]+grid[r-1,c-1]+grid[r,c-1]+grid[r+1,c-1]+grid[r+1,c])==3) then (grid[r,c] = 1)
elseif((grid[r-1,c]+grid[r-1,c-1]+grid[r,c-1]+grid[r+1,c-1]+grid[r+1,c]) ==2)then(grid[r,c] = grid[r,c])
else(grid[r,c] = 0) endif
)
elseif (r!=0 /\ c!=x) /\ (r!=size-1/\c!=x)/\(r!=x/\c!=0)/\(r!=x/\c!=size-1) then %rest
(if(( grid[r-1,c-1] + grid[r-1,c] + grid[r-1,c+1] +
grid[r,c-1] + grid[r,c+1] +
grid[r+1,c-1] + grid[r+1,c] + grid[r+1,c+1]
)==3)then(grid[r,c] = 1)
elseif (( grid[r-1,c-1] + grid[r-1,c] + grid[r-1,c+1] +
grid[r,c-1] + grid[r,c+1] +
grid[r+1,c-1] + grid[r+1,c] + grid[r+1,c+1]
)==2 )then (grid[r,c] = grid[r,c])
else(grid[r,c] = 0)
endif
) /\ %endif
if (grid[r,0]==1 /\ grid[r+1,0]==1) then grid[r+2,0]=0 endif /\
if (grid[0,c]==1 /\ grid[0,c+1]==1) then grid[0,c+2]=0 endif /\
if (grid[size-1,c]==1 /\ grid[size-1,c+1]==1) then grid[size-1,c+2]=0 endif /\
if (grid[r,size-1]==1 /\ grid[r+1,size-1]==1) then grid[r+2,size-1]=0 endif
else r=r/\c=c
endif
)
/\
forall(r in board,c in board)(
if (grid[r,0]==1 /\ grid[r+1,0]==1) then grid[r+2,0]=0 endif /\
if (grid[0,c]==1 /\ grid[0,c+1]==1) then grid[0,c+2]=0 endif /\
if (grid[size,c]==1 /\ grid[size,c+1]==1/\ c<size-2/\c>1) then grid[size-1,c+2]=0 endif /\
if (grid[r,size]==1 /\ grid[r+1,size]==1 /\ r<size-2/\r>1) then grid[r+2,size-1]=0 endif
)
;
output [
if j = 0 then "\n" else " " endif ++
show(grid[i,j])
| i,j in board
]
;
这是对单元格(不包括“此”单元格)的邻居求和的一般方法。对于每个单元格,它定义了一个临时变量 (t
),用于对相邻单元格的值求和。然后,您必须为 t
.
int: r = 4; % rows
int: c = 4; % column
array[1..r, 1..c] of var 0..1: x;
constraint
forall(i in 1..r, j in 1..c) (
let {
var 0..r*c: t
}
in
t = sum(a,b in {-1,0,1} where
i+a in 1..r /\ j+b in 1..c % ensure we are in the matrix
/\ (a != 0 \/ b != 0) % don't include "this" cell
) (x[i+a,j+b])
)
;
solve satisfy;
更新:这是具有函数 sum_neighbors
的同一模型,该函数计算特定单元格的邻居数。
int: r = 4; % rows
int: c = 4; % column
array[1..r, 1..c] of var 0..1: x;
function var int: sum_neighbors(int: i,int: j) =
sum(a,b in {-1,0,1} where
i+a in 1..r /\ j+b in 1..c /\ (a != 0 \/ b != 0)
) (x[i+a,j+b])
;
constraint
forall(i in 1..r, j in 1..c) (
let {
var 0..r*c: t
}
in
t = sum_neighbors(r,c)
)
;
solve satisfy;
您不必使用临时 t
变量,我添加它只是为了能够测试模型。您现在可以写
constraint
forall(i in 1..r, j in 1..c) (
if sum_neighbors(r,c) == 2 then
% ...
else
% ...
endif
)
;