我有以下例子:
bag(b1)
bag(b2)
item(i1)
item(i2)
item(i3)
item(i4)
现在我真的不明白我是如何从中获得所有可能性的?我必须使用所有的包。 就像我应该得到这样的列表列表:
[
[together(b1, [i1,i2,i3,i4]), together(b2, [])]
,...,
[together(b1, [i1]), together(b2, [i2,i3,i4])]
[together(b1, [i1,i2]), together(b2, [i3,i4])]
]
等所有可能的组合但必须使用所有项。我知道我可以使用findall
获取事实,但后来我被卡住了
这就是我所拥有的:
test(X) :-
findall(C, bag(C),Bags),
findall(K, item(K),Items),
something???
关于从哪里开始的任何想法,因为我是无能为力的,我不明白如何思考以达到这样的结果。
获得组合的可能想法:
item_combination(C) :-
findall(I, item(I), Is),
combination(Is, C).
combination(_, []).
combination(Set, [X|Xs]) :-
select(X, Set, Set0),
combination(Set0, Xs).
我需要类似的东西,得到第一个包的组合,然后,转到下一个包,采取组合,如果它是有效的(所有使用的项目)附加到列表,否则回到第一个包与另一种组合等等......还是有更好的解决方案?
提前致谢!
答案 0 :(得分:2)
首先定义谓词powset/3
,该谓词powset3([],[],[]).
powset3([H|T],T2,[H|T3]) :-
powset3(T,T2,T3).
powset3([H|T],[H|T2],T3) :-
powset3(T,T2,T3).
生成给定集合中的所有powersets,未选择元素作为第三个列表:
divide/3
接下来,我们定义一个N
命令,该命令给出一个项目列表,将其划分为divide(_,N,[]) :-
N < 1.
divide(Items,1,[Items]).
divide(Items,N,[Selected|Other]) :-
N > 1,
powset3(Items,Selected,Rest),
N1 is N-1,
divide(Rest,N1,Other).
个集合:
ziptogether/3
最后是一个ziptogether([],[],[]).
ziptogether([HA|TA],[HB|TB],[together(HA,HB)|TC]) :-
ziptogether(TA,TB,TC).
实用程序,它将两个列表压缩为谓词列表:
findall(I,item(I),Is),
findall(B,bag(B),Bs),
length(Bs,NB),
findall(Proposal,(divide(Is,NB,Ds),ziptogether(Bs,Ds,Proposal)),List).
你可以这样做:
?- findall(I,item(I),Is),
| findall(B,bag(B),Bs),
| length(Bs,NB),
| findall(Proposal,(divide(Is,NB,Ds),ziptogether(Bs,Ds,Proposal)),List).
Is = [i1, i2, i3, i4],
Bs = [b1, b2],
NB = 2,
List = [[together(b1, []), together(b2, [i1, i2, i3, i4])], [together(b1, [i4]), together(b2, [i1, i2, i3])], [together(b1, [i3]), together(b2, [i1, i2, i4])], [together(b1, [i3, i4]), together(b2, [i1, i2])], [together(b1, [i2]), together(b2, [i1|...])], [together(b1, [i2|...]), together(b2, [...|...])], [together(b1, [...|...]), together(..., ...)], [together(..., ...)|...], [...|...]|...].
示例:强>
findall
懒人版:
使用getBagConfig(Proposal) :-
findall(I,item(I),Is),
findall(B,bag(B),Bs),
length(Bs,NB),
divide(Is,NB,Ds),
ziptogether(Bs,Ds,Proposal).
的先前版本活动:它会生成整个配置列表。在许多情况下,延迟评估更好:它使一个人能够生成有限数量的实例。懒惰的版本是:
{{1}}
时间复杂度: 算法在O(b ^ n + b + n)中运行,其中b为二进制数,n为二进制数,n为项数。< / em>的
注意: 很可能一些引入的谓词已经存在于很多Prolog实现中,但由于这些谓词不是标准化的,因此最好自己提供一个实现。