【问题标题】:Pick random combination from 194481 possibilities从 194481 种可能性中选择随机组合
【发布时间】:2016-05-18 21:44:31
【问题描述】:

我有一个包含 194481 个排列的文件 0,1,2,3,4,5,6,...,21

看起来像这样;

[0,0,0,0],[0,0,0,1],[0,0,0,2],[0,0,0,3],[0,0,0,4],[0,0,0,5],[0,0,0,6],[0,0,0,7],[0,0,0,8],[0,0,0,9],[0,0,0,10],[0,0,0,11],[0,0,0,12],[0,0,0,13],[0,0,0,14],[0,0,0,15],[0,0,0,16],[0,0,0,17],[0,0,0,18],[0,0,0,19],[0,0,0,20],[0,0,1,0],[0,0,1,1],[0,0,1,2],[0,0,1,3],[0,0,1,4],[0,0,1,5],[0,0,1,6],[0,0,1,7],[0,0,1,8],[0,0,1,9],[0,0,1,10],[0,0,1,11],[0,0,1,12],[0,0,1,13],[0,0,1,14],[0,0,1,15],[0,0,1,16],[0,0,1,17],[0,0,1,18],[0,0,1,19],[0,0,1,20],[0,0,2,0],[0,0,2,1],[0,0,2,2],[0,0,2,3],[0,0,2,4],[0,0,2,5],[0,0,2,6],[0,0,2,7],[0,0,2,8],[0,0,2,9],[0,0,2,10],[0,0,2,11],[0,0,2,12],[0,0,2,13],[0,0,2,14],[0,0,2,15],[0,0,2,16],[0,0,2,17],[0,0,2,18],[0,0,2,19],[0,0,2,20],[0,0,3,0],[0,0,3,1],[0,0,3,2],[0,0,3,3],[0,0,3,4],[0,0,3,5],[0,0,3,6],[0,0,3,7],[0,0,3,8],[0,0,3,9],[0,0,3,10],[0,0,3,11],[0,0,3,12],[0,0,3,13],[0,0,3,14],[0,0,3,15],[0,0,3,16],[0,0,3,17],[0,0,3,18],[0,0,3,19],[0,0,3,20],[0,0,4,0],[0,0,4,1],[0,0,4,2],[0,0,4,3],[0,0,4,4],[0,0,4,5],[0,0,4,6],[0,0,4,7],[0,0,4,8],[0,0,4,9],[0,0,4,10],[0,0,4,11],[0,0,4,12],[0,0,4,13],[0,0,4,14],[0,0,4,15],[0,0,4,16],[0,0,4,17],[0,0,4,18],[0,0,4,19],[0,0,4,20],[0,0,5,0],[0,0,5,1],[0,0,5,2],[0,0,5,3],[0,0,5,4],[0,0,5,5],[0,0,5,6],[0,0,5,7],[0,0,5,8],[0,0,5,9],[0,0,5,10],[0,0,5,11],[0,0,5,12],[0,0,5,13],[0,0,5,14],[0,0,5,15],[0,0,5,16],[0,0,5,17],[0,0,5,18],[0,0,5,19],[0,0,5,20],[0,0,6,0],[0,0,6,1],[0,0,6,2],[0,0,6,3],[0,0,6,4],[0,0,6,5],[0,0,6,6],[0,0,6,7],[0,0,6,8],[0,0,6,9],[0,0,6,10],[0,0,6,11],[0,0,6,12],[0,0,6,13],[0,0,6,14],[0,0,6,15],[0,0,6,16],[0,0,6,17],[0,0,6,18],[0,0,6,19],[0,0,6,20],[0,0,7,0],[0,0,7,1],[0,0,7,2],[0,0,7,3],[0,0,7,4],[0,0,7,5],[0,0,7,6],[0,0,7,7],[0,0,7,8],[0,0,7,9],[0,0,7,10],[0,0,7,11],[0,0,7,12],[0,0,7,13],[0,0,7,14],[0,0,7,15],[0,0,7,16],[0,0,7,17],[0,0,7,18],[0,0,7,19],[0,0,7,20],[0,0,8,0],[0,0,8,1],[0,0,8,2],[0,0,8,3],[0,0,8,4],[0,0,8,5],[0,0,8,6],[0,0,8,7],[0,0,8,8],[0,0,8,9],[0,0,8,10],[0,0,8,11],[0,0,8,12],[0,0,8,13],[0,0,8,14],[0,0,8,15],[0,0,8,16],[0,0,8,17],[0,0,8,18],[0,0,8,19],[0,0,8,20],[0,0,9,0],[0,0,9,1],[0,0,9,2],[0,0,9,3],[0,0,9,4],[0,0,9,5],[0,0,9,6],[0,0,9,7],[0,0,9,8],[0,0,9,9],[0,0,9,10],[0,0,9,11],[0,0,9,12],[0,0,9,13],[0,0,9,14],[0,0,9,15],[0,0,9,16],[0,0,9,17],[0,0,9,18],[0,0,9,19],[0,0,9,20],[0,0,10,0],[0,0,10,1],[0,0,10,2],[0,0,10,3],[0,0,10,4],[0,0,10,5],[0,0,10,6],[0,0,10,7],[0,0,10,8],[0,0,10,9],[0,0,10,10],[0,0,10,11],[0,0,10,12],[0,0,10,13],[0,0,10,14],[0,0,10,15],[0,0,10,16],[0,0,10,17],[0,0,10,18],[0,0,10,19],[0,0,10,20],[0,0,11,0],[0,0,11,1],[0,0,11,2],[0,0,11,3],[0,0,11,4],[0,0,11,5],[0,0,11,6],[0,0,11,7],[0,0,11,8],[0,0,11,9],[0,0,11,10],[0,0,11,11],[0,0,11,12],[0,0,11,13],[0,0,11,14],[0,0,11,15],[0,0,11,16],[0,0,11,17],[0,0,11,18],[0,0,11,19],[0,0,11,20],[0,0,12,0],[0,0,12,1],[0,0,12,2],[0,0,12,3],[0,0,12,4],[0,0,12,5],[0,0,12,6],[0,0,12,7],[0,0,12,8],[0,0,12,9],[0,0,12,10],[0,0,12,11],[0,0,12,12],[0,0,12,13],[0,0,12,14],[0,0,12,15],[0,0,12,16],[0,0,12,17],[0,0,12,18],[0,0,12,19],[0,0,12,20],[0,0,13,0],[0,0,13,1],[0,0,13,2],[0,0,13,3],[0,0,13,4],[0,0,13,5],[0,0,13,6],[0,0,13,7],[0,0,13,8],[0,0,13,9],[0,0,13,10],[0,0,13,11],[0,0,13,12],[0,0,13,13],[0,0,13,14],[0,0,13,15],[0,0,13,16],[0,0,13,17],[0,0,13,18],[0,0,13,19],[0,0,13,20],[0,0,14,0],[0,0,14,1],[0,0,14,2],[0,0,14,3],[0,0,14,4],[0,0,14,5],[0,0,14,6],[0,0,14,7],[0,0,14,8],[0,0,14,9],[0,0,14,10],[0,0,14,11],[0,0,14,12],[0,0,14,13],[0,0,14,14],[0,0,14,15],[0,0,14,16],[0,0,14,17],[0,0,14,18],[0,0,14,19],[0,0,14,20],[0,0,15,0],[0,0,15,1],[0,0,15,2],[0,0,15,3],[0,0,15,4],[0,0,15,5],[0,0,15,6],[0,0,15,7],[0,0,15,8],[0,0,15,9],[0,0,15,10],[0,0,15,11],[0,0,15,12],[0,0,15,13],[0,0,15,14],[0,0,15,15],[0,0,15,16],[0,0,15,17],[0,0,15,18],[0,0,15,19],[0,0,15,20],[0,0,16,0],[0,0,16,1],[0,0,16,2],[0,0,16,3],[0,0,16,4],[0,0,16,5],[0,0,16,6],[0,0,16,7],[0,0,16,8],[0,0,16,9],[0,0,16,10],[0,0,16,11],[0,0,16,12],[0,0,16,13],[0,0,16,14],[0,0,16,15],[0,0,16,16],[0,0,16,17],[0,0,16,18],[0,0,16,19],[0,0,16,20],[0,0,17,0],[0,0,17,1],[0,0,17,2],[0,0,17,3],[0,0,17,4],[0,0,17,5],[0,0,17,6],[0,0,17,7],[0,0,17,8],[0,0,17,9],[0,0,17,10],[0,0,17,11],[0,0,17,12],[0,0,17,13],[0,0,17,14],[0,0,17,15],[0,0,17,16],[0,0,17,17]... etc.

结束于 [20,20,20,20]。

我需要从文件中挑选 50 个组合并将其分配给一个变量,这样就可以了

var combinationsArr = [
[0,0,17,9],[0,0,17,10],[0,0,17,11],[0,0,17,12]
]; //BUT 50 of them

如果它只是像[0,0,0,0],[0,0,0,1],[0,0,0,2],[0,0,0,3],[0,0,0,4],[0,0,0,5],[0,0,0,6],[0,0,0,7],[0,0,0,8],[0,0,0,9],[0,0,0,10],[0,0,0,11],[0,0,0,12] 这样的顺序就可以了,而不必像[1,2,3,4],[9,12,13,15],[20,12,6,7] 那样超级随机

只要能挑出50个就行。

我这样做是因为 194481 组合很多并且使我的程序很卡。所以我决定把它放在一个文本文件中,然后从文本文件中选择随机点,比如从 [0,0,0,1] 到 [0,0,0,50] 或 如果可能的话,从 [0,1,0,0] 到 [0,1,0,49]。

因为我必须生成一个随机组合。我有另一个不应该生成的组合数组。我们称之为 notAllowedArr。

var notAllowedArr = [
[0,0,17,9],[0,0,17,12]
];

我在想,我将生成 50 个组合并删除 notAllowedArr 中列出的组合,然后从 combinationArr 中选择一个作为最终结果。我仍然需要找到代码来从 combinationArr 中删除它们,但结果应该是这样的。

var combinationsArr = [[0,0,17,10],[0,0,17,11]];

然后我将有一个代码从combinationsArr 中选择一个随机值。 例子。组合Arr[0]。

所以最终的结果是; [0,0,17,10]

谁有更好的解决方案?

【问题讨论】:

  • 如果你一次读一行,你的程序不会崩溃:var lineReader = require('readline').createInterface({ input: require('fs').createReadStream('permutations.txt') }); lineReader.on('line', function (lineOfPermutations) { console.log('Line from file:', lineOfPermutations); }); 这样你就可以很容易地得到随机排列

标签: javascript jquery arrays algorithm random


【解决方案1】:

我只是想到了一个更好的方法。 我想我会做一个生成随机组合的函数。

然后检查它是否存在于notAllowedArr中。如果存在,它将生成另一个。如果不是,那将返回该组合:D

我认为这会更快^^;

【讨论】:

  • 如果您需要每个组合都是唯一的,您可以通过它们的总和来整理组合,即[0,0,0,1]是1,[0,2,0,0]是2 . 然后当你想检查它是否已经生成时,你只需首先检查总和是否存在,然后从那里检查已经生成的组合。这将比每次检查所有生成的结果要快。
  • @yoneal: [2,2,2,2] 与 [0,8,0,0] 具有相同的和
  • @SamAxe:是的,所以您只检查总和相同的结果子集,而不是整个结果集。
【解决方案2】:

这样的事情应该可以工作(在我的脑海中并且没有经过测试/调试):

var samples = new Array();

for(var index = 0; index < 50; index++) {
    samples.push(generatePermutation());
}

function generatePermutation() {
    var result = [Math.floor(Math.random() * 20) + 1,
                  Math.floor(Math.random() * 20) + 1,
                  Math.floor(Math.random() * 20) + 1,
                  Math.floor(Math.random() * 20) + 1];
}

【讨论】:

  • 是的.. 我想我会这样做然后检查生成的值是否存在于 notAlloweArr 中。如果是,我将再次生成Permutation()。
【解决方案3】:

如果我理解正确,您需要选择一个随机组合,该组合不在禁止组合列表中。

您可以将 0 到 20 的四个数字的组合视为 0 到 194480 的以 base-21 表示法的数字。因此,我们不必将所有组合存储在文件中,只需选择一个随机数并将其转换为 base-21。

要在某些值被禁止的范围内选择一个随机数,请在 0 到最大值减去禁止值的数量的范围内选择一个数字;然后从小到大遍历禁止值,并在每次找到较小或相等的禁止值时增加随机数。

这将确保每个组合具有相同的被选中概率,并避免重复选择禁止组合的可能性。

function randomBase21(skip) {
    var dec = [], result = [], num;
    // CONVERT FORBIDDEN COMBINATIONS FROM BASE-21 TO DECIMAL AND SORT
    for (var i = 0; i < skip.length; i++) {
        dec[i] = skip[i][0] * 9261 + skip[i][1] * 441 + skip[i][2] * 21 + skip[i][3];
    }
    dec.sort(function(a, b){return a - b});
    // GENERATE RANDOM NUMBER FROM 0 TO MAX - NUMBER OF FORBIDDEN COMBINATIONS
    num = Math.floor(Math.random() * (194481 - skip.length));
    // INCREMENT RANDOM NUMBER FOR EVERY SMALLER FORBIDDEN COMBINATION
    for (var i = 0; i < skip.length && num >= dec[i]; i++) {
        ++num;
    }
    // CONVERT RANDOM NUMBER TO FOUR BASE-21 DIGITS
    for (var i = 3; i >= 0; i--, num /= 21) {
        result[i] = Math.floor(num % 21);
    }
    return result;
}

var notAllowed = [[0,0,17,9],[0,0,17,12],[20,19,17,12],[15,16,17,12]];
document.write(randomBase21(notAllowed));

【讨论】:

  • 哇.. 这太棒了。我会用这个。谢谢:D
  • @JohannaCristineDy 顺便说一句,如果禁用组合列表是固定的,您可以预先将其从小到大排序,并跳过此函数中的排序。您还可以预先将禁止的组合转换为十进制,以使此功能更加简单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 2021-03-14
  • 1970-01-01
  • 2013-03-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多