回 帖 发 新 帖 刷新版面

主题:给定数字1~n,输出从中选出m(m<n)个数的排列组合

如题,谁能给出一个fortran编写的代码?

回复列表 (共7个回复)

沙发

楼主是否纠结与算法? n太大计算中怕溢出?

板凳

Reference: Richard A. Brualdi -- Introductory Combinatrorics --> Generating Permutations and Combinations.

2010 年 12 月 06 号 22:12 修改如下:
好人做到底,给出代码,参考文件见上。
! GeneratingSubset.f90
!
! Written by Zeng Zhuo-Quan
!
! Date: 2010 - 12 - 06
!

Module Generating_Subset
  implicit none
  
contains
  ! M-subset of {1, 2, 3, ..., N} in lexicographic order
  ! algorithm:
  ! Begin with the M-subset IA(1 : M) = (/1, 2, 3, ..., M/)
  ! While IA(1 : M) /= (/N - M + 1, N - M + 2, ..., M/)
  ! Determine the largest integer k such that IA(k) + 1 <= n
  !   and IA(k) + 1 is not one of IA(k + 1 : M)
  ! Replace IA(1 : M) with the M-subset
  !   IA(1), IA(2), ..., IA(k - 1), (IA(k) + 1), (IA(k) + 2), 
  !   ..., (IA(k) + M - k + 1)
  subroutine GeneratingSubset()
    implicit none
    integer, parameter:: N = 8;
    integer, parameter:: M = 5;
    integer:: IA(M), IB(M)   ! M-Subset
    integer:: IX(M)
    integer:: i, j   ! for loop
    character(len = 10):: fmt_str
    
    forall ( i = 1 : M : 1 )
      IX(i) = N - M + i
      IA(i) = i
    end forall
    
    open(unit = 6, file = "GeneratingSubset.txt")
    fmt_str = "(??I3)"
    write(unit = fmt_str(2 : 3), fmt = "(I2)") M
    j = 1
    do while ( any(IA /= IX) )
      write(unit = 6, fmt = fmt_str) IA    
      call Next_Subset(N, M, IA, IB)
      IA = IB
      j = j + 1
    end do   ! i
    write(unit = 6, fmt = fmt_str) IX
    write(unit = *, fmt = *) j, "-subset"
    close( unit = 6 )
     
    return
  end subroutine



  ! lexico-graphic order
  subroutine Next_Subset(N, M, IA, IB)
    implicit none
    integer, intent(in):: N 
    integer, intent(in):: M   ! M-Subset of N element set  
    integer, intent(in):: IA(M)
    integer, intent(out):: IB(M)    

    ! *** *** *** *** *** intermediate variable *** *** *** *** ***
    integer:: k
    integer:: i, j   ! for loop
    logical:: TF
    
    do i = M, 1, -1
      k = IA(i) + 1
      TF = (k <= N)
      if ( TF ) then
        do j = i + 1, M, 1
          if ( k == IA(j) ) then
            TF = .false.
          end if
        end do   ! j
      end if   ! TF
      if ( TF ) then
        k = i
        exit 
      end if   ! TF
    end do   ! i
    
    IB(1 : (k - 1)) = IA(1 : (k - 1))
    IB(k) = IA(k) + 1
    do i = k + 1, M, 1
      IB(i) = IB(i - 1) + 1
    end do   ! i

    return
  end subroutine
  
End Module

3 楼

什么意思?

4 楼

[quote]楼主是否纠结与算法? n太大计算中怕溢出?[/quote]


用Fortran递归,对于N=10,M=3怎么就像死机一样?有没有高效的算法?

5 楼

只能用遞歸或是類似的窮舉法,內存不會太費,整合一個結果就輸出一個。

6 楼

我很少用递归算法,效率太低。
Donald E. Knuth - The Art Of Computer Programming (Vol 4)
这本书上有不少算法,讨论很详细,阁下可以参考。

7 楼

[quote][quote]楼主是否纠结与算法? n太大计算中怕溢出?[/quote]


用Fortran递归,对于N=10,M=3怎么就像死机一样?有没有高效的算法?[/quote]
理论上说,递归都可以改成循环

我来回复

您尚未登录,请登录后再回复。点此登录或注册