如何用条件生成随机数

时间:2012-05-23 03:58:56

标签: python algorithm

我想在[1,n]范围内生成2n-1个随机整数,每个元素出现两次,除了随机值,只出现一次。
例如:

n = 3  
seq = [1, 2, 3, 1, 3]  

在此示例中仅出现一次。

我的算法是使用字典,如下所示:

-------------
| num |times|
|  1  |  2  |
|  2  |  1  |
|  3  |  2  |

其中键从1到n,值表示键的出现次数。我在字典中填入值为2的值,并将值减少为1,用于一个随机密钥。

  1. 还有其他算法吗?
  2. 如果n非常大导致无法存储在内存中怎么办?

5 个答案:

答案 0 :(得分:9)

我不确定我是否确定你的目标是什么,但这是一次尝试:

import random as rn

x = range(3)*2 #generate a list where each number appears twice

rn.shuffle(x) #shuffle it
x.pop()       #remove one number

结果:

>>> x
[2, 0, 2, 1, 0] #the result is a list where every number appears twice, except for
                #one number which was removed at random, also the numbers are 
                #randomly arranged

编辑:

这是尝试对非常大的n执行此操作(n表示该大小的列表不能存储在您的ram中)。我看不出如何改变整数。但是,我可以随意删除一个。假设您要将列表写入txt文件。

drop = rn.range(0,n) #choose a random integer to drop

with open('my_file.txt','w') as f:
    for ind,ele in enumerate(xrange(n)):  
        if ind == drop: #do not write the element to txt file
            pass
        else:
            f.write(str(ele) + '\n') #write every except for one element to txt file

with open('my_file.txt','a') as f:
    for ele in xrange(n):
        f.write(str(ele) + '\n') # write every element to txt file

最后我们写了n-1个元素到txt文件两次,1个元素一次,该元素是随机选择的。

对于n = 5,txt文件如下所示:

0
2
3
4
0
1
2
3
4

在上述情况下,1只出现一次,每隔一个数字出现两次。

答案 1 :(得分:0)

与@Akavall一样,不确定我是否理解正确。您想要生成1到n范围内的2n-1个数字(包括我假设的n)。这些数字并不是随机的,只有1次出现。

import random

n=3

# Generate n numbers
numbers = [i for i in range(1,n+1)]
# Concatenate list to itself (now have 2n numbers)
numbers *= 2
# Remove a random element in the list (now have 2n-1 numbers)
numbers.pop( random.randint(0, len(numbers)-1) )

# Print results
from collections import Counter
print( Counter(numbers) )

输出

Counter({1: 2, 3: 2, 2: 1})

答案 2 :(得分:0)

  

2。如果n非常大导致无法存储在内存中怎么办?

取决于您对这些数字的处理以及订单是否重要。从你提出表格的方式来看,我会说你不关心订单,所以即使是大n,编码整个表所需的实际信息量也非常小:n本身和只有一个条目的索引。

如果您认为记忆会成为一个问题,那么完全改变您的方法可能会更好,但如果没有更多信息则很难说。

答案 3 :(得分:0)

1)我建议使用随机数生成器来选择你的“单个”数字,然后我会使用构建所有数字的集合然后使用内置的shuffle方法。我建议使用build in shuffle方法,因为内置方法往往是高度优化的。

2)如果n非常大,那么您可能希望将数字块写入文件,并在任何给定时间仅对部分进行混洗。这样做的一个类比是试图同时洗牌5副牌。这将是非常困难的,但是你可以把大部分收集并将这些部分混合在一起,将部分返回到大集合中并选择两个部分进行随机播放,重复直到达到所需的洗牌要求。

答案 4 :(得分:0)

生成频率表的生成器,这应该有助于解决内存问题

from random import randint

def generate_counts(n):
    remove_index = randint(1,n+1)
    return ((i+1,2-(remove_index==i)) for i in range(n))

输出

for number, frequency in generate_counts(10):
    print "%i: %i"%(number,frequency)

1: 2
2: 2
3: 2
4: 1
5: 2
6: 2
7: 2
8: 2
9: 2
10: 2