Prolog,去除生成中的重复结果 [英] Prolog, remove repetitive results in generation

查看:86
本文介绍了Prolog,去除生成中的重复结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个 prolog 程序,它生成二维表中元素的所有可能位置.给出了元素数量和表格大小.

I wrote a prolog program which generates all possible positions of elements in a two-dimensional table. The number of elements and the table size are given.

我的代码是:

geni(Min, Min, Max) :- Min =< Max.
geni(Min, X, Max) :- Max >= Min, MinInc is Min+1, geni(MinInc, X, Max).
generate(_, 0, []) :- !.
generate(TSize, N, [X|Tail]) :- NDec is N-1, generate(TSize,NDec, Tail),
                                X=k(X1,Y1), geni(1,X1,TSize), geni(1,Y1,TSize), 
                                not(member(X, Tail)).

(其中TSize为表格大小,N为元素个数,最后一位为结果)谓词geni在区间[A;B]中生成数字X.

(there TSize is the size of table, N is the number of elements, and the last one is the result) Predicate geni generates number X in interval [A;B].

示例(2x2 表中的 2 个元素):

Example (2 elements in 2x2 table):

?- generate(2, 2, R).
R = [k(1, 1), k(1, 2)] ;
R = [k(1, 1), k(2, 1)] ;
R = [k(1, 1), k(2, 2)] ;
R = [k(1, 2), k(1, 1)] ;
R = [k(1, 2), k(2, 1)] ;
R = [k(1, 2), k(2, 2)] ;
R = [k(2, 1), k(1, 1)] ;
R = [k(2, 1), k(1, 2)] ;
R = [k(2, 1), k(2, 2)] ;
R = [k(2, 2), k(1, 1)] ;
R = [k(2, 2), k(1, 2)] ;
R = [k(2, 2), k(2, 1)] ;
false.

我的桌子是棋盘,元素是骑士.在这种情况下,所有元素都是平等的,但我的程序认为"不同.如何避免同等结果?像这样:

My table is chess board and elements are knights. In this case all elements are equal but my program "think" that the are different. How to avoid equal results? Like this:

R = [k(1, 1), k(1, 2)] ;
R = [k(1, 2), k(1, 1)] ;

推荐答案

目前,您使用 not(member(...)) 来确保结果不包含重复项.为了避免获得结果的所有排列,您只需确保结果中的元素是有序的.

Currently, you are using not(member(...)) to ensure the result contains no duplicate. To avoid getting all permutations of a result, you just have to make sure the elements in the result are ordered.

第一步是定义一个订单,比如这样:

Step 1 is to define an order, i.e. like this:

% A knight 1 is "bigger" than knight 2
% if the X-value is bigger or X is equal and Y is bigger
is_bigger(k(X1, Y1), k(X2, Y2)) :-
    X1 > X2; (X1 = X2, Y1 > Y2).

现在您必须确保要添加到列表中的元素比所有其他元素都大".

Now you have to ensure that the element you want to add to the list is "bigger" than all other elements.

geni(Min, X, Max) :- between(Min, Max, X).
generate(_, 0, []) :- !.
generate(TSize, N, [X|Tail]) :- X=k(X1,Y1),  NDec is N-1,
                            generate(TSize,NDec, Tail),
                            geni(1,X1,TSize),
                            geni(1,Y1,TSize),
                            maplist(is_bigger(X), Tail).

我使用内置谓词 maplist 来测试列表的所有元素.从示例中应该清楚它是如何工作的.

I am using the build-in predicate maplist to test all elements of the list. Frome the example it should be clear how it works.

如果您想颠倒顺序,请改用较低".

If you want to reverse the order, implement a "lower" instead.

?- generate(2, 2, T).
T = [k(1, 2), k(1, 1)] ;
T = [k(2, 1), k(1, 1)] ;
T = [k(2, 2), k(1, 1)] ;
T = [k(2, 1), k(1, 2)] ;
T = [k(2, 2), k(1, 2)] ;
T = [k(2, 2), k(2, 1)] ;
false.

这篇关于Prolog,去除生成中的重复结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆