pazza 发表于 2021-1-11 22:16:06

有没有简单方式实现类似python random.choice的方式,谢谢,谢谢

随机抽取数组的元素,

随机数的办法在数组比较小的时候,总是有截断误差,没法均匀抽取


风平老涡 发表于 2021-1-12 03:26:53

参考 https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

pazza 发表于 2021-1-12 10:33:08

风平老涡 发表于 2021-1-12 03:26
参考 https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

谢谢指点,

step1:生成从0到所剩元素个数之间的随机数k;
step2:将第 k 个数取出,并最后一个剩余元素与取出的元素交换,然后剩余元素的数量减一
step3:重复step1,step2,直至所有元素均取出
通过将取出元素与剩余的最后一个元素交换,总是可以保证生成随机数k所对应位置的元素时尚未取出的。同样可以保证元素的取出是服从均匀分布,且算法的时间复杂度为O(n)。

这个算法时间复杂度O(N),非常好

但是,以我有限的fortran知识,感觉只借助数组和指针的情况下,
还是没法解决我的问题。

step1:生成从0到所剩元素个数之间的随机数k;

这一步还是会碰到我的问题,实现不了N*random_num(x)刚好严格覆盖【1,N】






pazza 发表于 2021-1-12 11:37:12

本帖最后由 pazza 于 2021-1-12 13:01 编辑

pazza 发表于 2021-1-12 10:33
谢谢指点,

step1:生成从0到所剩元素个数之间的随机数k;

生成pp的问题

! ****************************************************************************************** !
Module random_choice_FYS
    use prec
    IMPLICIT NONE   


    Integer,allocatable,Target :: pos_tmp(:)
    Integer,Pointer :: posp(:)

    contains
!-------------------------------------------------------------------
!-------------------------------------------------------------------
Subroutine choice_FYS(NL,N,L,num,p,i,j)
    Integer,intent(IN) :: NL,N,L,num
    Integer,intent(INOUT) :: p
    Integer,intent(OUT) :: i,j
    Integer :: pp,tmp
    Real(kq) :: KK
!------------------------------------------------------------------


    call random_number(KK); pp=Int(KK*(NL-p-1) +1)

    if ((p < num))Then
      p=p+1      
      i = int(pp/L)
      j = mod(pp,L)

      tmp = posp(NL-p+1)
      posp(NL-p+1) = posp(pp)
      posp(pp) = tmp
    else
      return
    endif
    !---------------------------
    Return
End subroutine choice_FYS
!-------------------------------------------------------------------
!-------------------------------------------------------------------
End Module random_choice_FYS
!***************************************************************************

布衣龙共 发表于 2021-1-12 14:59:27

本帖最后由 布衣龙共 于 2021-1-12 15:04 编辑

Module random_choice_FYS
implicit none
integer,parameter,private :: kq = 4
contains

Subroutine choice_FYS(x,y)
    Integer :: x(:)
    Integer,intent(INOUT) :: y(:)
    integer:: m , p , j
    real(kq) :: KK
    m = size(x)
    Do j = 1 , size(y)
      call random_number(KK)
      p=Int(KK*M)+1
      if (p < m) x() = x()
      y(j) = x(m)
      m = m - 1
    End Do
End subroutine choice_FYS

End Module random_choice_FYS

Program Main
use random_choice_FYS
integer :: x(6) =
integer :: y(3)
call random_seed()
call choice_FYS(x,y)
write(*,*) y
write(*,*) x
End Program Main

pazza 发表于 2021-1-12 19:13:34

布衣龙共 发表于 2021-1-12 14:59
Module random_choice_FYS
implicit none
integer,parameter,private :: kq ...

学习了,非常感谢
页: [1]
查看完整版本: 有没有简单方式实现类似python random.choice的方式,谢谢,谢谢