2

私は10万の乱数を生成したいのですが、これが私が思いついたものです:

from random import randrange, seed

f=open("tree.in","w")
s=set()

seed(99)
for _ in xrange(1,10**5):
    while True:
        x=randrange(10**6)
        if x not in s:
            s.add(x)
            break

for x in s:
    f.write(str(x)+"\n")

f.close()

残念ながら、ファイル内の数値は次のようにまとめられています。

524369
524372
786520
786523
786526
98
524387
106
108
111
786544
786549

それらをリストに追加してランダムな順序にすることもできますが、スペースが無駄になります。
この問題を解決するエレガントな方法はありますか?
(cygwin がこの問題と関係があるかどうかはわかりません)

4

3 に答える 3

2

Python のset型は順序を保持しません。セット内の要素の順序は、追加する要素の挿入順序とハッシュによって異なります。CPython (Python の最も一般的な実装) は、ID 関数を整数のハッシュ関数として使用します (内部的な理由-1で にハッシュされる を除く)。-2この単純なハッシュ関数の結果として、観察した「クラスタリング」が得られます。

解決策は、結果のリスト *alongisde" をセットと共に使用して、生成した順序で結果を保持することです。または、単に を使用するだけrandom.sample()で、正しいことを行うこのアルゴリズムの最適化された実装が既に行われています。

于 2013-10-11T10:07:05.010 に答える
2

これにはrandom.sampleを使用することをお勧めします。

>>> import random
>>> s = random.sample(xrange(1, 10 ** 6), 10 ** 5)
于 2013-10-11T09:50:29.797 に答える
-1

ランダム化されたシードを気にするかどうかはわかりませんが (私はそれらを好みます)、それにステップ コンポーネントを追加すると、はるかに良い結果が得られます。例えば:

from random import randrange, randint, seed
import time

f=open("tree.in","w")
s=set()

seed(randint(1,10**6)
for _ in xrange(1,10**5):
    while True:
        x=randrange(randint(1,10**5), 10**8, randint(1,10**5))
        if x not in s:
            s.add(x)
            break

for x in s:
    f.write(str(x)+"\n")

f.close()
于 2013-10-11T09:58:31.717 に答える