練習問題

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 型に四則演算を行うメソッドを追加してください.

ヒント

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 の結果を返す.
    }
}

それぞれのメソッドの中では,thisvalue も値を変更せず,新たな実体を作成し,その実体に適切な値を設定して返して(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