来自prolog中的一组N维向量的最小支配向量

时间:2012-11-20 15:04:19

标签: prolog

我需要编写一个程序来构造一组N维向量的最小支配向量。用于矢量集合S的主导矢量被定义为其第i个分量大于或等于S中每个矢量的第i个分量的矢量,其中i在矢量的所有维度上测量。必须将维度N作为用户的输入。

2 个答案:

答案 0 :(得分:0)

Prolog没有载体。你可以使用arity N的列表或结构。 在第二种情况下,当然N必须小于允许的最大值(SWI-Prolog有无限长度......)

如果您使用列表,则此代码应该这样做。我假设N是从列表长度隐含的。

'minimal dominating vector'([V|Vs], Min) :-
  'minimal dominating vector'(Vs, V, Min).

'minimal dominating vector'([], M, M).
'minimal dominating vector'([V|Vs], MinSoFar, Min) :-
   maplist(min, V, MinSoFar, Updated),
   'minimal dominating vector'(Vs, Updated, Min).

min(X, Y, M) :- X < Y -> M = X ; M = Y.

试验:

?- 'minimal dominating vector'(["abc","aab","uaa"],M),format('~s',[M]).
aaa
M = [97, 97, 97].

如果您的Prolog没有maplist / 4(我无法记住P#的详细信息),请将maplist(min, V, MinSoFar, Updated),替换为minvect(V, MinSoFar, Updated),,并添加此定义

minvect([], [], []).
minvect([N|Ns], [M|Ms], [R|Rs]) :- min(N,M,R), !, minvect(Ns,Ms,Rs).

注意,OT 当我在一年前尝试P#时,我发现它很慢,而且记忆力很差。如果你有大数组,那么你最好使用LINQ

答案 1 :(得分:0)

串行实施:

fnt(M,N) :-
    fnt2(M,N,0,[]).

fnt2(_,N,N,Ds) :-
    reverse(Ds,R),
    write(R).
fnt2(M,N,K,Ds) :-
    column(M,K,Col),
    max_list(Col,H),
    K2 is K+1,
    fnt2(M,N,K2,[H|Ds]).


row(M, N, Row) :-
    nth(N, M, Row).

column(M, N, Col) :-
    transpose(M, MT),
    row(MT, N, Col).

symmetrical(M) :-
    transpose(M, M).

transpose([[]|_], []) :- !.
transpose([[I|Is]|Rs], [Col|MT]) :-
    first_column([[I|Is]|Rs], Col, [Is|NRs]),
    transpose([Is|NRs], MT).

first_column([], [], []).
first_column([[]|_], [], []).
first_column([[I|Is]|Rs], [I|Col], [Is|Rest]) :-
    first_column(Rs, Col, Rest).

nth(0,[X|_],X).
            nth(N,[_|T],R):- M is N-1,nth(M,T,R).

max_list([H], H).
max_list([H|T], M2) :- 
  max_list(T, M),
  M2 is max(H, M).

并行实施(次要调整)

fnt(M,N) :-
    fnt2(M,N,0,[]).

fnt2(_,N,N,Ds) :-
    reverse(Ds,R),
    write(R).
fnt2(M,N,K,Ds) :-
    column(M,K,Col),
    max_list(Col,H),
    K2 is K+1,
    fork(fnt2(M,N,K2,[H|Ds])).


row(M, N, Row) :-
    nth(N, M, Row).

column(M, N, Col) :-
    transpose(M, MT),
    row(MT, N, Col).

symmetrical(M) :-
    transpose(M, M).

transpose([[]|_], []) :- !.
transpose([[I|Is]|Rs], [Col|MT]) :-
    first_column([[I|Is]|Rs], Col, [Is|NRs]),
    transpose([Is|NRs], MT).

first_column([], [], []).
first_column([[]|_], [], []).
first_column([[I|Is]|Rs], [I|Col], [Is|Rest]) :-
    first_column(Rs, Col, Rest).

nth(0,[X|_],X).
            nth(N,[_|T],R):- M is N-1,nth(M,T,R).

max_list([H], H).
max_list([H|T], M2) :- 
  max_list(T, M),
  M2 is max(H, M).

reverse(A,R) :- reverse(A,[],R).
reverse([X|Y],Z,W) :- reverse(Y,[X|Z],W).
reverse([],X,X).

测试:

time(fnt([[1,2,3,56],[14,5,6,43],[7,8,9,22]],4)).