C++ 如何改进c++;?
事实上,我应该说我的算法选择了一个定义范围内的数字 我写这篇文章只是出于好奇 我不是在挑战现有的库功能。 在基于随机性编写应用程序时,我总是使用库函数,但我再次声明,我只是出于好奇才想这样做 我也想知道我的算法或方法是否有问题。 因为我在谷歌上搜索了PRNG的工作原理,在一些网站上,他们说那里有一个数学算法,一个预定义的数字序列和一个种子只是将指针设置在序列中的一个不同点上,经过一些时间间隔,序列会自动重复 我的算法只是开始在可能的值数组中来回移动,种子每次用不同的值打破循环。我不认为这种方法是错误的。我得到的答案建议使用不同的算法,但他们没有解释我当前的算法有什么问题? 是的,我的种子有一个问题,因为它不精确,结果难以预测,如下所示: 库特< < 注册护士(50100) 四次运行结果分别为74,93,56,79 参见“递增顺序”模式 对于大范围的模式可以很容易地看到。我得到了一个关于获得好种子的答案,但这也推荐了一个新的算法(但没有说为什么?) 另一种方法是随机洗牌我的数组,每次都生成一个新的序列。递增顺序的模式会消失。任何重新排列的帮助也会很好。下面是代码。如果我的功能不可用,请通知我 提前感谢你C++ 如何改进c++;?,c++,c++11,shuffle,random-seed,C++,C++11,Shuffle,Random Seed,事实上,我应该说我的算法选择了一个定义范围内的数字 我写这篇文章只是出于好奇 我不是在挑战现有的库功能。 在基于随机性编写应用程序时,我总是使用库函数,但我再次声明,我只是出于好奇才想这样做 我也想知道我的算法或方法是否有问题。 因为我在谷歌上搜索了PRNG的工作原理,在一些网站上,他们说那里有一个数学算法,一个预定义的数字序列和一个种子只是将指针设置在序列中的一个不同点上,经过一些时间间隔,序列会自动重复 我的算法只是开始在可能的值数组中来回移动,种子每次用不同的值打破循环。我不认为这种方法是
int rn(int lowerlt, int upperlt)
{
/* Over short ranges, results are satisfactory.
* I want to make it effective for big ranges.
*/
const int size = upperlt - lowerlt; // Constant size of the integer array.
int ar[size]; // Array to store all possible values within defined range.
int i, x, ret; // Variables to control loops and return value.
long pointer = 0; //pointer variable. The one which breaks the main loop.
// Loop to initialize the array with possible values..
for (i=0, x=lowerlt; x <= upperlt; i++, x++)
ar[i]=x;
long seed = time(0);
//Main loop . To find the random number.
for (i=0; pointer <= seed; i++, pointer++)
{
ret = ar[i];
if (i == size-1)
{
// Reverse loop.
for (; i >= 0; i--)
{
ret=ar[i];
}
}
}
return ret;
}
int-rn(int-lowerlt,int-upperlt)
{
/*在短范围内,结果令人满意。
*我想让它对大范围有效。
*/
const int size=upperlt-lowerlt;//整数数组的常量大小。
int ar[size];//用于存储定义范围内所有可能值的数组。
int i,x,ret;//用于控制循环和返回值的变量。
long pointer=0;//指针变量。中断主循环的变量。
//循环以使用可能的值初始化数组。。
对于(i=0,x=lowerlt;x警告:从您的帖子中,除了您的随机生成器算法之外,您的一个问题是获得一个好的种子值,因此我将讨论这一部分
您可以使用/dev/random
获取种子值。这将是一个很好的起点[本身就足够了],但从某种角度来看可能被视为“作弊”
所以,这里有一些“熵”的其他来源:
使用更高分辨率的时间时钟源:gettimeofday
或clock\u gettime(clock\u REALTIME,…)
称之为“cur\u time”。分别使用微秒或纳秒部分,称之为“cur\u nano”。注意cur\u nano本身通常是非常随机的
执行getpid(2)
。这有一些不可预测的位,因为在调用之间,其他程序正在启动,我们不知道有多少
创建一个新的临时文件并获取文件的索引节点号[然后删除它]。这会随着时间的推移而缓慢变化。每次调用时它可能是相同的[或者不是]
获取系统启动时系统的时间时钟的高分辨率值,称之为“sysboot”
获取“会话”开始时间的高分辨率值:当程序的父shell启动时,将其称为“shell\u start”
如果您使用的是Linux,您可以计算/proc/interrupts
的校验和,因为它总是在变化。对于其他系统,请获取各种类型的中断数的散列值[应该可以从某种类型的系统调用中获得]
现在,创建上面所有内容的一些散列(例如):
这是一个简单的等式。你可以用一些XOR
和/或sum
操作来增强它。进行实验,直到得到一个适合你的
注意:这仅为您的PRNG提供种子值。您必须从其他内容创建PRNG(例如earl的线性算法)
“s”随着该函数的每次调用而增长。
正确的是
unsigned int Random::next() {
s = (1664525 * s + 1013904223) % xxxxxx;
return s;
}
也许可以使用这个功能
long long Factor = 279470273LL, Divisor = 4294967291LL;
long long seed;
next()
{
seed = (seed * Factor) % Divisor;
}
“主要问题”是编写RNG很难,没有什么特别值得推荐的方法。这个问题的答案只包括建议另一个现有的算法,你也可以自己找到,并从中获得更多好处。@EJP构建RNG是困难的还是不困难的,找到解决方案很重要。我知道库函数。我只是想寻求一些帮助。我只是想知道不同的编程技术。我是新来的。所以,按照我的建议,去找一个。而不是从猜测开始。你会学到很多。@EJP是的,我会找到一个。这就是我来这里的原因。如果你想写一个竞争性的w.r.t.现有的实现。因此,要么使用现有的实现(来自
),要么花数年时间研究它们。或者编辑您的问题,解释您为什么要编写一个。
unsigned int Random::next() {
s = (1664525 * s + 1013904223) % xxxxxx;
return s;
}
long long Factor = 279470273LL, Divisor = 4294967291LL;
long long seed;
next()
{
seed = (seed * Factor) % Divisor;
}