2013-10-28 246 views
5

我试图做到的是以下几点:生成一个小范围的随机不重复的整数

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

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

,这是一个 “非法” 载体(自5如下5): [1 3 4 2 5 5 2 3 5 4]

我试过用randi和各种各样的变化与randperm,我总是陷入困境,当我尝试生成一个向量约100个元素,从一个小范围即1和5之间的整数)。

函数运行时间太长。

下面是我所做的尝试之一:

function result = nonRepeatingRand(top, count) 

    result = randi(top, 1, count); 

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

end 

任何及所有的帮助将非常感激。谢谢 !

+2

只是一个小评论。非重复的条件意味着你的向量不是“随机的” – bla

回答

11

那种序列的你正在寻找可以通过产生差异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万数字的非重复序列。

+0

+1非常聪明的解决方案! –

+0

我真的不知道你是怎么想出来的......?总之,来自我的+1! –

+1

刚才我想到,海报想要实现的约束最容易表达为diff。那么为什么不先生成差异,并从中得出序列。 –

0

这是怎么回事?

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 
1

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

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万数字的非重复序列。

+1

我认为我的其他答案更好:更快,更优雅。 –

0

是否有可能选择创建此“随机”序列而不重复,以便所有值均匀分布(与randperm一样)?

randperm似乎有限,我只能想到在while循环中调用第一个函数,直到我的“平等分配标准”满足..但它可以更快地完成?

2

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

randperm(M);

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

randperm(M,K);

享受

+1

谢谢,但是:正如你可能已经注意到的那样,这个问题在一年前得到了(非常优雅的)回答,正确的答案被标记为这样。其次,恐怕你没有回答我问过的问题 - 如果我需要在1-4范围内的100个非重复随机整数序列,'randperm(4,100)'当然会返回一个错误。 –

+0

你的答案非常简单,但你是最好的亲爱的,干杯 – Christina

相关问题