列出列表序言的所有组合
我想在 Prolog 中编写一个谓词,显示 N
元素列表与恰好 M
“黑色元素”(b
为黑色,w
表示白色)。
示例查询:
?- combination(3, 2, L).
L = [b, b, w] ;
L = [b, w, b] ;
L = [w, b, b] ;
false.
我已经写了这个:
combination(0, _, []).
combination(Nn, 0, [w|L]) :-
NN1 is Nn-1,
combination(NN1, 0, L).
combination(Nn, N, [b|L]) :-
N1 is N-1,
NN1 is Nn-1,
combination(NN1, N1, L).
combination(Nn, N, [w|L]) :-
NN1 is Nn-1,
combination(NN1, N, L).
返回第一个组合 (L = [b, b, w]
),但它不显示其他可能性。另外,它有一个无限循环,我不明白为什么。这是痕迹:
[trace] ?- combination(3, 2, L).
Call: (10) combination(3, 2, _2900) ? creep
Call: (11) _4108 is 2+ -1 ? creep
Exit: (11) 1 is 2+ -1 ? creep
Call: (11) _5624 is 3+ -1 ? creep
Exit: (11) 2 is 3+ -1 ? creep
Call: (11) combination(2, 1, _4100) ? creep
Call: (12) _7904 is 1+ -1 ? creep
Exit: (12) 0 is 1+ -1 ? creep
Call: (12) _9420 is 2+ -1 ? creep
Exit: (12) 1 is 2+ -1 ? creep
Call: (12) combination(1, 0, _7896) ? creep
Call: (13) _11700 is 1+ -1 ? creep
Exit: (13) 0 is 1+ -1 ? creep
Call: (13) combination(0, 0, _11692) ? creep
Exit: (13) combination(0, 0, []) ? creep
Exit: (12) combination(1, 0, [w]) ? creep
Exit: (11) combination(2, 1, [b, w]) ? creep
Exit: (10) combination(3, 2, [b, b, w]) ? creep
L = [b, b, w] ;
Redo: (13) combination(0, 0, _11692) ? creep
Call: (14) _19114 is 0+ -1 ? creep
Exit: (14) -1 is 0+ -1 ? creep
Call: (14) combination(-1, 0, _19106) ? creep
Call: (15) _21394 is -1+ -1 ? creep
Exit: (15) -2 is -1+ -1 ? creep
感谢您的帮助。
I want to write in Prolog a predicate that display all the combinations of a list of N
elements with exactly M
"black elements" (b
for black and w
for white).
Sample query:
?- combination(3, 2, L).
L = [b, b, w] ;
L = [b, w, b] ;
L = [w, b, b] ;
false.
I've written this:
combination(0, _, []).
combination(Nn, 0, [w|L]) :-
NN1 is Nn-1,
combination(NN1, 0, L).
combination(Nn, N, [b|L]) :-
N1 is N-1,
NN1 is Nn-1,
combination(NN1, N1, L).
combination(Nn, N, [w|L]) :-
NN1 is Nn-1,
combination(NN1, N, L).
that returns me the first combination (L = [b, b, w]
), but it don't display other possibilities. Also, it has an infinite loop, I don't understand why. Here is the trace:
[trace] ?- combination(3, 2, L).
Call: (10) combination(3, 2, _2900) ? creep
Call: (11) _4108 is 2+ -1 ? creep
Exit: (11) 1 is 2+ -1 ? creep
Call: (11) _5624 is 3+ -1 ? creep
Exit: (11) 2 is 3+ -1 ? creep
Call: (11) combination(2, 1, _4100) ? creep
Call: (12) _7904 is 1+ -1 ? creep
Exit: (12) 0 is 1+ -1 ? creep
Call: (12) _9420 is 2+ -1 ? creep
Exit: (12) 1 is 2+ -1 ? creep
Call: (12) combination(1, 0, _7896) ? creep
Call: (13) _11700 is 1+ -1 ? creep
Exit: (13) 0 is 1+ -1 ? creep
Call: (13) combination(0, 0, _11692) ? creep
Exit: (13) combination(0, 0, []) ? creep
Exit: (12) combination(1, 0, [w]) ? creep
Exit: (11) combination(2, 1, [b, w]) ? creep
Exit: (10) combination(3, 2, [b, b, w]) ? creep
L = [b, b, w] ;
Redo: (13) combination(0, 0, _11692) ? creep
Call: (14) _19114 is 0+ -1 ? creep
Exit: (14) -1 is 0+ -1 ? creep
Call: (14) combination(-1, 0, _19106) ? creep
Call: (15) _21394 is -1+ -1 ? creep
Exit: (15) -2 is -1+ -1 ? creep
Thanks for your help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
只需将颜色映射
black
和白色
到零附近的小非阴性整数,我们可以大大减少了我们的实施工作 - 使用有限域约束:
首先,我们绘制四个值,
1
:接下来,我们再次绘制四个值, at大多数两次
1
:最后,我们再次绘制四个值,至少两次
1
:Simply by mapping the colors
black
andwhite
to small non-negative integers around zero, we cangreatly reduce our implementation effort—by using finite domain constraints:
First, we draw four values, exactly two times
1
:Next, we again draw four values, at most two times
1
:Last, we again draw four values, at least two times
1
:您需要对表示元素数量 (
N
) 和黑色元素数量 (B) 的变量值进行额外约束代码>)。
示例:
You need additional constraints on the values of the variables denoting number of elements (
N
) and number of black elements (B
).Examples: