matlab中perms的非递归实现,兼容Coder
Non-recursive implementation of perms in Matlab, compatible with Coder
我正在尝试使用编码器将我在 matlab 中的部分函数转换为 C++。 Coder 不支持函数 perms
。我在我的代码中广泛使用 perms
。在线查看后,我发现很少有关于如何在没有 perms
的情况下生成所有排列列表的建议,但它已完成 "by hand",这意味着对于具有 3 个元素的排列,我们有三个 for 循环,我们有 4 个元素4 个循环等
1:4
示例:
row = 1;
n=a;
Z = zeros(factorial(n),n);
idxarray1=[1:4];
for idx=idxarray1
idxarray2=idxarray1(find(idxarray1~=idx)) ;
for jdx=idxarray2
idxarray3=idxarray2(find(idxarray2~=jdx));
for kdx=idxarray3
idxarray4=idxarray3(find(idxarray3~=kdx)) ;
for mdx=idxarray4
Z(row,:) = [idx,jdx,kdx,mdx];
row = row + 1 ;
end
end
end
end
对于 8 个元素,我必须编写 8 个 for 循环,关于如何将其转换为 n 个元素的任何建议?像
for i=n:-1:1
I=[1:n] ;
for j=1:i
J=I(find(I~=j));
... ?
thank you
这里的问题是perms
使用递归,这是Matlab Coder不支持的语言特性之一。所以我们需要做的是想出一个非递归的实现。
有意思的是,perms
在Matlab 6.0之前是递归的,然后是非递归的,然后又是递归的。因此,与其发明轮子,我们可以只采用以前的非递归修订之一,例如1.10
.
请注意,排列的顺序不同,但无论如何您都不应该在代码中依赖它。您可能需要更改名称以避免与本机 perms
函数冲突。使用 coder.screener
进行测试,确认 Coder 支持它。
function P = perms(V)
%PERMS All possible permutations.
% PERMS(1:N), or PERMS(V) where V is a vector of length N, creates a
% matrix with N! rows and N columns containing all possible
% permutations of the N elements.
%
% This function is only practical for situations where N is less
% than about 10 (for N=11, the output takes over 3 giga-bytes).
%
% See also NCHOOSEK, RANDPERM, PERMUTE.
% ZP. You, 1-18-99
% Copyright 1984-2000 The MathWorks, Inc.
% $Revision: 1.10 $ $Date: 2000/06/16 17:00:47 $
V = V(:)';
n = length(V);
if n == 0
P = [];
else
c = cumprod(1:n);
cn = c(n);
P = V(ones(cn,1),:);
for i = 1:n-1; % for column 1 to n-1, switch oldidx entry with newidx entry
% compute oldidx
j = n-i;
k = (n-j-1)*cn;
oldidx = (c(j)+1+k:c(j+1)+k)';
% spread oldidx and newidx over corresponding rows
for k = j+1:n-1
q = 0:c(k):k*c(k);
shift = q(ones(length(oldidx),1),:);
oldidx = oldidx(:,ones(1,k+1));
oldidx = oldidx(:)+shift(:);
end
% compute newidx
colidx = cn:cn:j*cn;
colidx = colidx(ones(c(j),1),:);
colidx = colidx(:);
colidx = colidx(:,ones(1,length(oldidx)/(j*c(j))));
newidx = oldidx + colidx(:);
% do the swap
q = P(newidx);
P(newidx)=P(oldidx);
P(oldidx)=q;
end
end
我正在尝试使用编码器将我在 matlab 中的部分函数转换为 C++。 Coder 不支持函数 perms
。我在我的代码中广泛使用 perms
。在线查看后,我发现很少有关于如何在没有 perms
的情况下生成所有排列列表的建议,但它已完成 "by hand",这意味着对于具有 3 个元素的排列,我们有三个 for 循环,我们有 4 个元素4 个循环等
1:4
示例:
row = 1;
n=a;
Z = zeros(factorial(n),n);
idxarray1=[1:4];
for idx=idxarray1
idxarray2=idxarray1(find(idxarray1~=idx)) ;
for jdx=idxarray2
idxarray3=idxarray2(find(idxarray2~=jdx));
for kdx=idxarray3
idxarray4=idxarray3(find(idxarray3~=kdx)) ;
for mdx=idxarray4
Z(row,:) = [idx,jdx,kdx,mdx];
row = row + 1 ;
end
end
end
end
对于 8 个元素,我必须编写 8 个 for 循环,关于如何将其转换为 n 个元素的任何建议?像
for i=n:-1:1
I=[1:n] ;
for j=1:i
J=I(find(I~=j));
... ?
thank you
这里的问题是perms
使用递归,这是Matlab Coder不支持的语言特性之一。所以我们需要做的是想出一个非递归的实现。
有意思的是,perms
在Matlab 6.0之前是递归的,然后是非递归的,然后又是递归的。因此,与其发明轮子,我们可以只采用以前的非递归修订之一,例如1.10
.
请注意,排列的顺序不同,但无论如何您都不应该在代码中依赖它。您可能需要更改名称以避免与本机 perms
函数冲突。使用 coder.screener
进行测试,确认 Coder 支持它。
function P = perms(V)
%PERMS All possible permutations.
% PERMS(1:N), or PERMS(V) where V is a vector of length N, creates a
% matrix with N! rows and N columns containing all possible
% permutations of the N elements.
%
% This function is only practical for situations where N is less
% than about 10 (for N=11, the output takes over 3 giga-bytes).
%
% See also NCHOOSEK, RANDPERM, PERMUTE.
% ZP. You, 1-18-99
% Copyright 1984-2000 The MathWorks, Inc.
% $Revision: 1.10 $ $Date: 2000/06/16 17:00:47 $
V = V(:)';
n = length(V);
if n == 0
P = [];
else
c = cumprod(1:n);
cn = c(n);
P = V(ones(cn,1),:);
for i = 1:n-1; % for column 1 to n-1, switch oldidx entry with newidx entry
% compute oldidx
j = n-i;
k = (n-j-1)*cn;
oldidx = (c(j)+1+k:c(j+1)+k)';
% spread oldidx and newidx over corresponding rows
for k = j+1:n-1
q = 0:c(k):k*c(k);
shift = q(ones(length(oldidx),1),:);
oldidx = oldidx(:,ones(1,k+1));
oldidx = oldidx(:)+shift(:);
end
% compute newidx
colidx = cn:cn:j*cn;
colidx = colidx(ones(c(j),1),:);
colidx = colidx(:);
colidx = colidx(:,ones(1,length(oldidx)/(j*c(j))));
newidx = oldidx + colidx(:);
% do the swap
q = P(newidx);
P(newidx)=P(oldidx);
P(oldidx)=q;
end
end