如果 [a,b] 已经存在,如何从列表 [b,a] 中删除

How to eliminate from a list [b,a] if already exist [a,b]

我想做的很简单:我已经有一个以列表开头的“函数”(即 [a,b,c,d])生成列表中两个不同元素的每个组合.

[a,b,c,d] -> [[a,b], [a,c], ..., [b,a], ... ]

fun(List, Res):-
    findall( [A, B],
             ( member(A, List), 
               member(B, List), 
               \+ A = B ), 
             Res ).

现在我需要检查并删除每个具有相同原子且不需要配位的元素。

([a,b]-[b,a] = [b,a]-[a,b])

我尝试做的只是添加

fun(List, Res):-
    findall( [A, B],
             ( member(A, List), 
               member(B, List), 
               \+ A = B, 
               \+ member([B,A], Res)), % I TRIED TO ADD THIS
              Res).

我认为您不能直接在函数内部读取 Res

谢谢。

由于顺序无关紧要,您只能选择第一个元素在第二个元素之前的对(在 standard order of terms 中)。因此,假设列表中的所有元素都是不同的,您可以按如下方式定义所需的谓词:

pairs(List, Pairs):-
    findall( [X, Y],
             ( member(X, List),
               member(Y, List),
               X @< Y ),
             Pairs ).

示例:

?- pairs([a, b, c, d], Pairs).
Pairs = [[a, b], [a, c], [a, d], [b, c], [b, d], [c, d]].

?- pairs([3, 1, 5], Pairs).
Pairs = [[3, 5], [1, 3], [1, 5]].

听起来您正在尝试生成列表的组合。也就是说,您想要 select 来自给定对象集的不同对集,其中顺序并不重要 — 也就是说,组合 [1,2] 与 [=18= 的组合相同].

例如,给定集合 [1,2,3,4,5],长度为 2 的组合如下(因为“正确的”组合不允许重复,例如 [2,2],假设该项目已经已从集合中删除):

[1,2] [1,3] [1,4] [1,5]
- [2,3] [2,4] [2,5]
- - [3,4] [3,5]
- - - [4,5]

如果要允许重复,成对组合的集合是这样的:

[1,1] [1,2] [1,3] [1,4] [1,5]
- [2,2] [2,3] [2,4] [2,5]
- - [3,3] [3,4] [3,5]
- - - [4,4] [4,5]
- - - - [5,5]

完成此操作的最简单方法是...正确生成组合。比删除重复项所需的要容易得多:

因此,select2 select 是给定列表中特定大小的组合。在回溯时,它将依次 return 剩余的组合。

注意:第二个参数必须实例化为所需大小的未绑定列表:

select( _      , [] ) .
select( [X|Xs] , [X|Cs] ) :- select( Xs ,    Cs  ).
select( [_|Xs] , [X|Cs] ) :- select( Xs , [X|Cs] ).

允许重复是一个微不足道的改变:

select( _      , []     ) .
select( [X|T]  , [X|Cs] ) :- select( [X|T] ,    Cs  ).
select( [_|T]  , [X|Cs] ) :- select(    T  , [X|Cs] ).

无论您选择哪种口味,使用方法都非常简单:

Combination = [_,_], select([1,2,3,4,5],Combination).

这将 return Combination = [1,2],等等,直到用尽可能的解决方案。

您可以包裹 select/2 以指定您想要的组合的所需大小:

combination(N,Xs,C) :-
    length(Xs,L),     % how big is the source set?
    between(0,L,N),   % Ensure N > 0 and N <= L, the length of the source set
    length(C,N),      % create an unbound list of the desired length.
    select(Xs,C).     % and select a combination

用法很简单:

combination(2,[1,2,3,4,5],Combination).

还有returns Combination=[1,2],等等,直到解决方案space被耗尽。

但是考虑到您需要一个包含所有可能组合的列表的用例,您所需要的只是基础 select/2:

findall( [A,B], select([1,2,3,4,5], [A,B]), Combinations ).

这给了你预期的

Combinations=[
  [1,2], [1,3], [1,4], [1, 5],
         [2,3], [2,4], [2, 5],
                [3,4], [3, 5],
                       [4, 5]
]