* Önsöz
* Fortran'a Giriş
* Fortran'nın Temelleri
* Basit ve Formatlı Okuma/Yazma
* Temel Kütüphane Fonksiyonları
* Karşılaştırma Deyimleri
* Döngüler
* Alt Programlar I
* Alt Programlar II
* Diziler
* Dinamik Diziler
* Gösterici (Pointer) Kavramı
* Katarlar (Stringler)
* Yapısal Veri Tipleri
* Dosya Yönetimi
* Modül Kavramı
* Sayısal Tipler (KINDs)
* Bit Düzeyinde Çalışmak
* Kütüphane Fonksiyonları Listesi
* Yararlanılan Kaynaklar
* - - -
* Karmaşık Sayılar
* Tarih-Saat Fonksiyonları
* Rastgele Sayılar
* Katar - Sayı Dönüşümleri
* Komut Satırı İşlemleri
* Co-Array Fortran
* Derleme Seçenekleri
* Fortran ve C
* Sayılar Kuramı
* Analiz
* Lineer Cebir
Fortran 90/95 Derleyicileri
|
* Salford (silversoft FTN95)
* G95
* GFORTRAN
* programlama.com
* Fortran (wikipedia)
* fortran.gantep.edu.tr
* g95.org
* Hot scripts
* E-posta
|
|
Bölüm 22: Rastgele Sayılar
###################- (%95)
|
Giriş
Bilimsel uygulamalarda problemler iki kısımda incelenebilir:
- kesin = deterministik (deterministic)
- tahmini = olası (random).
Kesin sistemler, kuralları kanun hükmünde olan matematiksel yasalarla tanımlanabilen
sistemlerdir; Örneğin yerçekimi yasası gibi. Fakat, tahmini sistemlerin kuralları muhtemel
veya raslantısal (stocastic) olan istatiksel yöntemlerle belirlenir; Örneğin havaya atılan bir
metal paranın yazı veya tura gelmesi gibi. Burada raslantıdan kasıt, tahmini sistemlerde,
başlangıç koşulları kesin olarak tayin edilemediği için sonuca dair çözümün tahmin edilmesi
anlamındadır. Yoksa, evrende raslantıya yer yoktur.
Tahmini sistemleri modelleyen algoritmaların hesine birden "Monte Carlo Yöntemleri" denir.
(Bkz: http://www1.gantep.edu.tr/~bingul/c/?ders=24)
Monte Carlo Yöntemleri rastgele üretilen sayıları kullanarak modelleme yapar.
Rastgele Sayı (random number) özel bir dağılımdan seçilen kargaşık
(caotic) bir sayıdır.
Bilgisayar ortamında, yazılımsal veya donanımsal olarak rastgele sayılar üretmek mümkündür.
Bu bölümde, yazılımsal olarak üretilen Rastgele Sayılar konu edilecektir.
22.1 Rastgele Sayılar Nasıl Üretilir?
Rastgele Sayı (random number) özel bir dağılımdan seçilen kargaşık (caotic) bir sayıdır.
Bilgisayarlar kesin (deterministic) bir yapıda çalıştıkları için gerçek anlamda rastgele sayı üretemezler.
Ancak, uygun algoritmlarla bir bilgisayarın düzgün bir dağılımdan seçilen ve genllikle [0,1] arasında gerçel
değerler alan rastgele sayı üretmesi sağlanabilir. Bilgisayarların ürettiği bu rastgele sayılar
yalancı rastgele sayı (pseudo-random numbers) olarak adlandırılır. Rastgele sayı üreten bu algoritmalara
rastgele sayı üreteci (random number generator) denir. Günümüz derleyicilerinin bir çoğunda
rastgele sayı üreteçleri için hazır kütüphane fonksiyonları tanımlanmıştır.
Fortran 90+, kullanıcılarına aşağıdaki iki alt programı sunmuştur:
- CALL RANDOM_NUMBER(HARVEST)
INTENT(OUT) özelliğine sahip HARVEST (hasat) değerini geri döndürür.
HARVEST, [0, 1] aralığından düzgün olarak seçilmiş rastgele bir değer alan gerçel bir
değişken veya bir dizi olabilir.
- CALL RANDOM_SEED([SIZE] [,PUT] [,GET])
Rasgeler sayı üretecini yeniden başlatır. Yani
RANDOM_NUMBER ile üretilen sayıların başlangıç (tohum = seed) değerini değiştirir.
Eğer hiç bir argüman belirtilmezse, üretilen kümenin başlangış değeri bilgisayarın tarih ve saattinden alınır.
- SIZE, INTENT(OUT) özelliğine sahip tamsayı türünde bir değişkendir.
PUT ve GET argümanları ile tanımlanan dizilerin boyutunu belirler.
- PUT, INTENT(IN) özelliğine sahip, eleman sayısı SIZE ile sınırlı tek boyutlu ve
tamsayı tipinde bir dizidir. Başlangıç değerini (seed) yeniden belirler.
- GET, INTENT(OUT) özelliğine sahip, eleman sayısı SIZE ile sınırlı tek boyutlu ve tamsayı tipinde bir dizidir.
Mevcut 'seed' değerini belirler.
Program 22.1'de RANDOM_NUMBER fonksiyonunun kullanımı gösterilmiştir.
Program 22.1: 5 adet rastgele sayı
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
|
PROGRAM Rastgele
!----------------------------------------------------
! 22prg01.f95
! [0,1] aralığında 5 adet rastgele sayı
!----------------------------------------------------
IMPLICIT NONE
REAL :: R
INTEGER :: I
DO I = 1, 5
CALL RANDOM_NUMBER(R)
PRINT *,R
END DO
END PROGRAM |
ÇIKTI
0.9839003
0.6999507
0.27531183
0.6611019
0.8098419
|
Program yeniden çalıştırılırsa:
ÇIKTI
0.9839003
0.6999507
0.27531183
0.6611019
0.8098419
|
şeklinde aynı çıktı elde edilir. Bunun nedeni, rastgele sayı üretecinin kümeye hep aynı değerle başlamasdır.
Kümenin ilk değeri RANDOM_SEED fonksiyonu belirlenir.
Program 22.2: 5 adet rastgele sayı
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
|
PROGRAM Rastgele
!----------------------------------------------------
! 22prg02.f95
! [0,1] aralığında 5 adet rastgele sayı
!----------------------------------------------------
IMPLICIT NONE
REAL :: R
INTEGER :: I
! kümenin ilk değeri bilgisayrın
! saatinden alınıyor...
CALL RANDOM_SEED()
DO I = 1, 5
CALL RANDOM_NUMBER(R)
PRINT *,R
END DO
END PROGRAM |
ÇIKTI
0.719955
0.56769586
0.8951854
0.29187852
0.9748538
|
Program yeniden çalıştırıldıkça her zaman yeni bir küme elde edilir.
ÇIKTI
0.83996755
0.9052106
0.07953507
0.111786485
0.5262628
|
22.2 Örnek Uygulamalar
ÖRNEK 1: Belli Aralıkta Rastgele Sayılar
RANDOM_NUMBER fonksiyonu her zaman [0, 1] aralığında gerçel sayı üretir. Bazı uygulamalarda
bu aralığın sınırlarını değiştirmek gerekbilir.
R [0, 1] aralığınd rastgele bir sayı olsun.
[A, B] aralığında rasgele gerçel sayı üretmek için: A + (B-A)*R
[M, N] aralığında rasgele tamsayı sayı üretmek için: M + INT(N*R)
işlemlerini yapmak yeterlidir. Örneğin
[-1, 1] aralığında rasgele gerçel sayı üretmek için: -1.0 + 2.0*R
[1, 6] aralığında rasgele tamsayı sayı üretmek için: 1 + INT( 6*R )
Program 22.3: Belli aralıkta rastgele sayılar
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
|
PROGRAM Rastgele
!----------------------------------------------------
! 22prg01.f95
! [0,1] aralığında 5 adet rastgele sayı
!----------------------------------------------------
IMPLICIT NONE
REAL :: R, Rg
INTEGER :: I, Rt
CALL RANDOM_SEED()
DO I = 1, 5
! [0,1] aralığında gerçel sayı
CALL RANDOM_NUMBER(R)
! [1, 100] aralığında gerçel sayı
Rg = 1.0 + 99.0*R
! [1, 6] aralığında tam sayı
Rt = 1 + INT(6*R)
PRINT '(F8.4,1x,I3)',Rg,Rt
END DO
END PROGRAM |
ÇIKTI
62.0038 4
91.4151 6
34.6946 3
68.7964 5
16.6470 1
|
ÖRNEK 2: Yazı Tura Simulasyonu
Hilesiz bir para atıldığında, yazı veya tura gelme olasılığı (P, probability) eşit ve kuramsal olarak P = 1/2 dir.
Düşünün ki bir para n kez atılsın ve gelen turaları sayıp ve t ile gösterelim.
Deney sayısı, n, arttıkça t/n oranı kararlı (sabit) kalmaya başlar. Bu durumda, olasılığın istatiksel tanımı şöyle yapılır:
P(t) = t/n
n sonsuza giderken P(t) değeri P = 1/2 değerine yaklaşır.
Şimdi, [0, 1] aralığından rastgele seçilen sayıları kullanarak, para atma deneyini yapalım. Rastgele sayı üreteçleri
sayıları eşit olasılıkla üretir. r bir rastgele sayı olsun. r < 0.5 durumuna tura, r >= 0.5
durumuna da yazı diyelim. Bu şekilde, bir döngü kullanarak deney sayısına (n) göre, yazı-tura simulasyonu yapılabilir.
Program 22.4, klavyeden girilen n'ye göre, P(t) ve 1 - P(t) olasılıklarını hesaplar.
Program 22.4: Yazı Tura
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
|
PROGRAM Yazı_Tura
!----------------------------------------------------
! 22prg04.f95
! Yazı-Tura Simulasyonu
!----------------------------------------------------
IMPLICIT NONE
INTEGER :: I, Tura = 0, Yazi, N
REAL :: R, P
! Deney sayısı
PRINT *,"Deney sayısını girin:"
READ *,N
CALL RANDOM_SEED()
! Deneyleri başlat
DO I = 1, N
CALL RANDOM_NUMBER(R)
IF(R<0.5) Tura = Tura + 1
END DO
P = REAL(Tura)/N
Yazi = N - Tura
PRINT *,"Tura sayisi:", Tura
PRINT *,"Yazi sayisi:", Yazi
PRINT *,"Olasılıklar:", P, 1.0-P
END PROGRAM Yazı |
ÇIKTI
Deney sayısını girin:
150
Tura sayisi: 77
Yazi sayisi: 73
Olasılıklar: 0.5133333 0.48666668
|
Program 22.4'de deney sayısı (n) bir dış döngüye bağlanarak, 10'un katları (10, 100, 1000, ...) olarak değiştirilmiştir.
Programın çıktısı sırasıyla, n, gelen tura sayısı, gelen yazı sayısı ve tura ve yazı olasılıklarıdır.
n büyüdükçe, p'nin 0.5'e yaklaştığına dikkat edin.
Program 22.5: Yazı Tura
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
|
PROGRAM Yazı_Tura
!----------------------------------------------------
! 22prg05.f95
! Yazı-Tura Simulasyonu
!----------------------------------------------------
IMPLICIT NONE
INTEGER :: I, J, Tura, Yazi, N
REAL :: R, P
CALL RANDOM_SEED()
DO J = 1, 8
! Deney sayısı 10 un katları
N = 10**J
Tura = 0
! Deneyleri başlat
DO I = 1, N
CALL RANDOM_NUMBER(R)
IF(R<0.5) Tura = Tura + 1
END DO
P = REAL(Tura)/N
Yazi = N - Tura
PRINT '(3I9," | ",2F10.7)', N, Tura, Yazi, P, 1.0-P
END DO
END PROGRAM Yazı |
ÇIKTI
10 8 2 | 0.8000000 0.2000000
100 46 54 | 0.4600000 0.5400000
1000 488 512 | 0.4880000 0.5120000
10000 5006 4994 | 0.5006000 0.4994000
100000 49946 50054 | 0.4994600 0.5005400
1000000 499572 500428 | 0.4995720 0.5004280
10000000 4999618 5000382 | 0.4999618 0.5000382
100000000 50005484 49994516 | 0.5000548 0.4999452
|
ÖRNEK 3: Zar Simulasyonu
Bu uygulamada, bir çift zar atımı modellenecektir. Bu, bir çok tavla programında kullanılan yöntemdir.
Bir çift zar atılıyor. Zarların toplamının 7 olma olasılığını bulan bir program yazalım (Program 22.6).
Program 22.6: Tavla Zarları
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
|
PROGRAM Zar
!----------------------------------------------------
! 22prg06.f95: Zar Simulasyonu
!
! Atılan bir çift zarın toplamının 7 (yedi) olma
! olasılığını hesaplar.
!
! Olasılık kuramına göre, birçift zarın toplamının
! 7 olma olasılığı aşağıdaki formülden hesaplanabilir:
! Ptoplam(7) = P(1,6) + P(2,5) + P(3,4) +
! P(4,3) + P(5,2) + P(6,1)
!
! Diğer taraftan:
! P(1,6)=P(2,5)=P(3,4)=P(4,3)=P(5,2)=P(6,1)=1/36'dır.
!
! Buna göre:
! Ptoplam(7) = 6*(1/36) = 1/6 = 0.16666.. dır.
!----------------------------------------------------
IMPLICIT NONE
INTEGER :: I, J, Yedi, Zar1, Zar2, N
REAL :: R1, R2, P
CALL RANDOM_SEED()
DO J = 1, 8
! Deney sayısı 10 un katları
N = 10**J
Yedi = 0
! Deneyleri başlat
DO I = 1, N
CALL RANDOM_NUMBER(R1)
CALL RANDOM_NUMBER(R2)
Zar1 = 1 + INT(6*R1)
Zar2 = 1 + INT(6*R2)
IF(Zar1+Zar2 == 7) Yedi = Yedi + 1
END DO
P = REAL(Yedi)/N
PRINT '(I9," | ",I9, F10.7)', N, Yedi, P
END DO
END PROGRAM |
ÇIKTI
10 | 3 0.3000000
100 | 17 0.1700000
1000 | 176 0.1760000
10000 | 1671 0.1671000
100000 | 16783 0.1678300
1000000 | 167329 0.1673290
10000000 | 1666192 0.1666192
100000000 | 16666043 0.1666604
|
|