下面是Bays&Durham的伪代码实现,我正在尝试使用c#中的内置随机数对随机数序列进行排序。
我遵循的伪代码是:
生成随机数(V)的数组
会生成一个随机数(Y)-种子应该是数组中的最后一个数字
使用以下公式生成随机索引(y):(K * Y)/ m 哪里: K-数组大小 Y-生成的随机数 M-用于填充数组的随机数生成器中使用的模数
返回数组Y位置处的元素,即V [y]
数组中Y位置的元素本身设置为Y,即V [y] = Y
int[] seq = GetRand(size, min, max);
int nextRand = cRNG.Next(seq[seq.Length-1]);
//int index = (seq.Length * nextRand) / [Add Modulus];
return seq;
我可以遵循的前几个步骤。现在,我需要返回一个改组后的数组,因此需要对伪代码进行一些修改。
上面的代码很少有指针: cRNG-> Random的实例名称 GetRand(...)->使用cRNG进行forloop
现在我不了解的是以下内容:
1)鉴于我正在使用内置随机变量,如何获得用于填充数组的模数,因为它只是使用cRNG.Next(min,max)的for循环
2)最后一步,我还不完全了解
任何帮助将不胜感激!
[编辑]
按照塞缪尔·维达(Samuel Vidal)的解决方案行之有效? (假设我必须用一种方法完成所有操作)
public static int[] Homework(int size, int min, int max)
{
var seq = GetRand(size, min, max);
nextRand = cRNG.Next(min, max);
var index = (int) ((seq.Length * (double) (nextRand - min)) / (max - min));
nextRand = seq[index];
seq[index] = cRNG.Next(min, max);
return sequence; // nextRand that should be returned instead.
// Made it return the array because it should return the newly shuffled array hence the for loop
}
答案 0 :(得分:0)
我认为您想要的是以下
var index = (int) ((sequence.Length * (double)(randNum - min)) / (max - min));
但是我建议您使用源中未更改的随机数填充数组,然后将随机数生成器的输出映射为区间[min, max[
作为重载方法Next(int min, int max)
来调用, Bays-Durham随机播放过程的输出。
public class BaysDurham
{
private readonly int[] t;
private int y; // auxiliary variable
// Knuth TAOCP 2 p. 34 Algorithm B
public BaysDurham(int k)
{
t = new int[k];
for (int i = 0; i < k; i++)
{
t[i] = rand.Next();
}
y = rand.Next();
}
public int Next()
{
var i = (int)(((long) t.Length * y) / int.MaxValue);
y = t[i];
t[i] = rand.Next();
return y;
}
public int Next(int min, int max)
{
long m = max - min;
return min + (int) ((Next() * m) / int.MaxValue);
}
private readonly Random rand = new Random();
}
通常,拥有separation of concerns是一个很棒的软件设计原则。
测试代码:
[Test]
public void Test()
{
const int k = 30;
const int n = 1000 * 1000;
const int min = 10;
const int max = 27;
var rng = new BaysDurham(k);
var count = new int[max];
for (int i = 0; i < n; i++)
{
var index = rng.Next(min, max);
count[index] ++;
}
Console.WriteLine($"Expected : {1.0 / (max - min):F4}, Actual :");
for (int i = min; i < max; i++)
{
Console.WriteLine($"{i} : {count[i] / (double) (n):F4}");
}
}
结果:
Expected : 0.0588, Actual :
10 : 0.0584
11 : 0.0588
12 : 0.0588
13 : 0.0587
14 : 0.0587
15 : 0.0589
16 : 0.0590
17 : 0.0592
18 : 0.0586
19 : 0.0590
20 : 0.0586
21 : 0.0588
22 : 0.0586
23 : 0.0587
24 : 0.0590
25 : 0.0594
26 : 0.0590