- ベストアンサー
二分探索で方程式の解を求める方法
C言語で二分探索を利用して、以下の方程式を解くように言われたのですが、 本やインターネットで調べましたが、見当がつかず困っています。 2(1-2x)/(33*(1-2x)-x(2x)^5) = 1-(1-x)^(1/4) 上記の式に限らず、複雑な方程式を二分探索で解を求めるようなときのプログラミングについてご指導いただければと思います。 プログラミングは初心者です。 よろしくお願いします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
初心者向けにご説明します。 2分探索法は、与えられた範囲を2つに分けて、求める解がどちらにあるか範囲を絞り、 絞った範囲をまた2つに分けてどちらかに絞り・・・ と繰り返して行って、求める解の範囲を絞っていくやり方です。 方程式を求めるには、解を含む範囲(複数個あってはいけない)と、許される誤差を 指定する必要があります。 もう少し具体的に話すと、範囲の下限、上限をそれぞれ x_min, x_max として、 f(x_min) < 0, f(x_max) > 0 つまり、与えられた範囲内ではグラフは右上がりで、1点だけx軸と交わる(これが解)場合、 x_mid = (x_min + x_max) / 2.0 として、 f(x_mid) < 0 であれば、求める解はx_midよりも大きい側にあるので、次はx_minにx_midを代入して 同じ処理を繰り返せばOK。 f(x_mid) > 0 の場合は、求める解はx_midよりも小さい側にあるので、次はx_maxにx_midを代入して 同じ処理を繰り返すことになります。 メインループのみ未コーディングのプログラムを以下に挙げます。 上記を参考に、仕上げてみて下さい。 余裕があれば、範囲の上下限がたまたま0になった場合の終わらせ方も考えてみて下さい。 ---(全角スペースは全て半角スペースに置き換えて下さい)----- #include <stdio.h> #include <math.h> /************************** 条件 ***************************/ double x_min = -1.5; /* 範囲最小値(初期値) */ double x_max = -1.0; /* 範囲最大値(初期値) */ double delta_x = 0.000001; /* 許容誤差 */ /************************** 方程式 ***************************/ double f(double x) { double ret; ret = 2 * (1 - 2 * x) / (33 * (1 - 2 * x) - pow(x * (2 * x), 5)) - (1 - pow((1 - x), 1 / 4)); return(ret); } /************************** main関数 ***************************/ int main(void) { double x_mid; /* 範囲の中央 */ double fx_min, fx_max; /* 範囲の境界 */ double dir; /* グラフの傾き(方向) */ /* 条件を検査 */ fx_min = f(x_min); fx_max = f(x_max); if((fx_min < 0) && (fx_max > 0)) dir = 1.0; /* グラフが右上がりの場合 */ else if((fx_min > 0) && (fx_max < 0)) dir = -1.0; /* グラフが右下がりの場合 */ else return(-1); /* 範囲の設定が悪い */ /* メインループ */ while(x_max - x_min > 2 * delta_x) { /* x_mid を算出する */ /* f(x_mid) を計算し、求める解がx_midのどちら側か判断する */ /* x_max, x_minを更新する */ } /* 最終的な範囲の中央値を求める解とする */ x_mid = (x_min + x_max) / 2.0; printf("x = %lf\n", x_mid); return(0); }
その他の回答 (1)
- maku_x
- ベストアンサー率44% (164/371)
参考URLのところに、「二分法による方程式の解法」として、原理が載っていましたよ。丁度 C言語のサンプルプログラムもありましたので、それを参考にすればプログラミングできるでしょう。
お礼
ありがとうございます。是非参考にさせていただきます。 自分のレベルだとプログラムの内容を理解するのに時間がかかりそうですが、頑張ってみます。
お礼
大変わかりやすく、丁寧な解説をありがとうございます。 なんとかプログラムも形にすることができました。 また機会がありましたら是非、よろしくお願いします。