Microsoft Word - COMP-MATH-2016-FULLTEXT.doc

Similar documents
C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

第9回 配列(array)型の変数

今回のプログラミングの課題 ( 前回の課題で取り上げた )data.txt の要素をソートして sorted.txt というファイルに書出す ソート (sort) とは : 数の場合 小さいものから大きなもの ( 昇順 ) もしくは 大きなものから小さなもの ( 降順 ) になるよう 並び替えること

Microsoft Word - no202.docx


Microsoft PowerPoint - program.ppt [互換モード]

プログラム例 /* ACM-ICPC2009 国内予選 Problem C */ // // filename = pc1.c // コンパイル

Microsoft PowerPoint - C4(反復for).ppt

スライド 1

kiso2-09.key

Taro-再帰関数Ⅲ(公開版).jtd

C言語による数値計算プログラミング演習

Microsoft Word - no103.docx

Microsoft Word - no15.docx

演算増幅器

Microsoft PowerPoint - 10.pptx

cp-7. 配列

スライド 1

[1] #include<stdio.h> main() { printf("hello, world."); return 0; } (G1) int long int float ± ±

Microsoft Word - no12.doc

Taro-再帰関数Ⅱ(公開版).jtd

スライド 1

行列、ベクトル

Microsoft Word - no11.docx

PowerPoint Presentation

スライド 1

喨微勃挹稉弑

PowerPoint プレゼンテーション

Taro-最大値探索法の開発(公開版

プログラミング実習I

PowerPoint プレゼンテーション

演習課題No12

PowerPoint プレゼンテーション

7 ポインタ (P.61) ポインタを使うと, メモリ上のデータを直接操作することができる. 例えばデータの変更 やコピーなどが簡単にできる. また処理が高速になる. 7.1 ポインタの概念 変数を次のように宣言すると, int num; メモリにその領域が確保される. 仮にその開始のアドレスを 1

数値計算法

FORTRAN( と C) によるプログラミング 5 ファイル入出力 ここではファイルからデータを読みこんだり ファイルにデータを書き出したりするプログラムを作成してみます はじめに テキスト形式で書かれたデータファイルに書かれているデータを読みこんで配列に代入し 標準出力に書き出すプログラムを作り

関数の呼び出し ( 選択ソート ) 選択ソートのプログラム (findminvalue, findandreplace ができているとする ) #include <stdiu.h> #define InFile "data.txt" #define OutFile "surted.txt" #def

Microsoft PowerPoint - 10.pptx

Microsoft PowerPoint - 計算機言語 第7回.ppt

Microsoft Word - no02.doc

PowerPoint プレゼンテーション

Microsoft PowerPoint - 第3回目.ppt [互換モード]

<4D F736F F D20438CBE8CEA8D758DC03389F0939A82C282AB2E646F63>

Microsoft PowerPoint - 説柔5_間勊+C_guide5ï¼›2015ã•’2015æŒ°æŁŽæš’å¯¾å¿œç¢ºèª“æ¸‹ã†¿ã•‚.pptx

プログラミングA

Microsoft PowerPoint - kougi6.ppt

CプログラミングI

/*Source.cpp*/ #include<stdio.h> //printf はここでインクルードして初めて使えるようになる // ここで関数 average を定義 3 つの整数の平均値を返す double 型の関数です double average(int a,int b,int c){

Microsoft PowerPoint - lec4.ppt

Microsoft PowerPoint - 11.pptx

今後の予定 6/29 パターン形成第 11 回 7/6 データ解析第 12 回 7/13 群れ行動 ( 久保先生 ) 第 13 回 7/17 ( 金 ) 休講 7/20 まとめ第 14 回 7/27 休講?

<4D F736F F D2094F795AA95FB92F68EAE82CC89F082AB95FB E646F63>

Microsoft PowerPoint - C_Programming(3).pptx

memo

プログラミング基礎

memo

<4D F736F F D20438CBE8CEA8D758DC F0939A82C282AB2E646F63>

データ構造

データ構造

プログラミング方法論 II 第 14,15 回 ( 担当 : 鈴木伸夫 ) 問題 17. x 座標と y 座標をメンバに持つ構造体 Point を作成せよ 但し座標 は double 型とする typedef struct{ (a) x; (b) y; } Point; 問題 18. 問題 17 の

PowerPoint プレゼンテーション

連立方程式の解法

Microsoft Word - no13.docx

kiso2-06.key

Microsoft PowerPoint - 4.pptx

Microsoft Word - VBA基礎(2).docx

09.pptx

C 言語第 3 回 2 a と b? 関係演算子 a と b の関係 関係演算子 等しい a==b 等しくない a!=b より大きい a>b 以上 a>=b より小さい a<b 以下 a<=b 状態 真偽 値 条件が満たされた場合 TRUE( 真 ) 1(0 以外 ) 条件が満たされなかった場合 F

gengo1-8

スライド 1

次に示す数値の並びを昇順にソートするものとする このソートでは配列の末尾側から操作を行っていく まず 末尾の数値 9 と 8 に着目する 昇順にソートするので この値を交換すると以下の数値の並びになる 次に末尾側から 2 番目と 3 番目の 1

関数の呼び出し ( 選択ソート ) 選択ソートのプログラム (findminvalue, findandreplace ができているとする ) #include <stdio.h> #define InFile "data.txt" #define OutFile "sorted.txt" #def

Section1_入力用テンプレートの作成

解析力学B - 第11回: 正準変換


PowerPoint プレゼンテーション

Microsoft Word - Cプログラミング演習(3)

コンピュータリテラシ 第 6 回表計算 2 このスライド 例題 /reidai6.xlsx /reidai6a.xlsx 課題 12 /reidai6b.xlsx /table12_13.xlsx

Microsoft Word - 3new.doc

Microsoft Word - Training10_プリプロセッサ.docx

(1) プログラムの開始場所はいつでも main( ) メソッドから始まる 順番に実行され add( a,b) が実行される これは メソッドを呼び出す ともいう (2)add( ) メソッドに実行が移る この際 add( ) メソッド呼び出し時の a と b の値がそれぞれ add( ) メソッド

※ ポイント ※

Microsoft PowerPoint - mp11-06.pptx

Microsoft PowerPoint - kougi2.ppt

1. 関数 scanf() 関数 printf() は変数の値を画面に表示しますが それに対し関数 scanf() はキーボードで入力した値を変数に代入します この関数を活用することで対話式 ( ユーザーの操作に応じて処理を行う ) プログラムを作ることができるようになります 整数の和

< F2D837C E95CF CF68A4A94C5816A2E6A>

memo

ープのロープ長以下であれば実現可能である ケース 3: 3 本のロープの杭の位置を点 P 1 = (x 1, y 1, 0), 点 P 2 = (x 2, y 2, 0), 点 P 3 = (x 3, y 3, 0) とする 点 P 1 = (x 1, y 1, 0), 点 P 2 = (x 2,

フローチャートの書き方

Microsoft Word - 漸化式の解法NEW.DOCX

Prog1_10th

ポインタ変数

Microsoft Word - COMP-MATH-2017-FULLTEXT.doc

Microsoft PowerPoint - C1(演算と変数).ppt

Microsoft PowerPoint - visualprogram.ppt

PowerPoint Presentation

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tol

gengo1-11

第1回 プログラミング演習3 センサーアプリケーション

XMPによる並列化実装2

Transcription:

#13 2017/1/17 16 連立一次方程式を解くその 2 1) 対角線上に 0 が現れる場合を回避する 0x + 3y = 9 2x + 4y = 16 これを kadai-26 で解いてみなさい 以下のようにエラーになる 0.00000000 3.00000000 9.00000000 2.00000000 4.00000000 16.00000000-1.#IND0000-1.#IND0000-1.#IND0000-1.#IND0000-1.#IND0000-1.#IND0000 でも 式 (0) と (1) をひっくり返したら エラーにならない 2x + 4y = 16 0x + 3y = 9 2.00000000 4.00000000 16.00000000 0.00000000 3.00000000 9.00000000 1.00000000 0.00000000 2.00000000 0.00000000 1.00000000 3.00000000 だから 対角線上に 0 が現れたら 式の順序を変えて 対角線上に 0 が来ないようにすればよい 上の例 では 式 (0) と (1) を交換する (Swap) ことによって 対角線上の 0 を回避している ( 式の順番を変えても 解 には影響がないから ) [i] 番目の式と [k] 番目の式を交換 (Swap) するとは a[i][0] a[i][1] a[i][j] a[k][0] a[k][1] a[k][j] ところで 二つの数を交換 (Swap) することをプログラムではどう書くか? a = 1.0; b=2.0; // a と b を交換するぞ a = b; b = a; これではダメ元の a の内容が残っていない そこで c = a; a = b; b = c; 待避場所として 一個の変数 ( ここでは C) を用いて 3 ステップの手順が必要になる 1/12/2017 P-111

これを係数の配列で行う (Ex24.c Kadai-27.c をコピーして修正する ) #define N 2 A[N][N+1] = 0,3,9,2,4,16 ; pra(),swapa(); // 交換する関数の宣言を追加する P,Q; i,j,k; for(i = 0; i < N; ++i) if(a[i][i] == 0.0) // 対角線項が 0 なら次の行と交換する P = A[i][i]; swapa(i,i+1); A[i][j] /= P; // 確認のために印字 // 改めて 対角線上の係数を P に置く // 以下 Kadai-27.c と同じ for(k = 0; k < N; ++k) if(k!= i) Q = A[k][i]; A[k][j] -= Q*A[i][j]; swapa(i,k) // i 行と k 行を交換する関数を追加する i,k; j; c; // 待避場所として c を使う for(j = 0; j < ; ++j) c = ; // c に何かを退避する A[i][j] = A[k][j]; = c; // c を何かに戻す pra() 以下 同じなので省略 上の ex24.c を完成させ 以下を解けることを確認しなさい 1/12/2017 P-112

0x + 3y = 9 2x + 4y = 16 ところで a[i][i] が 0 の場合 その下の係数 つまり a[i+1][i] も 0 かもしれない 1 0 a[0][i] a[0][n-1] a[0][n]= 右辺 [0] 0 1 0 0 a[i][i] a[i+1][i] 0 0 a[n-1][i] そこで a[i][i] から下に見ていって 絶対値が一番大きな係数を持つ行を見つけて その行と入れ替 えるという方針にする もし 上の網掛け部分が全部 0 なら それ以上掃き出しはできないのだから 解が求められない として終了して良い ( 実際には 解がない 場合と 解は決まらない 場合があるが これを区別するのは この 課題の範囲を超える ) まず findmax(i) という関数を用意する これは A[i][i] から下に係数を見て 最大の絶対値を持 つ係数 a[k][i] の k を求める もし 全部 EPSIRON(1.0e-10) 以下なら 全部ゼロと見なして処理を 中止する ------------ 練習 : 最大のもの を見つける 配列 A にデータの数値が入っている その中の最大の数値と 配列の番号 ( 添字 ) を求めなさい ex25.c #define N 10 A[10] = 23,45,21,44,68,96,13,77,62,35; i,imax,valmax; valmax = A[0]; // 仮の最大値 imax = 0; for( i = 0; i < N; ++i) if(a[i] > valmax ) valmax = A[i]; imax = i; prf(" 最大は A[%d] = %d\n",imax,valmax); 結果は最大は A[5] = 96 要するに 仮の最大値を適当に決めて それより大きいものが現れたら 置き換えていく これを踏まえて 1/12/2017 P-113

ex24. に以下の太字部分を 変更または加える #define N 3 A[N][N+1] = 0,1,0,1,0,0,1,2,1,0,0,3 ; pra(),swapa(); i,j,k; P,Q; for(i = 0; i < N; ++i) k = findmax(i); // i 式以降で絶対値が最大になる式の番号 k を求める if( k!= i) swapa(i,k); // それが [i] でなければ [i] と [k] 行を交換する // 確認の印字 P = A[i][i]; // 以下同様 A[i][j] /= P; for(k = 0; k < N; ++k) if(k!= i) Q = A[k][i]; A[k][j] -= Q*A[i][j]; #define EPSIRON (1.0e-10) // これ以下の値はゼロと見なす #include <math.h> // fabs() 絶対値を使うために必要 findmax(i) i; // A[i][i] から下を調べる k,kmax; amax = EPSIRON; for(k = i; k < N; ++k) if(fabs(a[k][i]) > amax) if(amax <= EPSIRON) return(kmax); 以下 ex29.c と同じなので省略 swapa(i,k) の本体 pra() の本体 // 今までの最大よりも kmax = k; // 大きい場合 amax = fabs(a[k][i]); // それを記録する prf("******** n 解が求められません n"); exit(); // ここでプログラムを終了させる 1/12/2017 P-114

ex24 を実行すると こうなる 0.00000000 1.00000000 0.00000000 1.00000000 0.00000000 0.00000000 1.00000000 2.00000000 1.00000000 0.00000000 0.00000000 3.00000000 1.00000000 0.00000000 0.00000000 3.00000000 //0 行と2 行が交換された 0.00000000 0.00000000 1.00000000 2.00000000 0.00000000 1.00000000 0.00000000 1.00000000 1.00000000 0.00000000 0.00000000 3.00000000 0.00000000 1.00000000 0.00000000 1.00000000 // 1 行と2 行が交換された 0.00000000 0.00000000 1.00000000 2.00000000 1.00000000 0.00000000 0.00000000 3.00000000 0.00000000 1.00000000 0.00000000 1.00000000 0.00000000 0.00000000 1.00000000 2.00000000 // 最後なので交換はしない 意図的に 解が決まらないようにしてみると #define N 3 A[N][N+1] = 0,1,0,1,0,0,1,2,0,0,0,3 ; 0.00000000 1.00000000 0.00000000 1.00000000 0.00000000 0.00000000 1.00000000 2.00000000 0.00000000 0.00000000 0.00000000 3.00000000 ******** 解が求められません // 0 列目は全部 0 なので 処理できない give up! ここまでで 一応掃き出し法の完成とする 仕上げに 係数をデータとして読むようにしよう 1/12/2017 P-115

以下を最終形 Kadai28.c とする 太字以外は ex24.c と同じ #define NMAX 30 // 連立の最大は 30 までとする A[NMAX][NMAX+1]; // データは不要 N; // N は入力させる pra(),swapa(); P,Q; i,j,k; prf(" 式の個数 N は?"); scanf("%d", ); // 整数 N を入力 for(i=0; i < ; ++i) prf(" 第 %d 式の係数をスペースで区切って入力しなさい : ",i); for(j = 0; j < ; ++j) scanf("%lf", & ); //(%lf はエル エフ long float) // 以下 ex29.c と同じ for(i = 0; i < N; ++i) k = findmax(i); if( k!= i) swapa(i,k); P = A[i][i]; A[i][j] /= P; for(k = 0; k < N; ++k) if(k!= i) Q = A[k][i]; A[k][j] -= Q*A[i][j]; #define EPSIRON (1.0e-10) #include <math.h> findmax(i) i; k,kmax; amax = EPSIRON; for(k = i; k < N; ++k) if(fabs(a[k][i]) > amax) kmax = k; 1/12/2017 P-116

amax = fabs(a[k][i]); if(amax <= EPSIRON) prf("******** n 解が求められません n"); exit(); return(kmax); swapa(i,k) i,k; j; c; for(j = 0; j < N+1; ++j) c = A[i][j]; A[i][j] = A[k][j]; A[k][j] = c; pra() i,j; prf(" n"); for( i = 0; i<n;++i) for( j=0; j < N+1; ++j) prf("%12.8f ",A[i][j]); prf(" n"); 実行例 式の個数 N は?3 第 0 式の係数をスペースで区切って入力しなさい : 27 9 3 14 第 1 式の係数をスペースで区切って入力しなさい : 8 4 2 5 第 2 式の係数をスペースで区切って入力しなさい : 1 1 1 1 27.00000000 9.00000000 3.00000000 14.00000000 8.00000000 4.00000000 2.00000000 5.00000000 1.00000000 1.00000000 1.00000000 1.00000000 1.00000000 0.00000000 0.00000000 0.33333333 0.00000000 1.00000000 0.00000000 0.50000000 0.00000000 0.00000000 1.00000000 0.16666667 h 秀丸でデータをファイル ( 例えば test.dat) を作っておく 3 27 9 3 14 8 4 2 5 1 1 1 1 実行は Kadai28 < test.dat とすれば 毎回データを入力しなくてもよい Kadai28.c を完成させ 下を解きなさい 1/12/2017 P-117

a + b + c + d = 10 2a + b + 3c + d = 17 3a + 5b + c + 2d = 24 a b + c d = 2 挑戦 : 検算もしてくれるとうれしい 3. 検算の仕方入力された係数行列 A のコピーを B として保持する A の N 列に解が求まったあと B の係数と解から方程式の右辺を計算する Kadai29.c(Kadai28.c の修正 ) #define NMAX 30 N; A[NMAX][NMAX+1]; B[NMAX][NMAX+1]; // 係数をコピーしておくための配列 pra(),swapa(),copyab(),kenzan(); // 関数を 2 こ追加 i,j,k; P,Q; prf(" 式の個数 N は?"); scanf("%d",&n); for(i=0; i<n; ++i) prf(" 第 %d 式の係数をスペースで区切って入力しなさい : ",i+1); for(j = 0; j < N+1; ++j) scanf("%lf",&a[i][j]); copyab(); // この時点のAをBにコピーする for(i = 0; i < N; ++i) k = findmax(i); if( k!= i) swapa(i,k); P = A[i][i]; A[i][j] /= P; for(k = 0; k < N; ++k) if(k!= i) Q = A[k][i]; A[k][j] -= Q*A[i][j]; 1/12/2017 P-118

kenzan(); // 検算の実行 copyab() // AをBにコピーする関数 i,j; for(i =0; i < N; ++i) for(j=0; j < N+1; ++j) B[i][j] = A[i][j]; kenzan() // 検算する関数 i,j; S; prf(" 検算 --------\n"); for(i = 0; i < N; ++i) for(j = 0, S = 0; j < N; ++j) prf("%10.6f * %10.6f ",B[ ][ ],A[ ][ ]); if(j!= N-1) prf("+ "); S += B[ ][ ]*A[ ][ ]; prf("= %f\n", ); このあとは Kadai28.c とおなじなので 省略 実行例 式の個数 N は?3 第 1 式の係数をスペースで区切って入力しなさい : 27 9 3 14 第 2 式の係数をスペースで区切って入力しなさい : 8 4 2 5 第 3 式の係数をスペースで区切って入力しなさい : 1 1 1 1 27.00000000 9.00000000 3.00000000 14.00000000 8.00000000 4.00000000 2.00000000 5.00000000 1.00000000 1.00000000 1.00000000 1.00000000 1.00000000 0.00000000 0.00000000 0.33333333 0.00000000 1.00000000 0.00000000 0.50000000 0.00000000 0.00000000 1.00000000 0.16666667 検算 -------- 27.000000*0.333333 + 9.000000*0.500000 + 3.000000*0.166667 = 14.000000 8.000000*0.333333 + 4.000000*0.500000 + 2.000000*0.166667 = 5.000000 1.000000*0.333333 + 1.000000*0.500000 + 1.000000*0.166667 = 1.000000 1/12/2017 P-119