−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
応用数学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