狼跃冲顶 发表于 2007-12-14 16:10

fortran如何生成【0,1】区间均匀分布的随机数?

fortran如何生成【0,1】区间均匀分布的随机数?
用vf6.5的话是不是有一个库函数可以调用?
是什么呢?
如果编程采用什么方法呢?
谢谢朋友们!

ssg1983 发表于 2007-12-21 17:13

REAL FUNCTION NRND1(R)
        DOUBLE PRECISION S,U,V,R
        S=65536.0
        U=2053.0
        V=13849.0
        M=R/S
        R=R-M*S
        R=U*R+V
        M=R/S
        R=R-M*S
        NRND1=R/S
        RETURN
        END

风花雪月 发表于 2007-12-24 11:01

看看fortran的帮助:

SEED
Run-Time Subroutine: Changes the starting point of the pseudorandom number generator.

Module: USE DFLIB

Syntax

CALL SEED (iseed)

iseed
(Input) INTEGER(4). Starting point for RANDOM.
SEED uses iseed to establish the starting point of the pseudorandomnumber generator. A given seed always produces the same sequence ofvalues from RANDOM.

If SEED is not called before the first call to RANDOM, RANDOMalways begins with a seed value of one. If a program must have adifferent pseudorandom sequence each time it runs, pass the constantRND$TIMESEED (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory)to the SEED routine before the first call to RANDOM.

风花雪月 发表于 2007-12-24 11:03

random返回的是个伪随机数,并不是真正的随机。

这个不仅fortran如此,vb也是一样的。

如果要实行随机数,在调用random之前应该先调用seed,就是先给random函数一个随机种子,这个随机种子一般是和cpu时间有关系,这样就可以实行随机功能了。

!***********************************
! Revision By: lu_zhaoshi@hotmail.com
! Revised on 2006-3-31 9:18:11
! Comments: ...
!***********************************!
program my_random
USE DFLIB
CALL SEED(RND$TIMESEED)
CALL RANDOM(rand)
print *, rand
end program my_random

狼跃冲顶 发表于 2008-1-6 16:15

谢谢 风花雪月
这个方法不错 而且可以循环产生

ant008 发表于 2008-1-29 17:34

也只能产生伪随机数吧

风花雪月 发表于 2008-2-19 16:19

原帖由 ant008 于 2008-1-29 17:34 发表 http://www.chinavib.com/forum/images/common/back.gif
也只能产生伪随机数吧

上面已经说过了,random生成的是伪随机数,真正的随机数是做不到的

linqus 发表于 2009-2-26 21:10

原帖由 风花雪月 于 2007-12-24 11:03 发表 http://www.chinavib.com/forum/images/common/back.gif
random返回的是个伪随机数,并不是真正的随机。

这个不仅fortran如此,vb也是一样的。

如果要实行随机数,在调用random之前应该先调用seed,就是先给random函数一个随机种子,这个随机种子一般是和cpu时间有关 ...


即便是调用了seed了,还是不行,

!CALL RANDOM_SEED()
!系统根据日期和时间随机地提供种子


最近在做一个小程序,

DO I=1,N1,1
   .....
   DO J=1,N2,1
      .....
      DO K=1,N1,1
         .....
      CALL RANDOM_SEED()
      CALL RANDOM_NUMBER(RANDTEMP)
         Z=randtemp
         ......
       ENDDO
    ENDDO
ENDDO

由于在k层循环时,计算时间很快,系统时间没法反映到CALL RANDOM_SEED()上吧(猜测)
生成的随机数即便一样。

做一个简单的小程序便知了:
PROGRAM ZZ
USE IMSL
USE DFLIB
USE RG
IMPLICIT NONE
REAL(KIND=8)::X(3)
INTEGER(KIND=8)::I,J
REAL(KIND=8),EXTERNAL::RAN1
DO I=1,5,1
CALL RANDOM_SEED()
!ϵͳ¸ù¾ÝÈÕÆÚºÍʱ¼äËæ»úµØÌṩÖÖ×Ó£»
CALL RANDOM_NUMBER(X)
WRITE(*,'(F6.2)')X
WRITE(*,*)'-------------------'
ENDDO
END PROGRAM ZZ

可以发现在一个循环内生成的随机数是一样的。

这个问题如何解决呢??

此外,不知道这个CALL RANDOM_SEED()返回什么东西。

谢谢讨论

linqus 发表于 2009-2-26 22:20

何光渝的frotran算法程序集中给出的四个函数
ran3为减去法生成0~1间随机数,
确实好用,尤其是在一次循环中

比如

DO I=1,N1
   ......
      X=ran3(idum)
      ...........
ENDDO

但是将程序运行两遍,发现生成的随机数是一样的!

正如上个帖子说的,
假如这个ran3函数位于三层循环的内层,
那外两层生成的东西岂不是一样的?
还有,不同时刻运行出来的结构还是一样的!

PROGRAM ZZ
USE IMSL
USE DFLIB
IMPLICIT NONE
REAL(KIND=8)::X
INTEGER(KIND=8)::k,I,J,INTTEMP
REAL(KIND=8),EXTERNAL::RAN3,RAN1
OPEN(UNIT=10,FILE='XXX.TXT')
DO k=1,94000,1
!CALL RANDOM_SEED()
!CALL RANDOM_NUMBER(x)
INTTEMP=K+10
X=RAN3(INTTEMP)
WRITE(10,9999)K,X
9999 FORMAT(I10,',',F10.4)
ENDDO
END PROGRAM ZZ
!##############################################################################
FUNCTION ran3(idum)
!¾ùÔÈ·Ö²¼Ëæ»úÊýÉú³É³ÌÐò
      INTEGER(KIND=8)::idum
      INTEGER MBIG,MSEED,MZ
      !REAL MBIG,MSEED,MZ
      REAL ran3,FAC
      PARAMETER (MBIG=1000000000,MSEED=161803398,MZ=0,FAC=1./MBIG)
      !PARAMETER (MBIG=4000000.,MSEED=1618033.,MZ=0.,FAC=1./MBIG)
      INTEGER i,iff,ii,inext,inextp,k
      INTEGER mj,mk,ma(55)
      !REAL mj,mk,ma(55)
      SAVE iff,inext,inextp,ma
      DATA iff /0/
      if(idum<0.or.iff==0) then
         iff=1
         mj=MSEED-iabs(idum)
         mj=mod(mj,MBIG)
         ma(55)=mj
         mk=1
         do i=1,54
            ii=mod(21*i,55)
            ma(ii)=mk
            mk=mj-mk
            if(mk<MZ) mk=mk+MBIG
            mj=ma(ii)
         end do
         do k=1,4
            do i=1,55
               ma(i)=ma(i)-ma(1+mod(i+30,55))
               if(ma(i)<MZ) ma(i)=ma(i)+MBIG
            end do
         end do
         inext=0
         inextp=31
         idum=1
      endif
      inext=inext+1
      if(inext==56) inext=1
      inextp=inextp+1
      if(inextp==56) inextp=1
      mj=ma(inext)-ma(inextp)
      if(mj<MZ) mj=mj+MBIG
      ma(inext)=mj
      ran3=mj*FAC
      END FUNCTION ran3
!##############################################################################

lilili606 发表于 2009-3-5 22:30

一个小小的建议,CALL RANDOM_SEED()这个subroutine尽量放在循环外面,多个随机数只需要一个种子,而如果子例程中有产生随机数的过程,那种子应该放在主程序中施加

touming24728 发表于 2011-3-29 10:43

请问大家,如果知道(0,1)内的算法后,怎么算任意给定区间内的随机数呢?请指教
页: [1]
查看完整版本: fortran如何生成【0,1】区间均匀分布的随机数?