Advertisement
Guest User

Implementing Jean-Claudes answer on MO https://math.stackexchange.com/a/4245115/12879

a guest
Sep 8th, 2021
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.37 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <random>
  4. #inlude <vector>
  5.  
  6. /**
  7.  * Math overflow Q, with a very nice answer by Jean-Claude Arbaut
  8.  * https://math.stackexchange.com/questions/4244997/estimating-the-value-of-e-using-a-random-function
  9.  */
  10.  
  11.  
  12. /**
  13.  * requires the sizes of the input to be equal
  14.  * @param permutation
  15.  * @param original
  16.  * @return false if any element perm[i] = orig[i] otherwise true
  17.  */
  18. bool is_derangement(const std::vector<int>& permutation, std::vector<int>& original){
  19.     auto first = permutation.begin();
  20.     auto last = permutation.end();
  21.     auto comp_iter = original.begin();
  22.     while(first != last){
  23.         if(*first == *comp_iter){
  24.             return false;
  25.         }
  26.         first++;
  27.         comp_iter++;
  28.     }
  29.     return true;
  30. }
  31. /**
  32.  *
  33.  * @param N
  34.  * @return A vector containing 0..N
  35.  */
  36. std::vector<int> generate_vec(size_t N){
  37.     std::vector<int> v(N);
  38.     auto counter = 0;
  39.     auto incrementor = [&counter](){
  40.         return counter++;
  41.     };
  42.     std::generate(v.begin(), v.end(), incrementor);
  43.     return v;
  44. }
  45.  
  46. auto VEC_SIZE = 1000;
  47. std::random_device rd;
  48. std::mt19937 g(rd());
  49.  
  50. double derangement_fraction(int n_samples){
  51.     auto derangements = 0U;
  52.     for(auto i = 0; i < n_samples; i++){
  53.         auto vec = generate_vec(VEC_SIZE);
  54.         auto original = vec;
  55.         std::shuffle(vec.begin(), vec.end(), g);
  56.         if (is_derangement(vec, original)){
  57.             derangements++;
  58.         }
  59.     }
  60.     return n_samples * 1.0 / derangements;
  61. }
  62.  
  63. using E = double;
  64. template <typename IT>
  65. E std_dev(IT begin, IT end){
  66.     auto N = std::distance(begin, end);
  67.     E average = std::accumulate(begin, end, E()) / N;
  68.     auto sum_term = [average](E init, E value)-> E{
  69.         return init + (value - average)*(value - average);
  70.     };
  71.     E variance = std::accumulate(begin,  end, E(), sum_term);
  72.     return std::sqrt(variance * 1.0 / (N - 1));
  73. }
  74. int main() {
  75.     auto sum = 0.0;
  76.     auto MAX_COUNT = 1000U;
  77.     auto SAMPLES = 10000U;
  78.     auto results = std::vector<double>();
  79.     for(auto count = 0U; count < MAX_COUNT; count++ ){
  80.         results.push_back(derangement_fraction(SAMPLES));
  81.     }
  82.     auto avg = std::accumulate(results.begin(), results.end(), 0.0) / results.size();
  83.     auto stddev = std_dev(results.begin(), results.end());
  84.     std::cout << "e = " << avg << " +-" << stddev << "\n";
  85. }
  86.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement