【问题标题】:Appending lists in prolog without repetition在序言中添加列表而不重复
【发布时间】:2014-04-06 01:45:27
【问题描述】:

我需要知道如何获得将两个列表相互附加而不重复的所有组合,例如 [1,2] 和 [3,4] 结果将是 [1,3] [1,4] [ 2,3] [2,4]

【问题讨论】:

  • 您自己尝试过吗?这很简单。看看member/2 谓词。
  • 提示:[X,Y] 是一对分别来自L1L2 的元素,如果XL1 的成员并且Y 是成员L2.
  • 是的,我试过了,但它只给了我 [1,3] [2,4] 但我需要所有组合,你能帮帮我吗?
  • 你能编辑你的问题并展示你尝试了什么吗?
  • 梳子([],[],[])。梳([H|T],[X|Y],[H,X])。梳([H,T|T1], [X,Y|T2], [T,Y])。梳([H|T],[X|Y],L):-梳(T,Y,[H|X])。这是我尝试过的

标签: prolog


【解决方案1】:

这是无法按预期工作的解决方案:

(1) comb([], [], []).
(2) comb([H|T], [X|Y], [H,X]).
(3) comb([H,T|T1], [X,Y|T2], [T,Y]).
(4) comb([H|T], [X|Y], L) :-
        comb(T, Y, [H|X]). 

(1) 说,将一个空列表与一个空列表组合是一个空列表。 这听起来逻辑上是正确的。

(2) 说,[H,X] 是来自[H|T][X|Y] 的一对元素。确实如此(仅提供解决方案的一种组合)。

(3) 说,[T,Y] 是来自[H,T|T1][X,Y|T2] 的一对元素。这也是正确的(只为解决方案提供了一种其他组合,与 #2 不同)。

(4) 说,L 是一对来自[H|T][X|Y] 的元素,如果[H|X] 是一对来自TY 的元素。这不可能是真的,因为L 没有出现在子句的结果中,所以它永远不会被实例化。

上述解决方案被过度考虑并且比它需要的更复杂。它失败了,因为它硬编码了两个解决方案(匹配前两个元素和后两个元素)。递归子句是错误的,因为它没有逻辑基础,解决方案被保留为单例变量。

首先,您需要确定谓词的含义。在这个特定问题中,如果P 是一对(比如[X,Y]),其中X 来自XsXXs 的成员,Y 来自 YsYYs 的成员)。然后,当您查询谓词时,它会提示您提供每个解决方案,直到找到所有解决方案。

这个问题可以用一条规则来说明:[X,Y] 是分别取自XsYs 的元素的组合,如果XXsY 的成员是Ys 的成员。这听起来像是一个微不足道的真实陈述,但这就是解决这个问题所需要的全部内容。

把它翻译成 Prolog 得到这个:

comb(Xs, Ys, [X,Y]) :-  % [X,Y] is combination of elements from Xs and Ys if...
    member(X, Xs),      % X is a member of Xs, and
    member(Y, Ys).      % Y is a member of Ys

现在让我们试试吧:

| ?- comb([1,2],[3,4],P).

P = [1,3] ? ;

P = [1,4] ? ;

P = [2,3] ? ;

P = [2,4]

(2 ms) yes
| ?-

它找到了所有的组合。我们让 Prolog 完成所有工作,我们只需要声明规则是什么。

如果您想将所有结果收集到一个列表中,可以使用内置谓词,例如findall/3

| ?- findall(P, comb([1,2], [3,4], P), AllP).

AllP = [[1,3],[1,4],[2,3],[2,4]]

yes
| ?-

然后瞧。 :)

您还可以非常轻松地概括解决方案,并从给定列表的每个列表中选择一个元素。在这里,multicomb/2 有一个列表列表作为第一个参数(例如、[[1,2]、[3,4]]`,并生成每个元素的组合,每个组合一个子列表:

multicomb([L|Ls], [X|Xs]) :-
    member(X, L),
    multicomb(Ls, Xs).
multicomb([], []).

这给出了:

| ?- multicomb([[1,2],[3,4]], P).

P = [1,3] ? a

P = [1,4]

P = [2,3]

P = [2,4]

yes
| ?-

还有:

| ?- multicomb([[1,2],[a,b],[x,y,z]], P).

P = [1,a,x] ? a

P = [1,a,y]

P = [1,a,z]

P = [1,b,x]

P = [1,b,y]

P = [1,b,z]
...

【讨论】:

    猜你喜欢
    • 2023-03-19
    • 2018-01-18
    • 1970-01-01
    • 1970-01-01
    • 2015-05-21
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 1970-01-01
    相关资源
    最近更新 更多