/** * Code for exercise 3 * Lecture Series Informatik II D-BAUG ETH Zürich * Felix Friedrich, Georg Ofenbeck, Lars Widmer */ class LCG { //this is the random number generator from last exercise static final long m = 2147483647; static final long b = 12345; static final long a = 1103515245; static long u = 0; //to use within the judge we fix the "seed", such that we always get the same random numbers public static double Uniform(){ u = (u * a + b) % m; return(double)u/m; } } // provide your modifications in this class only class RandomSurfer{ // pre: non-empty matrix m // post: matrix printout on System.out public static void printMatrix(double[][] m) { int rows = m.length; int cols = m[0].length; System.out.println(rows + " " + cols); for(int r = 0; r < rows; r++){ for (int c = 0; c < cols; c++){ System.out.printf("%7.5f ", m[r][c]); } System.out.println(""); } } // pre: matrix data provided via scanner // post: returns matrix data public static double[][] readMatrix(java.util.Scanner scanner){ int M = scanner.nextInt(); // Zeilen int N = scanner.nextInt(); // Spalten // Daten double[][] p = new double[M][N]; for (int i = 0; i < M; i++) for (int j = 0; j < N; j++) p[i][j] = scanner.nextDouble(); return p; } // pre: non-empty input vector of length N, matrix of size N times M // post: return vector-matrix product v * m. Vector of size M public static double[] multiplyVectorMatrix(double[] v, double[][] m) { int N = v.length; int M = m[0].length; double[] res = new double[M]; // result vector for (int c=0; c < M; ++c) { // for every column of the matrix res[c] = 0; // initial value (actually also done by the java VM) for (int r=0; r 0 // returns if v * m is close at v public static boolean checkConvergence(double[] v, double[][] P, double precision){ double[] product = multiplyVectorMatrix(v, P); for (int i = 0; i < v.length; i++) if (Math.abs(product[i] - v[i]) > precision) return false; return true; } // single step simulation from the lecture public static int simulateLine(double[] prob) { int res=0; double r = LCG.Uniform(); double sum = 0.0; for (int j = 0; j < prob.length; j++) { sum += prob[j]; if (r < sum) {res = j; break;} } return res; } // pre: non-empty probability matrix P // post: return relative frequencies of visits in each point // after MCMC simulation until convergence reached public static double[] simulate(double[][] P, double precision) { int N = P.length; int[] freq = new int[N]; // freq[i] = # times surfer hits page i int page = 0; // start at page 0 int max_steps = 10000000; double[] inv_freq = new double [N]; int t = 1; do { page = simulateLine(P[page]); freq[page]++; long sum = 0; for(int i = 0; i < freq.length; i++) sum += freq[i]; for(int i = 0; i < freq.length; i++) inv_freq[i] = (double)1.0/sum*freq[i]; t++ ; } while (t <= max_steps && !checkConvergence(inv_freq, P, precision)); //System.out.println("converged after " +t + " steps"); return inv_freq; } // pre: non-null vector // post: vector output to standard out public static void show(double[] v) { for (int i=0; i