获取列表的第 i 个排列
Getting the ith permutation of a list
我需要一个 Fortran 代码来计算给定列表 {1,2,3,...,n} 的第 i 个排列,而不计算所有排列,即 n!。
有没有人可以帮助我?提前谢谢你。
我解决了我的问题。在下文中,我向您展示了我实现的 Mathematica 和 Fortran 代码。如果您有任何改进建议,请不要犹豫发表评论。
MATHEMATICA(示例:{1,2,3,4,5} 的 10° 排列)
n = 5;
i = 10;
p = Range[n];
ithPermutation = p;
Do[f = (n - k)!;
d = Floor[i/f];
ithPermutation[[k]] = p[[d + 1]];
p = Drop[p, {d + 1}];
i = Mod[i, f], {k, 1, n}];
FORTRAN
SUBROUTINE ith_permutazione(lista_iniziale,n,i,ith_permutation)
IMPLICIT NONE
INTEGER :: j,k,f
INTEGER, INTENT(IN) :: n,i
INTEGER, DIMENSION(1:n), INTENT(IN) :: lista_iniziale
INTEGER, DIMENSION(1:n) :: lista_lavoro
INTEGER, DIMENSION(1:n), INTENT(OUT) :: ith_permutation
lista_lavoro=lista_iniziale
j=i
DO k=1,n
f=factorial(n-k)
ith_permutation(k)=lista_lavoro(FLOOR(REAL(j/f))+1)
lista_lavoro=PACK(lista_lavoro,MASK=lista_lavoro/=ith_permutation(k))
j=MOD(j,f)
ENDDO
ENDSUBROUTINE ith_permutazione
对于大数字,以下实现防止溢出错误。
! Fattoriale
RECURSIVE FUNCTION factorial(n) RESULT(n_factorial)
IMPLICIT NONE
REAL, INTENT(IN) :: n
REAL :: n_factorial
IF(n>0) THEN
n_factorial=n*factorial(n-1)
ELSE
n_factorial=1
ENDIF
ENDFUNCTION factorial
! ith-permutazione di una lista
SUBROUTINE ith_permutazione(lista_iniziale,n,i,ith_permutation)
IMPLICIT NONE
INTEGER :: k,n
REAL :: j,f
REAL, INTENT(IN) :: i
INTEGER, DIMENSION(1:n), INTENT(IN) :: lista_iniziale
INTEGER, DIMENSION(1:n) :: lista_lavoro
INTEGER, DIMENSION(1:n), INTENT(OUT) :: ith_permutation
lista_lavoro=lista_iniziale
j=i
DO k=1,n
f=factorial(REAL(n-k))
ith_permutation(k)=lista_lavoro(FLOOR(j/f)+1)
lista_lavoro=PACK(lista_lavoro,MASK=lista_lavoro/=ith_permutation(k))
j=MOD(j,f)
ENDDO
ENDSUBROUTINE ith_permutazione
我需要一个 Fortran 代码来计算给定列表 {1,2,3,...,n} 的第 i 个排列,而不计算所有排列,即 n!。 有没有人可以帮助我?提前谢谢你。
我解决了我的问题。在下文中,我向您展示了我实现的 Mathematica 和 Fortran 代码。如果您有任何改进建议,请不要犹豫发表评论。
MATHEMATICA(示例:{1,2,3,4,5} 的 10° 排列)
n = 5;
i = 10;
p = Range[n];
ithPermutation = p;
Do[f = (n - k)!;
d = Floor[i/f];
ithPermutation[[k]] = p[[d + 1]];
p = Drop[p, {d + 1}];
i = Mod[i, f], {k, 1, n}];
FORTRAN
SUBROUTINE ith_permutazione(lista_iniziale,n,i,ith_permutation)
IMPLICIT NONE
INTEGER :: j,k,f
INTEGER, INTENT(IN) :: n,i
INTEGER, DIMENSION(1:n), INTENT(IN) :: lista_iniziale
INTEGER, DIMENSION(1:n) :: lista_lavoro
INTEGER, DIMENSION(1:n), INTENT(OUT) :: ith_permutation
lista_lavoro=lista_iniziale
j=i
DO k=1,n
f=factorial(n-k)
ith_permutation(k)=lista_lavoro(FLOOR(REAL(j/f))+1)
lista_lavoro=PACK(lista_lavoro,MASK=lista_lavoro/=ith_permutation(k))
j=MOD(j,f)
ENDDO
ENDSUBROUTINE ith_permutazione
对于大数字,以下实现防止溢出错误。
! Fattoriale
RECURSIVE FUNCTION factorial(n) RESULT(n_factorial)
IMPLICIT NONE
REAL, INTENT(IN) :: n
REAL :: n_factorial
IF(n>0) THEN
n_factorial=n*factorial(n-1)
ELSE
n_factorial=1
ENDIF
ENDFUNCTION factorial
! ith-permutazione di una lista
SUBROUTINE ith_permutazione(lista_iniziale,n,i,ith_permutation)
IMPLICIT NONE
INTEGER :: k,n
REAL :: j,f
REAL, INTENT(IN) :: i
INTEGER, DIMENSION(1:n), INTENT(IN) :: lista_iniziale
INTEGER, DIMENSION(1:n) :: lista_lavoro
INTEGER, DIMENSION(1:n), INTENT(OUT) :: ith_permutation
lista_lavoro=lista_iniziale
j=i
DO k=1,n
f=factorial(REAL(n-k))
ith_permutation(k)=lista_lavoro(FLOOR(j/f)+1)
lista_lavoro=PACK(lista_lavoro,MASK=lista_lavoro/=ith_permutation(k))
j=MOD(j,f)
ENDDO
ENDSUBROUTINE ith_permutazione