Andy1201 发表于 2024-3-26 21:09:44

random seed

INTEGER :: i_seed
INTEGER, DIMENSION(:), ALLOCATABLE :: a_seed
INTEGER, DIMENSION(1:8) :: dt_seed

CALL RANDOM_SEED(size=i_seed)
ALLOCATE(a_seed(1:i_seed))

CALL RANDOM_SEED(get=a_seed)
CALL DATE_AND_TIME(values=dt_seed)
a_seed(i_seed)=dt_seed(8); a_seed(1)=dt_seed(8)*dt_seed(7)*dt_seed(6)

CALL RANDOM_SEED(put=a_seed)

DEALLOCATE(a_seed)

CALL RANDOM_NUMBER(AmpValueNew)

主要问题是,CALL RANDOM_SEED(size=i_seed),疑惑的是,也没有对i_seed进行赋值,那么call random seed(size=i_seed),括号里面这是在干嘛,i_seed要是赋值了,可能是定义种子的尺寸大小,可是i_seed啥也木有,不知道是在干啥

第二个问题是,call date and time括号里面的内容也不是很明白
求助Fortran大神

fcode 发表于 2024-3-27 13:35:06

本站随机数教程
http://fcode.cn/guide-96-1.html

Andy1201 发表于 2024-3-28 20:56:11

fcode 发表于 2024-3-27 13:35
本站随机数教程
http://fcode.cn/guide-96-1.html

谢谢大神
但是还是有几个问题想向您请教

第一个问题是,不论是我关闭程序后重新打开,或者直接重新运行程序,call random seed(size=n)这个n值为什么一直是2?为什么不是一个任意正整数?

第二个问题是关于size,为什么需要获取种子的个数(size),种子按理说不是只需要1个就可以了嘛?

第三个问题更困惑,put是输入参数,那么将一个大小为size的数组传输给put,会用哪个新的种子?

fcode 发表于 2024-3-28 22:05:18

第一个问题:
call random_seed( size = n ) !// 获得种子大小
此处,random_seed 函数会给 n 赋值。在你的编译器上,是 2。(其他编译器不一定)
这个n一般对特定的编译器是固定值。

第二个问题:
种子的个数 n 可以不止一个,当然也可以是一个。对特定的编译器通常是固定的值。获取种子的个数是为了方便你分配数组。

第三个问题:
请把 n 大小的数组,视为一个整体。

    call random_seed( size = n ) !// 请问你需要几个数做为种子?好的,你需要 n 个种子是吧?
    allocate( sed(n) ) !// 让我来分配 n 个种子 sed
    sed = ...... !// 让我来生成 n 个种子 sed
    call random_seed( put=sed ) !// 好了,这是你需要的 n 个种子 sed,我现在交给你

Andy1201 发表于 2024-4-4 16:57:43

fcode 发表于 2024-3-28 22:05
第一个问题:
call random_seed( size = n ) !// 获得种子大小
此处,random_seed 函数会给 n 赋值。在你的 ...

明白了,谢谢大神

我还有一个关于随机数的小问题,虽然设置与时间相关的种子可以获得真正意义上的随机数,但当我需要同时产生大量的随机数,却会发现,由于计算机的计算时间较快,在最小的时间间隔内就会产生几十次运算,但这几十次运算却都依赖于同一个时间种子,以至于生成的随机数是重复几十次之后,直到下一个时间种子才能出现新的重复随机数,举个例子就是会产生0.5,0.5,0.5(重复几十次)0.7,0.7,0.7(重复几十次)

但是当我不使用与时间相关的种子,使用系统自带的种子,那么在同时产生大量的随机数过程中,每一个随机数是保证了不同,但是每一次重新生成的大量随机数与上一次生成的大量随机数是一样的。

总结下来就是,同时产生大量的随机数,如果使用与时间相关的种子,当前次与下一次生成的大量随机数不同,但是在次内生成的大量随机数会出现相同。而如果我不使用与时间相关的种子,次内生成的大量随机数会不相同,但当前次与下一次生成的大量随机数一一对应,是相同的。

所以想请问大神,有没有一种办法可以实现单次内大量随机数不同且每一次生成的随机数也互不相同,从而实现真正的随机,谢谢大神

fcode 发表于 2024-4-4 17:49:00

你是不是每次都设置了种子?
设置种子的函数,只需要在程序一开始调用一次。之后不要再次调用。
计算机获得种子之后,每次生成随机数都会为下一次随机做好准备,不再需要再次指定种子。(否则容易导致下一次的状态被重置)

Andy1201 发表于 2024-4-8 16:04:13

fcode 发表于 2024-4-4 17:49
你是不是每次都设置了种子?
设置种子的函数,只需要在程序一开始调用一次。之后不要再次调用。
计算机获得 ...

明白了,我确实在循环内部每次都调用了时间种子,将调用的时间种子放置在循环外部,应该会解决我的上述问题。谢谢大神的解答,万分感谢!!

Andy1201 发表于 2024-4-8 18:06:56

fcode 发表于 2024-4-4 17:49
你是不是每次都设置了种子?
设置种子的函数,只需要在程序一开始调用一次。之后不要再次调用。
计算机获得 ...

大神,我还有一个随机数的问题想向您请教

当我使用了implicit none,如果我紧跟着声明变量,再调用时间种子,程序没有任何问题,如下所示
Implicit None
    integer::amp
    real::ampvalue
    call RANDOM_SEED()
    do amp=1,1500
      Call RANDOM_NUMBER(ampvalue)
      print *,ampvalue
    end do

但是当我使用了implicit none后,我紧跟着调用时间种子,再去声明变量程序编译就有问题,如下所示
Implicit None
    call RANDOM_SEED()
    integer::amp
    real::ampvalue
    do amp=1,1500
      Call RANDOM_NUMBER(ampvalue)
      print *,ampvalue
    end do

那么,出现这个问题的原因,难道是因为当我使用了Implicit none之后,必须紧跟着声明变量类型,而不能进行其他操作导致的,还是与随机数调用程序有关呢?

谢谢大神之前的解答!

fcode 发表于 2024-4-8 20:56:31

和随机数无关。
fortran的执行语句必须在所有定义语句的后面。
call RANDOM_SEED() 是执行语句,integer::amp 是定义语句。
改成
Implicit None
    integer::amp
    real::ampvalue
    call RANDOM_SEED()
    do amp=1,1500
      Call RANDOM_NUMBER(ampvalue)
      print *,ampvalue
    end do
就行了。

Andy1201 发表于 2024-4-10 16:47:58

fcode 发表于 2024-4-8 20:56
和随机数无关。
fortran的执行语句必须在所有定义语句的后面。
call RANDOM_SEED() 是执行语句,integer:: ...

明白了,谢谢大神吖,我还有两个小问题想向您请教

第一个问题是:call random number生成的随机数是0-1均匀分布的随机数,那么这个均匀分布的随机数端部0或1是可以生成的嘛还是只能在其之间?换句话说,生成的随机数是在闭区间还是开区间里面呢?

第二个问题是:如果我在Fortran中想生成一组已知均值和标准差的符合正态分布的随机数组,那么该如何进行操作呢?网站上贴出的生成正态分布随机数的代码原理是什么呢?

谢谢大神之前的回答!!
页: [1] 2
查看完整版本: random seed