有没有简单方式实现类似python random.choice的方式,谢谢,谢谢
随机抽取数组的元素,随机数的办法在数组比较小的时候,总是有截断误差,没法均匀抽取
参考 https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle 风平老涡 发表于 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 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 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
布衣龙共 发表于 2021-1-12 14:59
Module random_choice_FYS
implicit none
integer,parameter,private :: kq ...
学习了,非常感谢
页:
[1]