有没有一种简单的方法可以获得集合的前x个排列?
例如,具有5个字符{a,b,c,d,e}的集合将具有
5 * 5 * 5 * 5 * 5 = 3125排列输出
(允许重复,例如{a,a,a,a,a})
但我想只有前100个值,例如
答案 0 :(得分:2)
您可以使用WHERE
获取集合P = perms(S)
的所有排列,然后如果您想要100,则可以S
。
对于随机,您可以使用P(1:100,:)
。
如果您知道需要更具体地说明排列,那么您可以将P(randperm(size(P,1),100),:)
与permute
参数一起使用 - http://uk.mathworks.com/help/matlab/ref/permute.html
答案 1 :(得分:2)
生成所有排列的一种方法'当时按字典顺序排列,不必将它们全部存储在记忆中:
function permute_chars(alphabet, nword, nmax)
if nargin < 3 % default to displaying all, this can be a huge number!
nmax = nchar^nword;
end
nchar = length(alphabet);
ind = zeros(1, nword);
i = 0;
while i < nmax
% just printing the permutaions, edit according to your needs
disp(cell2mat(alphabet(ind + 1)));
% calculate next indices, classic elementary school addition with carry
ind(end) = ind(end) + 1;
for j = nword:-1:2
if ind(j) == nchar
ind(j) = 0; % wrap around
ind(j-1) = ind(j-1) + 1; % carry
end
end
i = i + 1;
end
当然,我忘记了一些不起眼的功能,它可以用更少的行来实现它,但是这样写的很清楚它是如何工作的。快速测试:
>> alphabet = {'a', 'b', 'c', 'd', 'e'};
>> permute_chars(alphabet, 1)
a
b
c
d
e
>> permute_chars(alphabet, 2)
aa
ab
ac
ad
ae
ba
[... snip ...]
ed
ee
仅打印有限数量的排列:
>> permute_chars(alphabet, 5, 8)
aaaaa
aaaab
aaaac
aaaad
aaaae
aaaba
aaabb
aaabc
答案 2 :(得分:1)
要从数字1:n
中选择100个随机唯一样本,并允许重复(替换采样),您可以使用randi
或类似内容创建超过100 x n
的列表随机样本,unique
删除重复项,然后取前100个。
例如,使用randi
:
% from numbers 1:n, create 200 by n random matrix
sample_list = randi(n,[200, n]);
% remove duplicates
sample_list = unique(sample_list,'rows');
% you should probably error check here
% presuming there's >100 options left, take 100 of them
sample_list = sample_list(1:100,:);
sample_list
将是一个数字矩阵,但如果需要,您可以轻松地将其用作其他内容的索引:
my_set = {'a','b','c','d','e'}; % 1 x 5 cell
my_permutes = my_set(sample_list); % 100 x 5 cell
这避免了必须计算每一个可能的选项,对于较大的n
,这会成为问题。
答案 3 :(得分:1)
为了在您获得的排列范围内更灵活一些,您可以使用一个函数,在给定排列的情况下,该函数会在该系列中生成下一个排列。在这个实现中,即使输入排列超出范围,我也选择让排列回绕到第一个排列。
function newperm = nextPerm(oldperm, base)
if any(oldperm >= base)
newperm = zeros(1,numel(oldperm));
return
end
idx = numel(oldperm);
newperm = oldperm;
while idx > 0
newperm(idx) = newperm(idx) + 1;
if newperm(idx) < base
return;
end
newperm(idx) = 0;
idx = idx - 1;
end
end
排列元素从0开始(因此max元素是base-1)。
p = [4 4 4 4 4]
nextPerm(p, 5)
ans =
0 0 0 0 0
p = [0 0 0 0 0]
nextPerm(p, 5)
ans =
0 0 0 0 1
p = [3 4 1 0 2]
nextPerm(p, 5)
ans =
3 4 1 0 3
p = [3 4 5 0 2] %// invalid value '5'
nextPerm(p, 5)
ans =
0 0 0 0 0
要获得范围,只需通过循环输入:
myPerms = zeros(5);
myPerms(1,:) = [3 1 2 0 4];
for k = 2:5
myPerms(k,:) = nextPerm(myPerms(k-1,:), size(myPerms,1));
end
myPerms =
3 1 2 0 4
3 1 2 1 0
3 1 2 1 1
3 1 2 1 2
3 1 2 1 3
要将排列映射到您的字母表,只需将1添加到向量并将其用作索引:
alphabet = ['a', 'b', 'c', 'd', 'e'];
word = alphabet(myPerms(1,:)+1)
word = dbcae