【问题标题】:Generate random non-repeating integers from a small range从小范围内生成随机非重复整数
【发布时间】:2013-11-07 18:09:43
【问题描述】:

我想要完成的是:

我希望从一个相对较小的范围内创建一个整数向量,并确保没有一个整数后跟相同的整数。

即,这是一个“合法”向量: [1 3 4 2 5 3 2 3 5 4]

这是一个“非法”向量(因为 5 跟在 5 后面): [1 3 4 2 5 5 2 3 5 4]

我已经尝试过randi,以及randperm 的各种变体,当我尝试从一个小范围(即 1 到5).

函数运行时间过长。

这是我所做的尝试之一:

function result = nonRepeatingRand(top, count)

    result = randi(top, 1, count);

    while any(diff(result) == 0)
         result = randi(top, 1, count);    
    end

end

我们将不胜感激任何和所有的帮助。谢谢!

【问题讨论】:

  • 只是一个小评论。不重复的条件意味着您的向量不那么“随机”

标签: matlab random


【解决方案1】:

借鉴A. Donda 的想法,但修复了实现:

r=[randi(top,1,1),randi(top - 1, 1, count-1)];
d=rem(cumsum(r)-1,top)+1;

r 的第一个元素是随机选择的开始元素。 r 的以下元素随机选择与前一个元素的差异,使用模运算。

【讨论】:

    【解决方案2】:

    您可以使用以下代码生成从 1 到 M 的非重复随机数

    randperm(M);

    对于从 1 到 M 的 K 个非重复随机数

    randperm(M, K);

    享受

    【讨论】:

    • 谢谢,但是:正如您可能已经注意到的那样,这个问题(非常优雅地)大约在一年前得到了回答,并且正确的答案被标记为这样。其次,恐怕你没有回答我问的问题——如果我需要一个 1-4 范围内的 100 个非重复随机整数的序列,randperm(4,100) 当然会返回错误。
    • 你的答案很简单,但亲爱的,你是最棒的,干杯
    【解决方案3】:

    您正在寻找的序列类型可以通过从1top - 1 生成差异 然后计算累积和模数 top 来定义,从随机初始值开始:

    function result = nonRepeatingRand(top, count)
    
        diff = randi(top - 1, 1, count);
        result = rem(cumsum(diff) + randi(1, 1, count) - 1, top) + 1;
    
    end
    

    在我的机器上,这会在 0.58 秒内以 1:5 生成一个由 1000 万个数字组成的非重复序列。

    【讨论】:

    • 我真的不明白你是怎么想出来的......?无论如何,来自我的 +1!
    • 我刚刚想到,发布者想要实现的约束最容易表达为关于差异。那么为什么不先生成差异并从中生成序列。
    • @A.Donda - 很棒的解决方案!
    • @A.Donda 错了!我只调用了该函数 5 次,而且我有两个带有重复数字的序列。
    • @karl71,我对此进行了广泛的测试,生成了许多非常长的序列,并且从来没有任何重复。也许您以不同的方式使用“重复号码”?正如问题中所解释的,这是关于立即重复,即2 3 2 1 2 没有“重复”,但2 3 1 2 2 有一个“重复”。
    【解决方案4】:

    不要每次都重新生成序列,而是修复重复。例如:

    function result = nonRepeatingRand(top, count)
    
        result = randi(top, 1, count);
    
        ind = (diff(result) == 0);
        while any(ind)
            result(ind) = [];
            result(end + 1 : count) = randi(top, 1, count - numel(result));
    
            ind = (diff(result) == 0);
        end
    
    end
    

    在我的机器上,这会在 1.6 秒内以 1:5 生成一个由 1000 万个数字组成的非重复序列。

    【讨论】:

    • 我认为我的另一个答案更好:更快,更优雅。
    【解决方案5】:

    这是怎么回事?

    top = 5;
    count = 100;
    n1 = nan;
    out = [];
    for t = 1: count 
        n2 = randi(top);
        while n1 == n2
            n2 = randi(top);
        end
        out = [out, n2];
        n1 = n2;
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-01
      • 1970-01-01
      • 2014-10-23
      • 2015-06-05
      • 2012-09-30
      • 1970-01-01
      相关资源
      最近更新 更多