让我有矩阵
A =
1 2 3
1 3 5
1 2 4
2 3 7
任务是重新排列矩阵,以使两个元素在任何行中都没有相同的顺序。
例如,在第1行和第2行中,数字1和3的顺序相同。我们将第1行中的1和3中的数字从左向右翻转,得到
3 2 1
1 3 5
1 2 4
2 3 7
我的想法是这是一个搜索问题,可以用答案集编程解决吗?问题是,如果您尝试使用某种算法来执行此操作,那么最终您将把两个数字按与其他行中相同的顺序放入。
这对于重新定向网格的三角形曲面网格面很有用,其中面法线指向不一致的方向,以便所有法线指向内(或向外)
答案 0 :(得分:0)
是的,您可以使用ASP进行此操作。
这不是最优雅的代码,但是我认为如果使用Clingo系列5,您可以这样做:
%% List the numbers to fill the matrix, we must associated each with an index value
number(1,1;2,2;3,3;1,4;3,5;5,6;1,7;2,8;4,9;2,10;3,11;7,12).
%% x limits
x(0..2).
%% y limits
y(0..3).
%% Generate the matrix
{ matrix(V, I, X, Y) } :- number(V, I), x(X), y(Y).
%% Define the order of the elements
order(V1, I1, V2, I2, Y) :- matrix(V1, I1, X1, Y), matrix(V2, I2, X2, Y), X1 < X2.
%% Do not allow two different rows to have the same order of elements
:- order(V1, I1, V2, I2, Y1), order(V1, I3, V2, I4, Y2), Y1 != Y2.
%% Each number must be in the matrix exactly once
:- not { matrix(V, I, X, Y) } = 1, number(V, I).
%% Each element can contain only one number
:- not #count { V, I : matrix(V, I, X, Y) } = 1, matrix(_, _, X, Y).
%% Show the matrix
#show matrix/4.
哪个给你作为输出:
3 1 3
4 2 3
1 1 5
2 2 7
尽管不介意,但仍有数十万种方法(我认为是数百万种)用于订购此矩阵并获得满足您的约束条件的结果。
答案 1 :(得分:0)
以以下形式输入:
value(ROW,COL,VAL).
nrows(nr).
ncols(nc).
您可以执行以下操作:
row(1..NR) :- nrows(NR).
col(1..NC) :- ncols(NC).
is_value(V) :- value(_, _, V).
% For each position in the original matrix, say what new column it's in.
{new_place(ROW,OLDCOL,NEWCOL,VAL) : col(NEWCOL)} = 1 :- value(ROW,OLDCOL,VAL).
% Can't have more than one value in the same position.
:- {new_place(ROW,_,COL,_)} > 1; row(ROW); col(COL).
% A comes before B in row ROW if COL_A < COL_B
ordered(A,B,ROW) :- new_place(ROW,_,COL_A,A); new_place(ROW,_,COL_B,B); COL_A < COL_B.
% For any two values A and B, there exists at most one row where A comes before B
:- {ordered(A,B,ROW) : row(ROW)} > 1; is_value(A); is_value(B).
#show.
#show p(R,C,V) : new_place(R,_,C,V).
请注意,如果一行中有重复项,则必须跟踪原始列。如果没有行包含重复项(例如您的示例),则new_place
的第二个参数是不必要的。