function [ a_new, more_new ] = derange_back_next ( n, a, more ) %*****************************************************************************80 % %% DERANGE_BACK_NEXT returns the next derangement of N items. % % Discussion: % % A derangement of N objects is a permutation which leaves no object % unchanged. % % A derangement of N objects is a permutation with no fixed % points. If we symbolize the permutation operation by "P", % then for a derangment, P(I) is never equal to I. % % The number of derangements of N objects is sometimes called % the subfactorial function, or the derangement number D(N). % % This routine uses backtracking. % % Licensing: % % This code is distributed under the GNU LGPL license. % % Modified: % % 30 July 2004 % % Author: % % John Burkardt % % Parameters: % % Input, integer N, the number of items to be deranged. % % Input, integer A(N), the output value of A_NEW from the previous call. % On first call with MORE = FALSE, the input value of A is not important. % % Input, logical MORE, should be set to FALSE on the first call, to force % initialization, and should be TRUE thereafter. % % Output, integer A_NEW(N), contains the next derangement, if MORE_NEW is TRUE. % % Output, logical MORE_NEW, is TRUE if another derangement was found, and % FALSE if there are no more derangements to return. % persistent indx; persistent k; persistent maxstack; persistent nstack; persistent stack; persistent ncan; more_new = more; if ( ~more_new ) a_new(1:n) = 0; if ( n < 2 ) more_new = 0; return end indx = 0; k = 0; maxstack = floor ( ( n * ( n + 1 ) ) / 2 ); nstack = 0; stack(1:maxstack) = 0; ncan(1:n) = 0; more_new = 1; else a_new(1:n) = a(1:n); end while ( 1 ) [ a_new, indx, k, nstack, ncan ] = i4vec_backtrack ( ... n, maxstack, stack, a_new, indx, k, nstack, ncan ); if ( indx == 1 ) break; elseif ( indx == 2 ) [ nstack, stack, ncan ] = derange_back_candidate ( n, a_new, k, nstack, ... stack, ncan ); else more_new = 0; break; end end return end