練習問題
1. 線形合同法による擬似乱数列
線形合同法(Linear Congruential Generators)を用いて,0〜1の範囲の乱数をコマンドライン引数で指定された数だけ求めてください.
コマンドライン引数で何も指定されなかった場合は,10が指定されたものとしてください.
クラス名は LinearCongruentialGenerator
としてください.
このプログラムも,素数の一覧
と同じように ArrayList<Double>
を返すメソッドを作成し,
返されたArrayList<Double>
の実体をそのままSystem.out.println
に渡してください.
線形合同法は,擬似乱数を発生させるアルゴリズムです.以下の漸化式で求めます.
$X_{n+1}=(A\times X_n + B) \mod M$
$A$,$B$,$M$は定数です.$A$は自分の誕生日(月日.3桁もしくは4桁),$B$は1, $M$は65535,$X_0$は自分の年齢としてください. 完成すれば,$A$,$B$,$M$,$X_0$の値を変更して結果がどのように変わるかを確認しましょう. ただし,$A<M$,$B<M$である必要があります.
この問題は,必ずしも再帰呼び出しで作成する必要はありません.
なお,C言語の rand
関数は,この線形合同法を用いて計算されています.
出力例
各自の出力結果は,以下のものと異なる値になります.
$ java LinearCongruentialGenerator
[0.019073486328125, 0.308502197265625, 0.329376220703125, 0.855133056640625, 0.471710205078125, 0.077545166015625, 0.383575439453125, 0.413238525390625, 0.002471923828125, 0.299713134765625]
$ java LinearCongruentialGenerator 2
[0.019073486328125, 0.308502197265625]
$ java LinearCongruentialGenerator 5
[0.019073486328125, 0.308502197265625, 0.329376220703125, 0.855133056640625, 0.471710205078125]
ヒント
乱数値はDouble
型で求めますが,$X_{n+1}$ の計算式はInteger
型で計算する必要があります.
つまり,結果を保存するとき,$X_{n+1}$ を $M$で割り,Integer
型からDouble
型に変換する必要があります.
ArrayList<Double> random(Integer max){
ArrayList<Double> results = // 結果を格納するリストを作成する.
Integer a, xn, b, m;
xn = 20; // X0(自分の年齢)
// a, b, m にも初期値を代入する.
// 以下の2行を指定回数繰り返す.
xn = // 線形合同法の計算式に従い,X_n+1 を求める.
results.add(1.0 * xn / m);
// xnを0.0〜1.0の範囲に変換してリストに追加する.
return results;
}
2. ニュートン法による立方根の計算
ニュートン法による平方根の計算を参考に立方根を求めてください.
クラス名は,CubicRoot
とします.
出力例
$ java CubicRoot 2 3 4 5 6 8 27
cubic_root(2.000000) = 1.259921
cubic_root(3.000000) = 1.442250
cubic_root(4.000000) = 1.587401
cubic_root(5.000000) = 1.709976
cubic_root(6.000000) = 1.817121
cubic_root(8.000000) = 2.000000
cubic_root(27.000000) = 3.000000
3. Fibonacci数列(任意桁)
第1講の練習問題 5. Fibonacci数列を改良し,桁あふれを起こさないようにしてください.
再帰呼び出しではなく,単純な繰り返しでFibonacci数列の$n$項目を求めてください(単純な再帰呼び出しにすると,非常に遅くなるため).
クラス名はBigFibonacci
としてください.
Fibonacci数列を Integer
型で扱うと,第47項目の計算で桁あふれを起こします.
コマンドライン引数に値が指定されない場合は,10項目が指定されたものとしてください. コマンドライン引数に複数個の数値が与えられた場合,全ての数値に対して結果を出力してください.
出力例
$ java BigFibonacci
fibonacci(10) = 55
$ java BigFibonacci 10 30 46 47 48 49 50
fibonacci(10) = 55
fibonacci(30) = 832040
fibonacci(46) = 1836311903
fibonacci(47) = 2971215073
fibonacci(48) = 4807526976
fibonacci(49) = 7778742049
fibonacci(50) = 12586269025
4. Complexの四則演算
Complex
型に四則演算を行うメソッドを追加してください.
Complex
同士の足し算(add
)- $(a + bi) + (c + di) = (a + c) + (b + d)i$
Complex
同士の引き算(subtract
)- $(a + bi) - (c + di) = (a - c) + (b - d)i$
Complex
同士の掛け算(multiply
)- $(a + bi)(c + di) = (ac - bd) + (ad + bc)i$
Complex
同士の割り算(divide
)- $(a + bi) / (c + di) = \frac{(a + bi)(c - di)}{(c + di)(c - di)} = \frac{(ac + bd) + (bc - ad)i}{c^2 + d^2}$
- 上記4つのメソッドは1つの
Complex
型の値を受け取り,新たなComplex
型の実体を返します.- 引数で受け取った
Complex
型の値は変更せずに,新たなComplex
型の実体を作成してください.
- 引数で受け取った
ComplexCalculator
のrun
メソッドに次の処理を追加してください.- 2つの
Complex
型の実体を作成してください.- 値はプログラム中で適当に指定してください.
- 上記の4つのメソッドを呼び出し,四則演算の結果を出力してください.
- 2つの
ヒント
public class Complex{
// ...
Complex add(Complex value){
// this + value の結果を返す.
}
Complex subtract(Complex value){
// this - value の結果を返す.
}
Complex multiply(Complex value){
// this * value の結果を返す.
}
Complex divide(Complex value){
// this / value の結果を返す.
}
}
それぞれのメソッドの中では,this
も value
も値を変更せず,新たな実体を作成し,その実体に適切な値を設定して返して(return
)ください.
例題 conjugate
が参考になるでしょう.
出力例
$ java ComplexCalculator
absoluate( 5.00 + -6.00 i) = 7.810250
conjugate( 5.00 + -6.00 i) = 5.00 + 6.00 i
5.00 + -6.00 i + 3.00 + 2.00 i = 8.00 + -4.00 i
5.00 + -6.00 i - 3.00 + 2.00 i = 2.00 + -8.00 i
5.00 + -6.00 i * 3.00 + 2.00 i = 27.00 + -8.00 i
5.00 + -6.00 i / 3.00 + 2.00 i = 0.23 + -2.15 i