c++ - Matlab中perms的非递归实现,兼容Coder

标签 c++ matlab permutation matlab-coder perms

我正在尝试使用编码器将 matlab 中的部分函数转换为 C++。 Coder 不支持perms 函数。我在代码中广泛使用perms。在网上查看后,我发现了一些关于如何在没有 perms 的情况下生成所有排列列表的建议,但它是“手动”完成的,这意味着对于具有 3 个元素的排列,我们有 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

请注意,排列的顺序是不同的,但无论如何您都不应该在代码中依赖它。您可能需要更改名称以避免与 native 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

关于c++ - Matlab中perms的非递归实现,兼容Coder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37504220/

相关文章:

C++ 数组指针 [] 或++

arrays - 数组操作——随机选择元素

matlab - 如何在 MATLAB 中使用 polyfitn 查找系数?

c++ - 我应该如何从 map<char, vector<char>> 生成所有可能的 map<char, char> 组合?

python - 重新排序簇号以实现正确对应

c++ - C++ 中的通知中心

c++ - 模板元编程 GCC 错误

c++ - 自定义 C++ boost::lambda 表达式帮助

MATLAB 如何保存图像?

java - JAVA中数组乘以数组