- ベストアンサー
二分法のC++プログラム
#include<iostream> #include<cmath> using namespace std; int main(){ double x1, x2, c; cout <<"x1:"; cin >> x1; cout <<"x2:"; cin >> x2; while(fabs(x2-x1) > 0.00001){ c=(x1+x2)/2; if(cos(x1/2.0)*cos(c/2)>=0) x1 = c; else x2 = c; } cout << "x=" << x1 <<endl; return 0; } cos(x/2)=0の解となるxを挟んでいないx1,x2を与えると、結果は保証できないですが、それは別にいいんですか?それはダメだとするとどこを訂正すればいいんですか
- みんなの回答 (5)
- 専門家の回答
みんなが選んだベストアンサー
> 解となるxを挟んでいないx1,x2を与えると、結果は保証できないですが、それは別にいいんですか? よいわけないでしょ。 > それはダメだとするとどこを訂正すればいいんですか 入力されたx1とx2で解を挟んでいるかどうか確認して,挟んでなければもう一度入力させるのが一番簡単。それがいやなら,自動的に入力した区間を大きくするのでもよい
その他の回答 (4)
- ninoue
- ベストアンサー率52% (1288/2437)
#4 です。 問題を読み間違えていたようですみません。 問題は、f(x/2)=cos(x/2)=0.0 となる xの値を求められているのですね。 f(x)=cos(x)=0.0 となる点を求めることを考えてコメントしていました。 (指定した変数に直接対応する関数の値を考えるのが普通だと考えていましたので) 申し訳ありませんでした。 cos(x/2)=0 を挟まない x1,x2が与えられた場合の処理についてですが、 while(...){...} の前に入力チェック、変数レンジ変更のロジックを追加します。 まず後の処理を分かりやすくするため、x1<x2となるように必要であれば入力を入れ替えます。 f(x1),f(x2)の符号が異なる場合は現在のwhile文へ進みます。 そうでない場合、dx=x2-x1; を先ず計算します。 その後、関数値の絶対値が小さい方へ、x1或いはx2を適当なステップ幅で 進めて行き、f(x1),f(x2)が異なった符号値になるまで繰返します。 (例えば 0<f(x1)<f(x2) の時、c=x1-dx; x1=c; として繰返す) その途中で一定回数繰返しても異なった値にならない場合、エラーとする必要があると思われます。 (関数値の変化割合:(f(c)-f(x2))/f(x2):が小さすぎる場合(例えば1/32以下等)は、ステップ幅dxを大きくする等の考慮も最適化迄考えると必要になりますが、初めはそこまでは不要でしょう) 以上等を考慮して検討を進めてください。
- ninoue
- ベストアンサー率52% (1288/2437)
http://okwave.jp/qa5396700.html 二分法のC++プログラム >簡単なプログラムが自分の思った通りには実行されない場合、 >まずデバッガでステップ実行し、関係する変数値、関数値、どのパスを通っているのかを確認する、 >或いはプリント文を追加し各変数値、関数値、通っているパス等を確認する >以上をやることはプログラマとしての常識のはずです。 >また関数としては何を考えているのですか、確認してください。 >これまでの他の人のヒントも考慮すれば解決出来るはずです。 >分かってしまえば簡単な事ですから、後は人に頼らず自分で解いてください。 >そうしないといつまでも力が付かないと思います。 以上の通り指摘していたはずですか、各変数値、関数値、実行パスの確認はされましたか? 次のようにprint文を2行追加すればすぐに分かるはずです。 関数値は0に近い値ですか、次第に0に近づいていますか? if(...){ print(...); ... } else { print(...); ... } 本当は机上デバッグをすればすぐに分かるはずです。 関数としては何を考えているのですかとのヒントで誤りに気が付かれることを期待していたのですが。 プログラムの中に不要な文字が6文字含まれています。
- 麻野 なぎ(@AsanoNagi)
- ベストアンサー率45% (763/1670)
「解は保証できない」ではなく、「最初に入 れた x1, x2 の値のいずれかに収束」します。 ※冷静に考えれば、どちらに収束するかもわか ります。 あと、プログラムの中に、意味の上では間違っ ているところが1カ所あります。 正しい解が求められるときには、たまたま、 x1 == x2 == c に収束するので、表示される 結果はあっていますが。 (その意味では、まあ、間違っているとも言 えず、「気持ち悪い」程度かもしれません) 最初に入力された x1, x2 が解を挟むかどうか は、一般的には、求める方程式 f(x) = 0 に対 して、f(x1) と f(x2) の符号が異なるという ことですが、このプログラムは、f(x) が単調 増加することを前提としているので、f(x1) > 0 かつ f(x2) < 0 が「解を挟む必要条件」です。 (ただし、x1 > x2) さらにいえば、これは、「ひとつ以上の解を 挟む」ための条件に過ぎないので、x1, x2 の 範囲が広くて、ふたつ以上の解を挟んでしま うと(その間に単調減少している部分が存在 するので)失敗することもあります。 これを考えると。 ・f(x1) > 0 かつ f(x2) < 0 (x1 > x2) ・f(x1) < 0 かつ f(x2) > 0 (x1 < x2) ・f(x1) = f(x2) = 0 (x1 = x2) ・x1 - x2 の絶対値が f(x) の 1/2 以下 が必要十分条件かなと思います。 最初の3つをまとめると ・f(x1)(x1 - x2) > 0 かつ f(x2)(x1 - x2) < 0 ・x1 - x2 の絶対値が f(x) の 1/2 以下 になるのかな?(未検証)
- Tacosan
- ベストアンサー率23% (3656/15482)
「結果が保証できないけどそれでいいのかどうか」あるいは「それでダメなときにどう訂正すればよいか」はあなたがこのプログラムで解こうとしている問題に依存します. 「よくない」と断言してしまうのはちょっと勇み足っぽい気がします>#1.
補足
どこを訂正すればいいんですか