−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
   応用数学II                         1995.7.6/7
 10.乱数三昧 + 一次変換                  飯島
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

10.0 杉本君の願いと石戸谷先生のお言葉

 またもや,杉本君からのお願いがありました。石戸谷先生の「幾何学要論」での宿題の お手伝いをしてねというお願いでした。それは,複素数の一次変換の像をいろいろと調べ なさい。余力があったら,パソコンで調べなさいというものでした。  実は,それ自体は,後期に取り組んでもいいと思っていた内容だったのですが,石戸谷 先生の意図を了解してからでないといけないので,「石戸谷先生に聞いてからね」という ことにしました。  さて,石戸谷先生に伺ってみたところ,            「馬鹿なことをいっちゃあいけない」 と一笑されてしまいました。       「まずは手で計算し,点をプロットすることが狙いなんだ」 ということです。ですから,まずは,自分の手できちんと計算して,プロットしてくださ い。しかし,それだけでは,ちょっと可愛そうだと思ったので,「手掛かりになるような プログラム例を与えてもいいですか」と再度伺ってみると,                「それはいいですよ」 ということだったので,急遽今回の課題として,次のものも追加することにしました。             「実数の線型変換の像を調べる」  なお,これだけでは,1時間もたない可能性もあります。そこで,乱数を使ったプログ ラミング例もいくつか追加してみます。今回は,それらを適当につまみ食いしてください 。  それから,試験等に関することですが,応用数学では,               試験週間に実技試験を行う ことにしたいと思います。  基本的には,次のようなことです。  1:授業に関するものは何でも持ち込んでよい。  2:何かについて調べる問題が与えられる。  3:今までに入力したことのあるプログラムを使ってもいいし,それを修正してもいい    し,また新しく入力してもいいが,それを使って答えを出す。  4:評価は,その答えが合っているかどうかで判定する。   (今回は,プログラムの中身は判定しない)  例:1から順に自然数を加えていくとき,初めて10000を越えるのはいつでしょう    (こんなのは,手計算でも分かりますね。)     でも,次のような問題になると,コンピュータがないと難しいでしょう。    1から順に素数を加えていくとき,初めて10000を越えるのはいつでしょう。    そのような問題をいくつか出題する予定です。   (なるべくやさしいのにする予定)

10.1 線型変換による直線の像を調べる

 入力すべきもの:a,b             (直線を決める)          a11,a12,a21,a22 (行列を決める)  出力     :直線および,その像  次のプログラムを解読しながら,入力し,実行してみてください。 SCREEN 12 MaxOfX = 15 PRINT "input the matrix" INPUT "a11"; a11 INPUT "a12"; a12 INPUT "a11"; a21 INPUT "a22"; a22 PRINT "input a,b which means the line y = a*x + b" INPUT "a="; a INPUT "b="; b DO CLS MaxOfY = MaxOfX * 480 / 640 dp = MaxOfX / 320 WINDOW (-MaxOfX, MaxOfY)-(MaxOfX, -MaxOfY) LINE (-MaxOfX, 0)-(MaxOfX, 0) FOR i = -INT(MaxOfX) TO INT(MaxOfX) LINE (i, 5 * dp)-(i, -5 * dp) NEXT LINE (0, -MaxOfY)-(0, MaxOfY) FOR i = -INT(MaxOfY) TO INT(MaxOfY) LINE (5 * dp, i)-(-5 * dp, i) NEXT FOR t = -MaxOfX TO MaxOfX STEP dp x = t y = a * x + b PSET (x, y), 2 Newx = a11 * x + a12 * y Newy = a21 * x + a22 * y PSET (Newx, Newy), 4 NEXT Restart: LOCATE 1, 1 PRINT "M:MaxOfX, T:Matrix, L:Line, Q:Quit" a$ = UCASE$(INPUT$(1)) SELECT CASE a$ CASE "M" INPUT "MaxOfX"; MaxOfX IF MaxOfX <= 0 THEN MaxOfX = 10 CASE "Q": EXIT DO CASE "L" INPUT "a="; a INPUT "b="; b CASE "T" PRINT "input the matrix" INPUT "a11"; a11 INPUT "a12"; a12 INPUT "a11"; a21 INPUT "a22"; a22 CASE ELSE BEEP GOTO Restart END SELECT LOOP

10.2 線型変換による円の像を調べる

 入力すべきもの:a11,a12,a21,a22 (行列を決める)  出力     :円および,その像  次のプログラムを解読しながら,入力し,実行してみてください。  なお,線型変換の場合には,原点を中心とする円を入力すればいいのですが,複素数で の1次変換を考える場合のことを考慮して,                 円の半径,中心 も設定できるようにしました。  これらのプログラムにおいて,線型変換の部分を,書き換えれば,様々な変換について 調べることができるはずです。 SCREEN 12 MaxOfX = 15 PRINT "input the matrix" INPUT "a11"; a11 INPUT "a12"; a12 INPUT "a11"; a21 INPUT "a22"; a22 r = 5 DO CLS MaxOfY = MaxOfX * 480 / 640 dp = MaxOfX / 320 WINDOW (-MaxOfX, MaxOfY)-(MaxOfX, -MaxOfY) LINE (-MaxOfX, 0)-(MaxOfX, 0) FOR i = -INT(MaxOfX) TO INT(MaxOfX) LINE (i, 5 * dp)-(i, -5 * dp) NEXT LINE (0, -MaxOfY)-(0, MaxOfY) FOR i = -INT(MaxOfY) TO INT(MaxOfY) LINE (5 * dp, i)-(-5 * dp, i) NEXT FOR t = -MaxOfX TO MaxOfX STEP dp x = r * COS(t) + x0 y = r * SIN(t) + y0 PSET (x, y), 2 Newx = a11 * x + a12 * y Newy = a21 * x + a22 * y PSET (Newx, Newy), 4 NEXT Restart: LOCATE 1, 1 PRINT "M:MaxOfX, T:Matrix,R:radius, C:center of circle, Q:Quit" a$ = UCASE$(INPUT$(1)) SELECT CASE a$ CASE "M" INPUT "MaxOfX"; MaxOfX IF MaxOfX <= 0 THEN MaxOfX = 10 CASE "R" PRINT "now radius ="; r INPUT "new radius ="; r CASE "C" INPUT "x0="; x0 INPUT "y0="; y0 CASE "Q": EXIT DO CASE "T" PRINT "input the matrix" INPUT "a11"; a11 INPUT "a12"; a12 INPUT "a11"; a21 INPUT "a22"; a22 CASE ELSE BEEP GOTO Restart END SELECT LOOP

10.3 乱数でπを調べる

 次のようにすると,乱数を使ってπを調べることができるというのですが,どうしてで しょうか。それを考えながら,作業をしてください。 SCREEN 12 MaxOfX = 1.5 CLS MaxOfY = MaxOfX * 480 / 640 dp = MaxOfX / 640 / 2 'dp = .1 WINDOW (-MaxOfX, MaxOfY)-(MaxOfX, -MaxOfY) LINE (-MaxOfX, 0)-(MaxOfX, 0) FOR i = -INT(MaxOfX) TO INT(MaxOfX) LINE (i, 10 * dp)-(i, -10 * dp) NEXT LINE (0, -MaxOfY)-(0, MaxOfY) FOR i = -INT(MaxOfY) TO INT(MaxOfY) LINE (10 * dp, i)-(-10 * dp, i) NEXT FOR i = 1 TO 100000 x = RND y = RND IF x ^ 2 + y ^ 2 < 1 THEN ct1 = ct1 + 1 PSET (x, y) ELSE PSET (x, y), 2 ct2 = ct2 + 1 END IF IF i MOD 100 = 0 THEN LOCATE 1, 1 PRINT ct1; ct2 PRINT ct1 * 4 / i END IF NEXT

10.4 ネルトン

 終わっちゃいましたね。ネルトン紅鯨団。あれを見ていて,「大体できるカップル数は 決まっている」と思った人はいませんか。そういう人は,なかなかセンスがいい。(ある いは野暮ということか。)  さて,ネルトンの場合には,女子に「拒否権」があるので,それをコンピュータでシミ ュレートすることはできないのですが,「第一印象いいもの同士」ならば,次のようにシ ミュレートはできます。  n人ずつの男女がいる。  それぞれ好きな人を一人決める。  それが合っていればおめでとう。  これをプログラムにすると, CLS DEFINT A-Z PRINT "Welcome to NELTON. How many members are there ?" INPUT num DIM man(num), lady(num), Result(num) FOR ct = 1 TO 1000 Couple = 0 FOR i = 1 TO num man(i) = INT(num * RND + 1) lady(i) = INT(num * RND + 1) NEXT FOR i = 1 TO num IF lady(man(i)) = i THEN Couple = Couple + 1 NEXT Result(Couple) = Result(Couple) + 1 LOCATE 1, 1 PRINT ct sum = 0 FOR i = 0 TO num PRINT i; "pairs : "; Result(i) sum = sum + Result(i) * i NEXT PRINT "Average : "; sum / ct; " "; NEXT

10.5 誕生日が同じ人はクラスの中にいるだろうか

 これも,よくある確率の問題ですが, 問題:このクラスの中に,「誕生日が同じ」二人の人がいる確率はいくつでしょう。    人数     予想     シミュレーションの結果   数学的結果    10人    15人    20人    25人    30人    35人    40人    45人  こういうのを計算するための手掛かりとして,次のプログラムを使うことができます。             (コメントは英語になおしてね) CLS DEFINT A-Z DIM Day(365) RANDOMIZE TIMER PRINT "どれくらいの人がいると,誕生日が同じ人がいるのでしょう。" PRINT "試しに実験をしてみましょう。" INPUT "人数"; NumOfMen CLS FOR i = 1 TO NumOfMen BirthDay = INT(RND * 365 + 1) LOCATE 2, 1 PRINT i; "人目"; BirthDay; Day(BirthDay) = Day(BirthDay) + 1 Month = 0 Day0 = 0 FOR ct = 1 TO 365 Day0 = Day0 + 1 SELECT CASE Month CASE 2: IF Day0 = 29 THEN Day0 = 1 CASE 4, 6, 9, 11: IF Day0 = 31 THEN Day0 = 1 CASE ELSE: IF Day0 = 32 THEN Day0 = 1 END SELECT IF Day0 = 1 THEN Month = Month + 1 PRINT END IF IF Day(ct) > 1 THEN COLOR 0, 7 ELSE COLOR 7, 0 PRINT STR$(Day(ct)); NEXT NEXT  また,これは「1回」調べているだけです。100程度実行して,確率を推測するプロ グラムにしてください。

10.6 確率と言えばつきものの...

 何でしょう。 Uma$ = " ̄/=\O"          ← もっともらしい形にしましょう                     ¥はバックスラッシュです。 CLS PRINT "Welcome!" INPUT "How many horses"; NumOfUma DIM Uma(NumOfUma) Money = 10000 RANDOMIZE TIMER DO PRINT "Your money : "; Money INPUT "Which horse do you bet(0-> end)"; Kake IF Kake = 0 THEN EXIT DO INPUT "How much do you bet"; KakeMoney LOCATE 7, 1 PRINT SPACE$(80 * (NumOfUma + 1)) FOR i = 1 TO NumOfUma LOCATE i + 7, 2 PRINT Uma$; LOCATE i + 7, 67 PRINT "|"; Uma(i) = 0 NEXT LOCATE Kake + 7, 67 PRINT "+"; DO Muchi = INT(NumOfUma * RND + 1) Uma(Muchi) = Uma(Muchi) + 1 LOCATE Muchi + 7, 2 * Uma(Muchi) - 1 PRINT " " + Uma$; IF Uma(Muchi) > 30 THEN EXIT DO FOR i = 1 TO 40000 \ (NumOfUma) NEXT LOOP PRINT " "; Muchi; " Goal !"; LOCATE 1, 1 PRINT SPACE$(80 * 6); LOCATE 1, 1 IF Muchi = Kake THEN Money = Money + KakeMoney * (NumOfUma - 1) PRINT " Nice! Go Go Next betting!" Kachi = Kachi + 1 ELSE Money = Money - KakeMoney Make = Make + 1 PRINT " Oh no!, but I want to get much money next." END IF LOOP CLS PRINT "Thank you." PRINT "you win : "; Kachi PRINT "you lose: "; Make PRINT "you get "; Money - 10000