お願いします
Re: お願いします
返信ありがとうございます
ソースは改良しすぎたせいでぐちゃぐちゃになってしまいましたのもう少し待ってもらえますでしょうか
問題文は
モンテカルロ法を使って区間[a,b]における関数f(x) ( f(x)>0, a<=x<=b )の定積分を計算するプログラムを作成せよ
ただしここではf(x)=exp(-0.5*x)[-5,0]
また、関数f(x)はC言語として実現すること
です
ソースは改良しすぎたせいでぐちゃぐちゃになってしまいましたのもう少し待ってもらえますでしょうか
問題文は
モンテカルロ法を使って区間[a,b]における関数f(x) ( f(x)>0, a<=x<=b )の定積分を計算するプログラムを作成せよ
ただしここではf(x)=exp(-0.5*x)[-5,0]
また、関数f(x)はC言語として実現すること
です
Re: お願いします
正しく計算できるプログラムが完成してからでないと改良はできないはずだし、
ぐちゃぐちゃになってしまったのならば改良じゃない、
というお約束のつっこみは我慢しよう。
モンテカルロ法については円周率を求めるサンプル等が簡単に見つかるだろうし、
原理を理解したら定積分に応用するのもそれほど難しくない。
というわけでプログラムを作ってみたが、何故か正しい答がでない、
という状況と思ってよいでしょうか?
だとすると、ソースコードが貼られてからしかアドバイスできません。
ぐちゃぐちゃになってしまったのならば改良じゃない、
というお約束のつっこみは我慢しよう。
モンテカルロ法については円周率を求めるサンプル等が簡単に見つかるだろうし、
原理を理解したら定積分に応用するのもそれほど難しくない。
というわけでプログラムを作ってみたが、何故か正しい答がでない、
という状況と思ってよいでしょうか?
だとすると、ソースコードが貼られてからしかアドバイスできません。
Re: お願いします
>>正しく計算できるプログラムが完成してからでないと改良はできないはずだし、
ぐちゃぐちゃになってしまったのならば改良じゃない、
というお約束のつっこみは我慢しよう。
改造の間違えですねすいません
>>モンテカルロ法については円周率を求めるサンプル等が簡単に見つかるだろうし、
原理を理解したら定積分に応用するのもそれほど難しくない。
というわけでプログラムを作ってみたが、何故か正しい答がでない、
という状況と思ってよいでしょうか?
正直にな話原理はまったく理解してませんというか理解できません
勉強はしてるのですがまだそこまで追いついてない状態なので宿題をやるのが精一杯な現状がいまです
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define F(x) exp(-0.5*x)
float frand()
{
return rand()/(RAND_MAX+1.0);
}
main()
{
int k, m, n;
float a, b, c, x, y, s;
a=-5;
b=0;
printf("[m]");
scanf("%d", &m);
printf("[c]");
scanf("%f", &c);
k=n=0;
srand((unsigned)time(NULL));
while(++n <m){
x= frand();
y= frand();
if(y<F(x)) k++;
}
s= F(b)-F(a);
printf("Sum = %f\n", s);
}
これが自分の今の限界です
間違いしかないかもしれませんがよろしくお願いします
ぐちゃぐちゃになってしまったのならば改良じゃない、
というお約束のつっこみは我慢しよう。
改造の間違えですねすいません
>>モンテカルロ法については円周率を求めるサンプル等が簡単に見つかるだろうし、
原理を理解したら定積分に応用するのもそれほど難しくない。
というわけでプログラムを作ってみたが、何故か正しい答がでない、
という状況と思ってよいでしょうか?
正直にな話原理はまったく理解してませんというか理解できません
勉強はしてるのですがまだそこまで追いついてない状態なので宿題をやるのが精一杯な現状がいまです
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define F(x) exp(-0.5*x)
float frand()
{
return rand()/(RAND_MAX+1.0);
}
main()
{
int k, m, n;
float a, b, c, x, y, s;
a=-5;
b=0;
printf("[m]");
scanf("%d", &m);
printf("[c]");
scanf("%f", &c);
k=n=0;
srand((unsigned)time(NULL));
while(++n <m){
x= frand();
y= frand();
if(y<F(x)) k++;
}
s= F(b)-F(a);
printf("Sum = %f\n", s);
}
これが自分の今の限界です
間違いしかないかもしれませんがよろしくお願いします
Re: お願いします
モンテカルロ法について理解されてません。プログラムの前にモンテカルロ法について調べてください。
なお,このような問題を解くときは,どのようなグラフになるかを知らなくてはいけません。
参考までに,画像を添付しました。
-5のときのf(x)の値は,12.1825です。
なお,このような問題を解くときは,どのようなグラフになるかを知らなくてはいけません。
参考までに,画像を添付しました。
-5のときのf(x)の値は,12.1825です。
non
Re: お願いします
>>モンテカルロ法について理解されてません。プログラムの前にモンテカルロ法について調べてください。
それは↑でもいった通り理解しています
調べても理解ができませんので
>>なお,このような問題を解くときは,どのようなグラフになるかを知らなくてはいけません。
参考までに,画像を添付しました。
-5のときのf(x)の値は,12.1825です。
一応グラフの形もその値になることもわかっています
それは↑でもいった通り理解しています
調べても理解ができませんので
>>なお,このような問題を解くときは,どのようなグラフになるかを知らなくてはいけません。
参考までに,画像を添付しました。
-5のときのf(x)の値は,12.1825です。
一応グラフの形もその値になることもわかっています
Re: お願いします
>調べても理解ができませんので
そうですか、失礼しました。
xの範囲は当然、-5から0の範囲で乱数を発生させますよね。yの範囲は、孫策さんは、いくらで発生させたいですか?
これは、孫策さんが決めることです。
すると、その範囲の面積はいくらになりますか?
次に、乱数は何回発生させますか?仮に100000回としたら、if(y<F(x)) k++;でカウントした回数との比から、面積が出ますね。
なお、プログラムではfloatより、doubleで計算させましょう。
そうですか、失礼しました。
xの範囲は当然、-5から0の範囲で乱数を発生させますよね。yの範囲は、孫策さんは、いくらで発生させたいですか?
これは、孫策さんが決めることです。
すると、その範囲の面積はいくらになりますか?
次に、乱数は何回発生させますか?仮に100000回としたら、if(y<F(x)) k++;でカウントした回数との比から、面積が出ますね。
なお、プログラムではfloatより、doubleで計算させましょう。
non
Re: お願いします
[quote="non"]>調べても理解ができませんので
>>そうですか、失礼しました。
情けなくてすいません
ネットで調べて参考にさせてもらい新たに#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define F(x) (exp(-0.5*x))
double frand()
{
return rand()/(RAND_MAX);
}
void syuku(int i)
{
int k, n;
double a, b, y, x, sum;
a=-5;
b=0;
k = i;
n = 0;
srand((unsigned)time(NULL));
while(k>0){
--k;
x=frand()*b;
y=frand();
if(F(x)>=y) n++;
}
sum = (F(b)-F(a))*(double)n/i;
printf("Sum = %f\n", sum);
}
main()
{
return 0;
}
を書いてみたんですがやはりできませんでした
やっぱりyの範囲とかが重要なのでしょうか?
>>そうですか、失礼しました。
情けなくてすいません
ネットで調べて参考にさせてもらい新たに#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define F(x) (exp(-0.5*x))
double frand()
{
return rand()/(RAND_MAX);
}
void syuku(int i)
{
int k, n;
double a, b, y, x, sum;
a=-5;
b=0;
k = i;
n = 0;
srand((unsigned)time(NULL));
while(k>0){
--k;
x=frand()*b;
y=frand();
if(F(x)>=y) n++;
}
sum = (F(b)-F(a))*(double)n/i;
printf("Sum = %f\n", sum);
}
main()
{
return 0;
}
を書いてみたんですがやはりできませんでした
やっぱりyの範囲とかが重要なのでしょうか?
Re: お願いします
> やっぱりyの範囲とかが重要なのでしょうか?
理解しないで正しいプログラムが書けるわけがありません。
何を調べ、何が判らないのかを書けば、アドバイスできるかも。
理解しないで正しいプログラムが書けるわけがありません。
何を調べ、何が判らないのかを書けば、アドバイスできるかも。
Re: お願いします
>>理解しないで正しいプログラムが書けるわけがありません。
いつも理解せず時間をかけて作ってます…
>>何を調べ、何が判らないのかを書けば、アドバイスできるかも。
とりあえずモンテカルロ法の積分で類似問題っぽいものを調べて
そこをいじって今に至る訳なんですが
理解してないから解らないもの具体的にいうのは難しいのですが
どこから狂っているのか指摘していただきたいです
いつも理解せず時間をかけて作ってます…
>>何を調べ、何が判らないのかを書けば、アドバイスできるかも。
とりあえずモンテカルロ法の積分で類似問題っぽいものを調べて
そこをいじって今に至る訳なんですが
理解してないから解らないもの具体的にいうのは難しいのですが
どこから狂っているのか指摘していただきたいです
Re: お願いします
プログラムの態をなしていません。
モンテカルロ法云々という以前の問題かもしれません。
ある範囲の点をi回発生させ、その点がf(x)の上にあるか下にあるかで、カウントします。仮に、f(x)の下に点が打たれた回数を
n回とすると、n/iが割合になります。ある範囲の面積をsとするなら、求める積分の面積はs*k/nで求められます。
>sum = (F(b)-F(a))*(double)n/i;
この式がそのつもりですね。(F(b)-F(a))は面積ではないですね。高さです。でも、b=0、a=-5なら、F(b)-F(a)<0になっちゃうでしょ。
だから、グラフを見るように伝えてます。ここまで、理解できますか?
モンテカルロ法云々という以前の問題かもしれません。
ある範囲の点をi回発生させ、その点がf(x)の上にあるか下にあるかで、カウントします。仮に、f(x)の下に点が打たれた回数を
n回とすると、n/iが割合になります。ある範囲の面積をsとするなら、求める積分の面積はs*k/nで求められます。
>sum = (F(b)-F(a))*(double)n/i;
この式がそのつもりですね。(F(b)-F(a))は面積ではないですね。高さです。でも、b=0、a=-5なら、F(b)-F(a)<0になっちゃうでしょ。
だから、グラフを見るように伝えてます。ここまで、理解できますか?
non
Re: お願いします
逸れてすいませんがこのプログラムで実行したら値が不安定ですがだいたい22.~って感じになったのですが小数点以下を安定させるためにはやはり改良が必要でしょうか?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define F(x) (exp(-0.5*x))
double f(double x){
return x;
}
int main(){
int n, m, k;
double a, b, c, x, y, s;
m=100000;
a=-5;
b=0;
c=13;
k=n=0;
srand((unsigned)time(NULL));
while(++n < m){
x= a+(b-a)*(double)rand()/RAND_MAX;
y= c*(double)rand()/RAND_MAX;
if(y<F(x)) k++;
}
s=(double)k/n*c*(b-a);
printf("Sum = %f\n", s);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define F(x) (exp(-0.5*x))
double f(double x){
return x;
}
int main(){
int n, m, k;
double a, b, c, x, y, s;
m=100000;
a=-5;
b=0;
c=13;
k=n=0;
srand((unsigned)time(NULL));
while(++n < m){
x= a+(b-a)*(double)rand()/RAND_MAX;
y= c*(double)rand()/RAND_MAX;
if(y<F(x)) k++;
}
s=(double)k/n*c*(b-a);
printf("Sum = %f\n", s);
return 0;
}
Re: お願いします
結果の値を安定させることはできません。
試行回数を多くすることで精度を上げることはできます。
乱数を使う、というモンテカルロ法の性質上、
毎回結果が異なって当たり前です。
試行回数を多くすることで精度を上げることはできます。
乱数を使う、というモンテカルロ法の性質上、
毎回結果が異なって当たり前です。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define WIDTH (5)
#define HEIGHT (13)
int main(void)
{
int n, i, count;
srand((unsigned int) time(NULL));
do {
printf("試行回数:");
scanf("%d", &n);
} while (n <= 0);
for (count = i = 0; i < n; i++) {
double x = (double) rand() / RAND_MAX * -WIDTH;
if ((double) rand() / RAND_MAX * HEIGHT <= exp(-0.5 * x)) {
count++;
}
}
printf("%f\n", (double) count / n * WIDTH * HEIGHT);
return 0;
}
Re: お願いします
OKです。答えが異なるのは、初級者さんが言われる通りです。
細かいところですが、
>double f(double x){
>return x;
>}
これは、何かの残骸ですね。不要です。
>while(++n < m){
これでは、ループ回数がm-1です。1回少ない。
>rand()/RAND_MAX
これですと、乱数範囲は 0<= x <=1
で、両方に=が付きます。それが、わかって使ったのなら、これでかまいません。
一般的には
rand()/(RAND_MAX+1)
>c=13;
高さを13に固定してしまったのは、概算値としてはかまいません。しかし、精度をあげるなら、
F(-5)-F(0)の範囲で乱数を発生させた方がいいでしょう。
細かいところですが、
>double f(double x){
>return x;
>}
これは、何かの残骸ですね。不要です。
>while(++n < m){
これでは、ループ回数がm-1です。1回少ない。
>rand()/RAND_MAX
これですと、乱数範囲は 0<= x <=1
で、両方に=が付きます。それが、わかって使ったのなら、これでかまいません。
一般的には
rand()/(RAND_MAX+1)
>c=13;
高さを13に固定してしまったのは、概算値としてはかまいません。しかし、精度をあげるなら、
F(-5)-F(0)の範囲で乱数を発生させた方がいいでしょう。
non
Re: お願いします
>>これは、何かの残骸ですね。不要です。
除き忘れました、ありがとうございます
>これでは、ループ回数がm-1です。1回少ない。
改善してみます
>これですと、乱数範囲は 0<= x <=1
で、両方に=が付きます。それが、わかって使ったのなら、これでかまいません。
一般的には
rand()/(RAND_MAX+1)
今回は一応解ってましたが次回からは下でいこうと思います
>高さを13に固定してしまったのは、概算値としてはかまいません。しかし、精度をあげるなら、
F(-5)-F(0)の範囲で乱数を発生させた方がいいでしょう。
解りました。改善させてみます
長い時間本当にありがとうございました
初心者さんもありがとうございます
参考になりました
除き忘れました、ありがとうございます
>これでは、ループ回数がm-1です。1回少ない。
改善してみます
>これですと、乱数範囲は 0<= x <=1
で、両方に=が付きます。それが、わかって使ったのなら、これでかまいません。
一般的には
rand()/(RAND_MAX+1)
今回は一応解ってましたが次回からは下でいこうと思います
>高さを13に固定してしまったのは、概算値としてはかまいません。しかし、精度をあげるなら、
F(-5)-F(0)の範囲で乱数を発生させた方がいいでしょう。
解りました。改善させてみます
長い時間本当にありがとうございました
初心者さんもありがとうございます
参考になりました