• ベストアンサー

C言語 二分法 プログラム

C言語での二分法の解法になやんでいます。 f(x)=X2乗-2でf(x)=0の解を2分法により求める場合のプログラムを教えて下さい。 収束条件|ak-bk|<10^-6と|f(ck+1)|<10^-6のいずれかを満足。また、解を求める過程として、k,ak,bk,|ak-bk|, ck+1, f(ck+1) (k=0,1,2,3...)も示してくれないでしょうか。よろしくお願いします。 注: a,b,cに付属するk,k+1はa,b,cの下側に付く小文字です。(a1,a2... ak, ak+1. b1 b2... bk, bk+1)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

#include <stdio.h> #include <math.h> #define DISP_PROCESS double f(double x) {return x * x - 2;} double solve(double a, double b, double (*func)(double v)) { // a と b の間にある、func(c) == 0 となる、c を算出する。 // ただし、a < b であり、かつ、func(a) < 0, func(b) >0 かつ、[a, b] で、func() は、 // 単調に増加するものと仮定している。 const double err = 1.0e-6; static int k = 0; double c = (a + b) /2 ; k++; #if defined(DISP_PROCESS) printf("k = %d\na = %f, b = %f , abs(a - b) = %f\nc = %f, func(c) = %f\n\n", k, a, b, fabs(a - b), c, func(c)); #endif if (fabs(a - b) < err) return c; if (fabs(func(c)) < err) return c ; if (f(c) > 0) return solve(a, c, func); else return solve(c, b, func); } int main() { printf("ANS = %f", solve(0, 2, f)); return 0; } --------------------------------------------------------- solve() をわずかに一般化して、 ・a < b ・func(a) と func(b) が異符号 ・[a, b] で func() は単調 の条件で、対応可能とした例。 int sign(double v) { if (v > 0) return 1; if (v < 0) return -1; return 0; } double solve(double a, double b, double (*func)(double v)) { const double err = 1.0e-6; static int k = 0; double c = (a + b) /2 ; k++; #if defined(DISP_PROCESS) printf("k = %d\na = %f, b = %f , abs(a - b) = %f\nc = %f, func(c) = %f\n\n", k, a, b, fabs(a - b), c, func(c)); #endif if (fabs(a - b) < err) return c; if (fabs(func(c)) < err) return c ; if (sign(func(a)) == sign(func(c))) return solve(c, b, func); if (sign(func(b)) == sign(func(c))) return solve(a, c, func); return c; } 再帰って美しい。

その他の回答 (1)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

> C言語での二分法の解法になやんでいます。 C言語じゃない解法には悩んでないのですね? それをC言語に「翻訳」するだけですが、どこで悩んでいるのでしょう? 繰り返し方、とか、収束条件の判定と成立/不成立での処理方法、とか、途中の表示、とかがわからないなら、C言語の基本なので、最初から復習してください。

関連するQ&A

  • ニュートン法をC言語でプログラム

    方程式 cos^2x-0.5=0 (0<x<π) の解をニュートン法で求める という問題をC言語のプログラムを作り計算したいのですが分かりません。 自分で考えてみたプログラムは以下の通りです。 #include <stdio.h> #include <math.h> #define f1(x) cos(x)*cos(x)-0.5 #define f2(x) sin(2*x) /* ニュートン法による方程式の解 */ main() { double x0,x1,a,b,c,d,g,n; a=1; x0=0.7; n=0; while(a>0.0001){ b=x0; d=f1(b); g=f2(b); x1=x0-d/g; c=x1; a=f1(c); n=n+1; printf(" n= %f x1=%f x0=%f\n",n,x1,x0); printf(" a= %f → 解 x= %f \n", a,x1); x0=x1; } } 自分としてはこれが精一杯で、何故間違ってるのか、何をどうすればいいのか、さっぱり分かりません。どういったところが間違ってるのか可能性だけでも示して頂ければ幸いです。 参考として、ニュートン法によるプログラム例として書かれていたものを上げさせて頂きます。 例: e^x-3=0 の解をニュートン法により計算する。 #include <stdio.h> #include <math.h> #define f1(x) exp(x)-3 #define f2(x) exp(x) /* ニュートン法による方程式の解 */ main() { double x0,x1,e,a,b,c,d,g,n; a=1; x0=3; n=0; while(a>0.0001){ b=x0; d=f1(b); g=f2(b); x1=x0-d/g; c=x1; a=f1(c); n=n+1; printf(" n= %f x1=%f x0=%f\n",n,x1,x0); printf(" a= %f → 解  x= %f \n", a,x1); x0=x1; } }

  • C言語プログラム(二分法)について質問です。

    C言語プログラム(二分法)について質問です。 以下作成したプログラムでは、aを入力すると, x=b - (log(a)) - (a+x)/2の解が求まります。(今回式は適当ですが。) 二分法で解を求めるというプログラムは作成できたのですが、 このプログラムで、aを1~10まで変化させたときのxの値というようなループをプログラムでしたうえで、 a*xの値がもっとも大い点を求めるためにはどのようなプログラムを組めば(これを改良すれば)いいのでしょうか? 具体的に行いたいことは、この二分法のプログラムをaとxの関数とし、a*xの最大点を求めたいのです。 質問が分かりにくいかもしれませんが、お願いします。 以下作成したプログラムです。 #include <stdio.h> #include <stdlib.h> #include <math.h> #define eps 1.0e-6 double b=0.3; double a=0; double f(double x); void nibun(void); int main() { nibun(); return 0; } void nibun(void) { int count; double x0,x1,m; printf("aの値\n"); scanf("%lf",&a); count=0; x0=-2*b; x1=b; do { count++; m=(x0+x1)/2.0; if(f(m)*f(x0)<0) x1=m; else x0=m; if(count==700) { printf("Error\n"); exit(1); } } while (!(fabs(x0-x1)<eps)); printf("解の値は %f\n",m); } double f(double x) { return(b - (log(a)) - (a+x)/2); }

  • 間違っているのはどこ?

    a,b,cを正の定数とし、x,yが axy-bx-cy=0,x>0,y>0 を満たしているとき、x+yの最小値を求めよ。 x+y=kとおくと、y=k-xより、x>0,y>0だから 0<x<k。 y=k-xをaxy-bx-cy=0に代入して、ax^2-(ak-b+c)x+ck=0 これが、0<x<kに少なくとも1つの解を持てばよい。 y=ax^2-(ak-b+c)x+ckとおく。x=0のとき、y=ck>0,x=kのとき、y=bk>0 また、判別式=>0となる(計算すると分かる)。よって、0<x<kに解をもつから、 軸の条件から、0<(ak-b+c)/2a<kを解いて、kの範囲が分かり、最小値が分かると 思ったのですが、(b-c)/a<k, (c-b)/a<kが出てきましたが、答えには程遠いように 思います。間違いを教えてください。よろしくお願いします。

  • C言語のプログラムについて

    下記は、何言語かわからないです。 これをC言語にするにはどうすればよいでしょうか。 プログラムは、「ニュートン法を用いて、方程式x^3(xの3乗)-4=0の近似解を求めるプログラム。ただし、実数解と、近似解の誤差は、0.0001以下とする。ここで、この方程式の導関数は、3x^2(3*xの二乗)である。」 100 DEF F(X)=X*X*X-4 110 DEF G(X)=3*X*X 120 INPUT PROMPT "初期値":A 130 LET B=A-F(A)/G(A) 140 IF ABS(A-B)<=.0001 THEN 170 150 LET A=B 160 GOTO 130 170 PRINT "近似解";B 180 END 以上です。 ご回答よろしくお願いいたします。

  • 二分法のプログラム

    関数x^3-7x^2-6x+2を二分法で解くプログラムを作ったのですが、エラーが出てコンパイルできません。訂正箇所を教えて下さい。 宜しくお願い致します。 #include<stdio.h> #include<math.h> #define EPSILON 0.1E-5 #define TURE 1 #define FALSE 0 int kansu(int x); void Nibunho(left,right,sol,flag); double left,right; int flag; int main(void) { printf("区間の左端と右端は?\n"); scanf("%lf %lf",&left,&right); flag=FALSE; Nibunho(left,right,&root,&flag); if(flag) printf("解 = %e (繰り返し回数 = %d)\n",root,k); else { printf("入力した範囲で解は求まりませんでした。\n"); printf("f(%e) = %e \n",root,k); } return 0; } int kansu(int x) { int f(double x) f(x)=x*x*x-7.0*x*x-6.0*x+2.0; return(f(x)); } void Nibunho(left,right,sol,flag) { double left,right,*sol; int *flag; double a,b,c,fa,fb,fc; k=0; a=left; b=right; do { k++; c=(a+b)/2.0; fc=f(c); fa=f(a); fb=f(b); if(fabs(fc)<1.0e-10) { a=c; b=c; *flag=TRUE; } else { if( (fa * fc < 0.0) || (fb * fc < 0.0) ) { *flag = TRUE; if( (fa*fc) < 0.0 ) b=c; else a=c; } else { if( fabs(fa) > fabs(fb) ) a=c; else b=c; } } } while((b-a)>EPSILON) *sol=(a+b)/2.0; }

  • C言語のプログラム

    C言語で2つの微分方程式をEuler法、Heun法、Runge-Kutta法により求めるプログラムを作りたい。ただし、初期条件はx=0,y=1とする。また、間隔Δxを変えたときの解の変化を調べたい。 Euler法のプログラムはどうにか分かったのですが、Heun法、Runge-Kutta法のプログラムがわかりません。 Euler法のプログラム #include_<stdio.h> #include_<math.h> int_main(){ __double__a=0; __double__b; __int_____m=10; __int_____n; __double__h; __double__x,y; __double__dydx; __int_____k; __double__e; __double__f; __printf("オイラー法計算例:y=e^x,_y=1/e^4x\n\n"); __//_y_=_e^x __b_=_1; __for(n=100;n<=10000;n*=100){ ____h_=_(b-a)/n; ____printf("y'_=_y:_h(=dx)_=_%.1e_(y=e^x)\n",h); ____x_=_a;_y_=_1; ____for(k=0;k<=n;k++)_{ ______x_=_k*h; ______if(k%(n/m)==0)_{ ________f_=_exp(x); ________e_=_fabs(y-f); ________printf("x=%.2f,_y=%f,_e^x=%f_er=%.0e\n", ________x,y,f,e); ______} ______dydx_=_y; ______y_=_y_+_dydx*h; ____} __} __printf("\n"); __//_y_=_1/e^4x __b_=_4; __for(n=100;n<=10000;n*=100){ ____h_=_(b-a)/n; ____printf("y'_=_-4y:_h(=dx)_=_%.1e_(y=1/e^4x)\n",h); ____x_=_a;_y_=_1; ____for(k=0;k<=n;k++)_{ ______x_=_k*h; ______if(k%(n/m)==0)_{ ________f_=_exp(-4*x); ________e_=_fabs(y-f); ________printf("x=%.2f,_y=%f,_1/e^4x=%f_er=%.0e\n", ________x,y,f,e); ______} ______dydx_=_-4*y; ______y_=_y_+_dydx*h; ____} __} __return_0; } 分かる方がいましたら、回答よろしくお願いします。

  • C言語 二分法

    初投稿です。 お恥ずかしながらパソコンが苦手で、Cゲッが難しくてできません。 今回二分法です。 途中まではやったのですができません。 演習 0~1の乱数を12個発生させ,これらの平均をxi,yi とする。(s,tは乱数) xi=1/12(x1i+x2i+....x12i) yi=1/12(y1i+y2i+....y12i) このようなを1000個作り,(xi,yi)で散布図 を作りなさい。またx,yのそれぞれの平均を求 めよ。 この演習で #include<stdio.h> #include<stdlib.h> #include<math.h> #define eps 1.0e-5 float f(double x); void nibuin(void); int main () { int count; double a,b,m; count=0; printf("範囲の左の値を入力してください。\n"); scanf("%lf",&a); printf("範囲の右の値を入力してください。\n"); scanf("%lf",&a); if(count==1000){ printf("収束しませんでした。\n"); exit(1); } } while(!(fabs(a-b)<eps)); printf("解の値は%f\n収束するのに%d回かかりました。"m,count); } float f(double x) { reurn x*sin(x)+log(x); } まではできたのですが、 scanf("%lf",&a);とif(count==1000){の間に入る命令が打てません。 よろしくお願いします。

  • C言語のプログラムの問題で質問です。

    C言語のプログラムの問題で質問です。 問題は、 与えられた実数(a,b,c,d)に対して、次の連立非線形方程式の解 を「ニュートン法」を用いて解く。 f1(x,y)=y+ax^2-b=0 f2(x,y)=y^2+cx^2-d=0 ただし初期値(a,b,c,d)を入力でき、上記の方程式の解が画面表示されること。 という問題です。 普通の連立方程式を解くプログラムならできるのですが、ニュートン法 で解くというのが分かりません。 プログラムを教えてください。参考にしたいです。

  • C言語のプログラムの問題で質問です。

    C言語のプログラムの問題で質問です。 問題は、 与えられた実数(a,b,c,d)に対して、次の連立非線形方程式の解 を「ニュートン法」を用いて解く。 f1(x,y)=y+ax^2-b=0 f2(x,y)=y^2+cx^2-d=0 ただし初期値(a,b,c,d)を入力でき、上記の方程式の解が画面表示されること。 という問題です。まず、どういう方針で作っていくのかが分かりません。 できるのなら参考例を挙げてもらえればありがたいです。お願いします。

  • フーリエ級数展開の問題

    フーリエ級数展開の問題 このフーリエ級数展開の問題が分かりません. アドバイスいただけたら幸いです f(x)= a0/2+ Σ(k=1→∞) ( ak*coskx + bk*sinkx) でa0,bk,akは実数です (a)次の関数をフーリエ級数展開せよ g(x ) = ( π - x ) ( 0 < x < 2π ) = 0 x=0 (b) (a)の結果より、(1)(2)を証明せよ (1) (1/2π)*∫(0→2π) f(x)* ( π - x ) dx =Σ(k=1→∞) (bk/k) (2) (1/2π)*∫(0→2π) f(x+t)* ( π - x ) dx =Σ(k=1→∞) (bk*coskt - ak*sinkt) /k (c) (b)の結果より、次の値を求めよ Σ(k=1→∞) ( (-1)^n) / n^2 補足 (b)以降が分かりません (a)はbk=2/kだとおもいまし a0,akともに0だと思います

専門家に質問してみよう