PDA

Tam Sürümünü Görmek İçin : Monte Carlo Benzetimi ve C


DaesAgelmar
27/02/2004, 15:42
(0-1) aralığında düzgün, (U(0.1)), rassal sayılar kullanılarak, zaman faktörünün önemli olmadığı, olasılıklı (stokastik) veya belirli (deterministik) problemlerin çözümünde kullanılan bir tekniktir. Monte Carlo Benzetimi, genellikle statik benzetim modellerinde kullanılır.
konuyla ilgili genel bir bilgi verdikten sonra sormak istediğim soru şu
sinx fonk. o- pi arasında monte carlo benzetimi uygulayarak çözmek istiyorum ama problem şu ki 0-pi arasında random sayı üretecek bi sayı üreteci c de nası yazılır pek bilemiyorum

int rand_number(void)
{
return rand() % 9000 + 1000;
}
benzer bi fonksiyon kullansam gerekli sonuçları verir mi?
aslında fonk pi X (sigma0-n sinx)/n olacak ama şu sayı üretme olayında takıldım


Volkan Uzun
28/02/2004, 04:42
const long int pi=3141517;
srand(time());
int i = rand() % pi ;
gibimi

DaesAgelmar
28/02/2004, 15:29
const long int pi=3141517;
srand(time());
int i = rand() % pi ;
gibimi
aslında şöle bişi tam işime yarar ama biraz düzenlemem lazım

//================================================== ====== file = lec11.c =====
//= A sample Monte-Carlo simulation to solve a simple integral =
//================================================== ===========================
//= Notes: Computes the area under func() in the real range a to b where =
//= max of func() is m using Monte-Carlo simulation. That is, =
//= area = Integral(a, b) func(x) dx =
//=---------------------------------------------------------------------------=
//= Build: bcc32 lec11.c =
//=---------------------------------------------------------------------------=
//= History: KJC (02/07/99) - Genesis =
//================================================== ===========================

//----- Include files ---------------------------------------------------------
#include <stdio.h> // Needed for printf()
#include <math.h> // Needed for sin()
#include <stdlib.h> // Needed for rand() and RAND_MAX

//----- Include files ---------------------------------------------------------
#define NUM_SAMPLES 1000000 // The number of samples to run

//----- Function prototypes ---------------------------------------------------
double uniform(double x, double y); // Computes uniform RV in range x to y
double func(double x); // Function to be integrated

//===== Main program ================================================== ========
void main(void)
{
double r1; // Uniform random number from a to b
double r2; // Uniform random number from 0 to M
double a, b; // X-axis range from a to b
double m; // Y-axis range from 0 to m
long int accept; // Accept counter
long int reject; // Reject counter
double area; // Computed area
long int i; // Loop counter

// Initialize a, b, and m for function under study. In this case the
// function under study is sin(x) in the range 0 to pi.
a = 0.0;
b = 3.14159265;
m = 1.0;

// Initialize accept and reject counters
accept = reject = 0;

// Main loop for simulation
for (i=0; i<NUM_SAMPLES; i++)
{
// Pull uniform RVs for r1 and r2
r1 = uniform(a, b);
r2 = uniform(0, m);

// Test if accept or reject and increment appropriate counter
if (r2 < func(r1))
accept++;
else
reject++;
}

// Compute the area
// area = (percentage of accepts) * (area of rectangle formed by
// a to b on X-axis and 0 to m on Y-axis)
area = ((double) accept / (accept + reject)) * ((b - a) * (m - 0.0));

// Output the area
printf("Area of function (for %ld iterations) = %f \n", NUM_SAMPLES, area);
system("PAUSE");
}

//================================================== ===========================
//= Function to generate uniformly distributed RV on range x to y =
//= - Input: x (lower bound) and (y upper bound) =
//= - Output: Returns with uniform RV =
//================================================== ===========================
double uniform(double x, double y)
{
double z; // Uniform random number from 0 to 1

// Pull a uniform RV (0 < z < 1)
do
{
z = ((double) rand() / RAND_MAX);
}
while ((z == 0) || (z == 1));

return(x + ((y - x) * z));

}

//================================================== ===========================
//= Function of interest which to compute area under =
//= - Input: x =
//= - Output: y = f(x) =
//================================================== ===========================
double func(double x)
{
return(sin(x));
system("PAUSE");
}


yukarıdaki kod sin(x) alanı hesaplamak için aslında aynı şey ama ben alan yazsın istemiyorum

DaesAgelmar
02/03/2004, 01:45
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

#define PI 3.14159265358979323

main()
{
int i;
double n,x,rast,toplam,integral;


printf("\n hesaplanma sayisini giriniz:");
scanf("%lf",&n);
toplam=0;
x=0;

for(i=0;i<=n;i++)
{
rast=rand()%(22/7)+1;
x=sin((rast*(22/7))/180);
toplam=toplam+x;
}
integral=(PI/180)*(22/7)*(toplam/n);
printf("\nintegralin sonucu=%lf",integral);
system("PAUSE");
return 0;
}


şöyle bir code yazdım fakat integrali yaklaşık ikli yerine 0,08231 gibi hesaplıyor acaba yanlışlık nerde var bakabilirmisiniz?

acehreli
03/03/2004, 21:22
DaesAgelmar, rassal sayilar olusturmak ilginc
bir konudur.

Bazi programlarda rassal sayilarin nasil olusturulduklari
sonucu onemli olcude degistirir. Ornegin, herhangi bir
dinamik sistem uzerinde deney yapan bir program, rassal
sayilarin nasil olusturulduklarina gore sonucu bambaska
bulabilir. (Bu konu uzerinde bir konusmayi dinlemistim.)

Bazi programlar [0,1) araligi yerine [0,1] araliginda sayi
uretirler ve programlari bu nedenle gocebilir. (Kendim de bu
hataya yakin bir zamanda dusmustum; asagida verdigim
baglantilarda acikliyorum.)

Ama oncelikle, % islecini kullanmayi bir kenara birakman
gerekir. Bazi kitaplar ve ogretmenler rand islevini
anlatirken % islecini kullanirlar, ama okuyucuyu veya
ogrenciyi bu yontemin zararlari konusunda uyarmazlar. O
insanlar ya bu isi, ya da onemini bilmiyorlar demektir :)

Ben yakin bir zaman once bu konuda bir mektup atmistim ama
ceviz.net'in gecirdigi sunucu sorunlari o mektubu da ucurmus
gibi gorunuyor.

O mektupta baska bir forumdaki konulara baglantilar
vermistim. Okumaya su mektuptan baslamak ilginc olabilir:

http://groups.yahoo.com/group/cdili/message/3381

ceviz.net'te 'rand' veya 'srand' sozcuklerini aratarak daha
once yazilan mektuplari da bulabilirsin.

Baska yorumlarimi daha sonra yazacagim...

Ali

acehreli
03/03/2004, 21:29
sanal_programci, 'srand'i 'rand'a bu kadar yakin kullanmak
cok yanlistir. Hele ona time(0)'in dondurdugu degeri
vermek, bir saniye boyunca hep ayni rastgele (!) degerin
olusmasina neden olur :)

'srand' normalde 'main'in basinda bir kere cagirilir.

Boyle yapildiginda bile ona 'time(0)'in sonucunu gondermek,
programin ayni saniye icinde birden fazla kere cagrilmasi
durumunda hep ayni sonuclari vermesine neden olur. ('time'in
duyarligi 1 saniyedir.)

Ali

acehreli
03/03/2004, 21:59
DaesAgelmar, programinla ilgili yorumlarim asagida.

Kisaca, tamsayi islemlerinin sonuclarinin da tamsayi
olduklarini hatirlaman gerekiyor.

Sonuclarin tam olarak hangi tamsayi turunde olacaklari benim
gibi cogu insan icin karisiktir; ama her iki sayinin da ayni
turden oldugu durumlarda sonuc, sayilarla ayni turdendir.

Ali


#include <stdio.h>
#include <math.h>
#include <stdlib.h>

#define PI 3.14159265358979323
/*
Bu tamsayi zaten math.h icinde M_PI olarak
tanimlidir.
*/


/*
'main'in donus turu 'int'tir. Gonderdigin
ornekteki 'void main' cok yapilan bir yanlistir.

Donus turunu senin yaptigin gibi bos birakmak, 'int' olarak
varsayilmasina neden olur ama bence her islevde oldugu gibi
onu da acikca yazmak daha iyidir:
*/
int main()
{
int i;
double n,x,rast,toplam,integral;

printf("\n hesaplanma sayisini giriniz:");
scanf("%lf",&n);
toplam=0;
x=0;

for(i=0;i<=n;i++)
{
rast=rand()%(22/7)+1;

/*
22/7 isleminin sonucu 3'tur (int)

Yani rast su araliktadir: [1,4]
*/

x=sin((rast*(22/7))/180);

/*
rast*(22/7) sunlardan birisidir:
{ 3.0, 6.0, 9.0, 12.0 }

Onlarin 180'e bolumu su kumeyi verir:
{ 0.166, 0.333, 0.500, 0.666 }

Yani bu programda sin bu dort degerle
cagriliyor.
*/
toplam=toplam+x;
}
integral=(PI/180)*(22/7)*(toplam/n);

/*
Burada da yukaridakiler gibi bir bolme
hatasi var: 22/7 her zaman icin 3'tur.
*/
printf("\nintegralin sonucu=%f",integral);

/*
gcc beni %lf kullaniminin standart olmadigi
konusunda uyardi. %f, %g, %e zaten 'double'
turuyle calisirlar. Onun icin yukaridaki
satiri %f kullanacak sekilde degistirdim.
*/

/* system("PAUSE"); */

/*
(PAUSE benim sistemimde yok; onun icin cikarttim.)
*/

return 0;
}

x-Acto
04/03/2004, 09:00
isin c kismini pek bilmiyorum ama.. monte carlo benzetiminin dogru sonuc vermesi icin uretilen rassal sayilarin uygunlugunun test edilmesi lasim.. bunu icin 6 - 7 cesit uygunluk testi var.. bunlari da goz onune alman lasim...

kolay gele

DaesAgelmar
04/03/2004, 20:58
önerileriniz ve verdiğiniz kaynaklar için çok teşekkür ederim hem beni bu konuda düşünmeyi ittiniz hemde bir çok kişinin faydalanacağı bir bilgi havuzu oluşturdunuz