How to resolve the algorithm Average loop length step by step in the Ruby programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Average loop length step by step in the Ruby programming language

Table of Contents

Problem Statement

Let f be a uniformly-randomly chosen mapping from the numbers 1..N to the numbers 1..N (note: not necessarily a permutation of 1..N; the mapping could produce a number in more than one way or not at all). At some point, the sequence 1, f(1), f(f(1))... will contain a repetition, a number that occurring for the second time in the sequence.

Write a program or a script that estimates, for each N, the average length until the first such repetition. Also calculate this expected length using an analytical formula, and optionally compare the simulated result with the theoretical one.

This problem comes from the end of Donald Knuth's Christmas tree lecture 2011. Example of expected output:

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Average loop length step by step in the Ruby programming language

The provided Ruby code demonstrates how to calculate the average number of random numbers that need to be generated until one of them is repeated for a given range n. It also compares these empirical averages with their expected values derived from mathematical analysis.

Here's a detailed breakdown of the code:

  1. Extending the Integer class:

    • The code extends the Integer class with a factorial method that calculates the factorial of the integer. This method is used later in the analytical calculation of expected values.
  2. rand_until_rep method:

    • This method generates random numbers within a given range n and keeps track of the generated numbers in a rands hash.
    • It continues generating random numbers until a repeated number is encountered.
    • The number of random numbers generated until a repetition occurs is returned as the result.
  3. Main Execution:

    • The code sets runs to 1,000,000, indicating how many times the experiment should be run for each value of n.
  4. Table Header:

    • The code prints a table header with the following columns: "N" (range), "average" (empirical average), "exp." (expected value), and "diff" (percentage difference between empirical average and expected value).
  5. Loop Over Different n Values:

    • The code iterates over n values from 1 to 20.
    • For each n, it calculates the empirical average by running the rand_until_rep method runs times and accumulates the number of random numbers generated until repetition in the sum_of_runs variable. The average is then calculated by dividing the sum_of_runs by runs.
  6. Expected Value Calculation:

    • The expected value is calculated using mathematical analysis. It computes the sum of probabilities for each random number within the range n, taking into account the number of possible repetitions for each random number.
  7. Printing Results:

    • The code prints the n value, the empirical average, the expected value, and the percentage difference between the empirical average and expected value for each n value.

The output of the code is a table showing the empirical averages, expected values, and their percentage differences for different n values. This table helps analyze the behavior of the rand_until_rep method and compare its empirical results with theoretical expectations.

Source code in the ruby programming language

class Integer
  def factorial
    self == 0 ? 1 : (1..self).inject(:*)
  end
end

def rand_until_rep(n)
  rands = {}
  loop do
    r = rand(1..n)
    return rands.size if rands[r]
    rands[r] = true
  end
end

runs = 1_000_000

puts " N    average    exp.        diff   ",
     "===  ========  ========  ==========="
(1..20).each do |n|
  sum_of_runs = runs.times.inject(0){|sum, _| sum += rand_until_rep(n)}
  avg = sum_of_runs / runs.to_f
  analytical = (1..n).inject(0){|sum, i| sum += (n.factorial / (n**i).to_f / (n-i).factorial)}
  puts "%3d  %8.4f  %8.4f  (%8.4f%%)" % [n, avg, analytical, (avg/analytical - 1)*100]
end


  

You may also check:How to resolve the algorithm Write language name in 3D ASCII step by step in the Raku programming language
You may also check:How to resolve the algorithm Prime conspiracy step by step in the Java programming language
You may also check:How to resolve the algorithm Web scraping step by step in the PureBasic programming language
You may also check:How to resolve the algorithm Binary search step by step in the 360 Assembly programming language
You may also check:How to resolve the algorithm Multi-dimensional array step by step in the Objeck programming language