项目欧拉#149的滞后斐波纳契Rng

时间:2009-12-11 04:17:08

标签: c++ random

嘿伙计们,这很可能是我的全脑屁,但我希望有人可以看看下面的陈述,该陈述描述了如何设置滞后的斐波纳契线:

  

首先,使用所谓的“滞后斐波纳契生成器”的特定形式生成四百万个伪随机数:

     

对于1≤k≤55,s(k)= [100003 -   200003k + 300007k ^(3)](模数   1000000) - 500000。

     

对于56≤k≤4000000,s(k)= [s(k-24)   + s(k-55)+ 1000000](模数1000000) - 500000。

     

因此,s(10)= -393027和s(100)=   86613

所以看起来非常简单(这用于生成矩阵,然后是要解决的实际问题,这个link有问题)。无论如何,这是我的实现及其输出s(10)和s(100):

class lagged_fib
{
private:
    typedef std::deque<int> seed_list;
    seed_list seeds;
    size_t k;

public:
    lagged_fib()
    {
        k = 1;
    }
    int operator()()
    {
        if (k<56)
        {
            seeds.push_back(((100003 - 200003*k + 300007*k*k*k)%1000000) - 500000);
            k++;
        }
        else
        {
            seeds.push_back(((seeds[31]+seeds[0]+1000000)%1000000) - 500000);
            seeds.pop_front();
        }       
        return seeds.back();        
    }
};

哪个收益率:

s(10) = -393027
s(100) = -422827

你会注意到s(10)是预期的(因此可以肯定算法的第一部分是正确的),但s(100)不是。所以,希望有人能够发现我出错的地方,这让我感到困惑。

由于

2 个答案:

答案 0 :(得分:2)

看起来您的代码中存在整数溢出。

尝试使用int64_t类型而不是int。

答案 1 :(得分:1)

尝试使用long值而不是int值执行计算。初始化被k 20处的32位整数溢出破坏。

以下是intlong输出的摘录,后面是源代码。初始化部分打印内部值以显示溢出发生的位置。

integer arithmetic
  1:      200007  200007 -299993
  2:     2100053  100053 -399947
  3:     7600183  600183  100183
  4:    18500439  500439     439
  5:    36600863  600863  100863
  6:    63701497  701497  201497
  7:   101602383  602383  102383
  8:   152103563  103563 -396437
  9:   217005079    5079 -494921
 10:   298106973  106973 -393027
 11:   397209287  209287 -290713
 12:   516112063  112063 -387937
 13:   656615343  615343  115343
 14:   820519169  519169   19169
 15:  1009623583  623583  123583
 16:  1225728627  728627  228627
 17:  1470634343  634343  134343
 18:  1746140773  140773 -359227
 19:  2054047959   47959 -452041
 20: -1898811353 -811353 -1311353
 21: -1520702529 -702529 -1202529
 22: -1104792823 -792823 -1292823
 23:  -649282193 -282193 -782193
 24:  -152370597 -370597 -870597
 25:   387742007  742007  242007
 ...
 55: -1636843089 -843089 -1343089
 56:   94698
 ...
 99: -596227
100: -357419

long arithmetic
  1:      200007  200007 -299993
  2:     2100053  100053 -399947
  3:     7600183  600183  100183
  4:    18500439  500439     439
  5:    36600863  600863  100863
  6:    63701497  701497  201497
  7:   101602383  602383  102383
  8:   152103563  103563 -396437
  9:   217005079    5079 -494921
 10:   298106973  106973 -393027
 11:   397209287  209287 -290713
 12:   516112063  112063 -387937
 13:   656615343  615343  115343
 14:   820519169  519169   19169
 15:  1009623583  623583  123583
 16:  1225728627  728627  228627
 17:  1470634343  634343  134343
 18:  1746140773  140773 -359227
 19:  2054047959   47959 -452041
 20:  2396155943  155943 -344057
 21:  2774264767  264767 -235233
 22:  3190174473  174473 -325527
 23:  3645685103  685103  185103
 24:  4142596699  596699   96699
 25:  4682709303  709303  209303
 ...
 55: 49902764463  764463  264463
 56:   29290
 ...
 99: -119491
100:   86613

public class LaggedFib {

    public static void main(String[] args) {
        int[] buffer = new int[56];
        computeInt(buffer);
        computeLong(buffer);
    }

    private static void computeInt(int[] buffer) {
        System.out.println("\n    integer arithmetic");
        for (int k = 1; k < 56; ++k) {
            int partial = 100003 - 200003 * k + 300007 * k * k * k;
            int modded = partial % 1000000;
            buffer[k] = modded - 500000;
            System.out.printf("    %3d: %11d %7d %7d\n", k, partial, modded, buffer[k]);
        }
        for (int k = 56; k <= 100; ++k) {
            int p24 = (k - 24) % 56;
            int p55 = (k - 55) % 56;
            int pk  = k % 56;
            buffer[pk] = ((buffer[p24] + buffer[p55] + 1000000) % 1000000) - 500000;
            System.out.printf("    %3d: %7d\n", k, buffer[pk]);
        }
    }

    private static void computeLong(int[] buffer) {
        System.out.println("\n    long arithmetic");
        for (int k = 1; k < 56; ++k) {
            long partial = 100003L - 200003L * k + 300007L * k * k * k;
            long modded = partial % 1000000L;
            buffer[k] = (int) (modded - 500000L);
            System.out.printf("    %3d: %11d %7d %7d\n", k, partial, modded, buffer[k]);
        }
        for (int k = 56; k <= 100; ++k) {
            int p24 = (k - 24) % 56;
            int p55 = (k - 55) % 56;
            int pk  = k % 56;
            buffer[pk] = (int)(((buffer[p24] + buffer[p55] + 1000000L) % 1000000L) - 500000L);
            System.out.printf("    %3d: %7d\n", k, buffer[pk]);
        }
    }

}