2016-05-28 11 views
2

Ich versuche, einen Teil meiner Funktion in Matlab in C++ mit Coder zu konvertieren. Coder unterstützt die Funktion perms nicht. Ich verwende ausgiebig perms in meinem Code. Nachdem ich online geschaut habe, habe ich einige Vorschläge gefunden, wie man eine Liste aller Permutationen ohne perms erzeugen kann, aber es wird "von Hand" gemacht, was bedeutet, dass für Permutationen mit 3 Elementen wir drei for Schleifen haben, mit 4 Elementen haben wir 4 Schleifen usw.Nicht-rekursive Implementierung von Dauerwellen in Matlab, kompatibel mit Coder

Beispiel für 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 

für 8 Elemente würde ich 8 für Schleifen schreiben hat, irgendwelche Vorschläge, wie ich dies für n Elemente umwandeln kann? So etwas wie

for i=n:-1:1 
    I=[1:n] ; 
    for j=1:i 
     J=I(find(I~=j)); 

... ? 


thank you 
+3

[ 'std :: next_permutation'] (http://en.cppreference.com/w/cpp/algorithm/next_permutation) – 101010

+1

@ 101010, das ist nicht hilfreich, da OP nicht um den Code zu C++ übersetzen selbst. Er stützt sich dabei auf Matlab Coder, was bedeutet, dass er nur die Matlab-Funktionen verwenden muss, die übersetzt werden können. –

Antwort

5

Das Problem hierbei ist, dass perms Rekursion verwendet, die eine der Sprachfunktionen, die Matlab-Coder nicht unterstützt. Was wir also tun müssen, ist eine Implementierung, die nicht rekursiv ist.

Interessanterweise war perms vor Matlab 6.0 rekursiv, dann nicht rekursiv und dann wieder rekursiv. Anstatt also das Rad zu erfinden, können wir einfach eine der vorherigen nicht-rekursiven Revisionen, z.B. 1.10.

Beachten Sie, dass die Reihenfolge der Permutationen unterschiedlich ist, aber Sie sollten sich in Ihrem Code sowieso nicht darauf verlassen. Möglicherweise müssen Sie den Namen ändern, um den Konflikt mit der systemeigenen perms-Funktion zu vermeiden. Getestet mit coder.screener, die bestätigt, dass Coder es unterstützt.

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