2013-04-22 56 views
14

Cython'da [0,1] rasgele bir rasgele oluşturmanın en verimli ve taşınabilir yolu nedir?Cython'da rasgele sayılar oluşturmak için doğru yol?

from libc.stdlib cimport rand 
cdef extern from "limits.h": 
    int INT_MAX 
cdef float randnum = rand()/float(INT_MAX) 

bu şekilde INT_MAX kullanılabilir mi: Bir yaklaşım C kütüphanesinden INT_MAX ve rand() kullanmaktır?

import sys 
print INT_MAX 
print sys.maxint 

verimleri: Bence sen Python'un maksimum int aldığım sabit oldukça farklı olduğunu fark

2147483647 (C max int) 
9223372036854775807 (python max int) 

rand() için doğru "normalleşme" sayı hangisi? DÜZENLEME ek olarak, rasgele tohum (örneğin, şu anki zamana göre tohumlanmış) nasıl bir çağrı C yaklaşımını kullanıyorsa rand() libc?

+0

Birkaç bin numunenin maksimum ve minimum değerlerini almayı ve hangi ölçekleme faktörünün "1.0" yakınında olduğunu görmeyi denediniz mi? – phs

+0

Lütfen "[rand() zararlı olarak göz atın] (https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful)" –

cevap

8

C standart yüzden normalleştirmek için uygun bir yoldur (stdlib.h dan) RAND_MAX bölünerek, RAND_MAX rand döner 0 ila bir int dahil söylüyor. Pratikte, RAND_MAX hemen hemen her zaman MAX_INT'e eşit olacaktır, ancak buna güvenmeyin.

rand, C89'dan beri ISO C'nin bir parçası olduğundan, her yerde kullanılabilir olduğu garanti edilir, ancak rasgele sayılarının kalitesiyle ilgili hiçbir garanti verilmez. Taşınabilirlik sizin ana endişeniz ise, Python'un random modülünü kullanmaya istekli olmadığınız sürece en iyi seçeneğiniz olacaktır. Python'un sys.maxint tümüyle farklı bir konseptidir; Python'un kendi int türünde temsil edebileceği en büyük pozitif sayıdır; daha büyük olanlar uzun olmalı. Python ints ve longs özellikle C'ler ile ilgili değildir.

+0

Teşekkürler! Tohumun libc yaklaşımı kullanılarak nasıl ayarlanabileceğini biliyor musunuz? – user248237dfsf

+1

Muhtemelen bunun için 'random.randint (0, INT_MAX)' kullanabilirdim. Ek yük bir sorun değil, çünkü sadece bir kez gerçekleşecek. – Cairnarvon

+0

yükü önemli bir konudur çünkü buna, döngü içinde rastgele sayılar üretmek için birçok kez denir (kısmi olarak çok parçalı örnekleme yapmak için). 'Random.randint (0, INT_MAX)' ı kurabilir ve sonra C'nin rand() 'sini arayabilir ve C ve Python tohumlarının" senkronize "olmasını sağlayabilir miyim? – user248237dfsf

2

'c' stdlib rand() 32767.

rastgele piton kullanmak için herhangi bir neden() var mı genellikle 0 ile RAND_MAX arasında bir sayı döndürür?

Generate random integers between 0 and 9

+0

Bunu bir Cython işlevinde iç döngü ve Python'u arıyorum. Bunun için sistemimde çok pahalı – user248237dfsf

+0

RAND_MAX 2147483647 (2 ** 31-1). En azından * 2 ** 15-1 olması garantilidir, ama hiç bu kadar düşük olduğunu görmüyorum. – Cairnarvon

+0

Oh, görünüşe göre msvc's 2 ** 15-1. Bu korkunç. – Cairnarvon

1

Drand'ın yeni bir ekleme olup olmadığından emin değilim, ancak pahalı bölümlemeden kaçınarak tam olarak istediğiniz şeyi yapıyor gibi görünüyor. senin bölünme yöntemi yeterli rastgeleliğine oluşturulan eğer araştırma sırasında

cdef extern from "stdlib.h": 
    double drand48() 
    void srand48(long int seedval) 

cdef extern from "time.h": 
    long int time(int) 

# srand48(time(0)) 
srand48(100) 
# TODO: this is a seed to reproduce bugs, put to line of code above for 
# production 
drand48() #This gives a float in range [0,1) 

Ben this idea geldi. Bulduğum kaynak, benim durumumda, rasgele sayıyı iki basamaklı bir ondalık ile karşılaştırdığımı gösterdiğinden, gerçekten sadece 3 ondalık kesinlik noktasına ihtiyacım var. Yani INT_MAX, fazlasıyla yeterli. Ancak, drand48'in maliyet maliyetinden tasarruf ettiği görülüyor, bu yüzden kullanmaya değer olabilir.

+2

Bu arada, taşınabilir değil çünkü srand48' ve 'drand48' yalnızca POSIX sistemlerinde kullanılabilir –

İlgili konular