序言中列表中0和1的唯一组合

问题描述 投票:0回答:2

我有问题,因为我想生成列表的排列(在序言中),该列表包含n个零和24-n个无重复的数。我试过:findall(L, permutation(L,P), Bag),然后sort删除重复,但这会导致堆栈溢出。任何人都有有效的方法吗?

list prolog permutation non-repetitive
2个回答
0
投票

而不是考虑列表,而考虑二进制数。该列表的长度为24个元素。如果所有这些元素均为1,则我们有:

?- X is 0b111111111111111111111111.
X = 16777215.

事实上的标准谓词between/3可用于生成区间[0, 16777215]中的数字:

?- between(0, 16777215, N).
N = 0 ;
N = 1 ;
N = 2 ;
...

仅其中一些数字满足您的条件。因此,您将需要过滤/测试它们,然后将传递的数字转换为等效的二进制列表表示形式。


0
投票

按升序选择0到23之间的n个随机数。这些整数为您提供零的索引,并且所有配置都不同。关键是生成这些索引列表。

%
% We need N monotonically increasing integer numbers (to be used
% as indexes) from [From,To].
%

need_indexes(N,From,To,Sol) :-
   N>0,!,
   Delta is To-From+1,
   N=<Delta,                                % Still a change to generate them
   N_less is N-1,
   From_plus is From+1,
   (
      (need_indexes(N_less,From_plus,To,SubSol),Sol=[From|SubSol])    % From is selected      
      ;
      (N<Delta -> need_indexes(N,From_plus,To,Sol))                   % Alternatively, From is not selected
   ).

need_indexes(0,_,_,[]). 

现在我们可以从可用的可能的索引中获取索引列表。

例如:

给我5个索引,从0到23(含0:):

?- need_indexes(5,0,23,Collected).
Collected = [0, 1, 2, 3, 4] ;
Collected = [0, 1, 2, 3, 5] ;
Collected = [0, 1, 2, 3, 6] ;
Collected = [0, 1, 2, 3, 7] ;
...

全部给他们:

?- findall(Collected,need_indexes(5,0,23,Collected),L),length(L,LL).
L = [[0, 1, 2, 3, 4], [0, 1, 2, 3, 5], [0, 1, 2, 3, 6], [0, 1, 2, 3, 7], [0, 1, 2, 3|...], [0, 1, 2|...], [0, 1|...], [0|...], [...|...]|...],
LL = 42504.

我们期望:(24!/((24-5)!* 5!))解决方案。

确实:

?- L is 20*21*22*23*24 / (1*2*3*4*5).
L = 42504.

现在唯一的问题是将每个解决方案(如[0, 1, 2, 3, 4])转换为0和1的字符串。这留作练习!

© www.soinside.com 2019 - 2024. All rights reserved.