使用随机“预定义”值填充数组,不重复且快速

时间:2016-12-21 04:49:33

标签: javascript arrays algorithm discrete-mathematics

我的问题是性能问题:

  • 我想填充N x N数组,其中N从2 ... 10开始;
  • 值必须来自字母[a,b,c],所有这些都是整数;
  • 目标是生成具有该字母表的那些阵列的所有可用排列的样本。

我想生成5M个不同的唯一数组。对于任意N. 如果(N <4)我想生成所有这些,因为有43046721个唯一组合。

我的尝试,我尝试过解决这个问题的方法种类繁多:

将矩阵表示为三元数(实际上是它)。 基本上我传递一个整数并将其转换为三元表示(对于模块/分区来说它很慢)。

我也试过,创建一个数组[NxN]并递归循环字母表改变我所在的索引,这将生成所有矩阵,并且当N值较大时实际上不能生成随机样本。

我创建了一个函数,当N很大时,它似乎是最有效的创建随机样本:授予它生成大量重复值,我试图用js对象/ hashset缓解,因为matrice基本上是a三元数,我可以从矩阵中的数字计算出ID。

function ipow( base,  exp)
{
    var result = 1;
    while (exp)
    {
        if (exp & 1)
            result *= base;
        exp >>= 1;
        base *= base;
    }

    return result;
}


var alphabet = [0, 1, -1];
var array = [];
var N = 4;
var repeated = 0;
var hashset = {};
var correct = 0;


for (var j = 0; j < 43046721; j++) {
    var matrixId = 0;
        array= [];
    for (var i = 0; i < N * N; i++) {
        var index = Math.floor(Math.random() * alphabet.length);
        var alph = array[index];
        array[i] = alph;
        matrixId += ipow(3,i) * index;
    } 
    if (hashset[matrixId] != null)
    {
        repeated++;
        if ( repeated < 5000000)
            j--;
    }    
    else
    {
        hashset[matrixId] = true;
        matrixId = 0;
        correct++;
    }        
}

示例代码在JS中,但我并不关心,我只是想找到一种更好/更快的方法。

1 个答案:

答案 0 :(得分:0)

我更喜欢三元表示法。要克服性能问题:

您已经花费了大量内存来存储已使用组合的哈希表。 但是有可能为某些数字范围制作一个具有三元表示的表格。

计算此表一次,并使用它从新生成的数字填充数组的每一行。

也许,JS内置随机生成器的行为和周期不是很好(我不知道) - 所以尝试更高级的PRNG如Mersenne twister来减少(忽略?)重复的概率相同的数字序列(移动K * number_of_rows)。