Ich habe vorher geschrieben Implementieren Sie die Monte-Carlo-Methode schnell in Python.
Die Implementierung mit Cython war zu ausgelassen, daher werde ich sie ergänzen.
import random
NUM=100000000
def monte():
counter = 0
for i in range(NUM):
x = random.random()
y = random.random()
if x*x+y*y < 1.0:
counter += 1
pi = 4.0*counter/NUM
print(pi)
def main():
monte()
if __name__ == '__main__':
main()
#monte.pyx
import random
cdef int NUM = 100000000
cdef cmonte():
cdef :
int counter = 0
int i=0
double x
double y
for i in range(NUM):
x = random.random()
y = random.random()
if x*x + y*y < 1.0:
counter += 1
cdef double pi = 4.0*counter/NUM
return pi
def monte():
pi=cmonte()
print(pi)
Es ist gut, dass es sich von ungefähr 100 Sekunden auf 17 Sekunden verkürzt hat (gemessen mit einem 12-Zoll-MacBook), aber ich sollte in der Lage sein, mein Bestes zu geben. Da der zufällige Teil Python-Code ist, scheint es gut, hier die C-Implementierung zu verwenden.
from libc.stdlib cimport rand, RAND_MAX
cdef int NUM = 100000000
def monte():
cdef :
int counter = 0
int i=0
double x
double y
for i in range(NUM):
x = (rand()+1.0)/(RAND_MAX+2.0)
y = (rand()+1.0)/(RAND_MAX+2.0)
if x*x + y*y < 1.0:
counter += 1
pi = 4.0*counter/NUM
print(pi)
Schreiben wir auch setup.py
.
#setup.py
from setuptools import setup, Extension
ext_modules = [
Extension(
name='monte',
sources=['monte.pyx']
)
]
setup(
name = 'cymonte',
ext_modules = ext_modules
)
Sie können ein Modul erstellen, indem Sie im Terminal Folgendes ausführen. Ich denke, dass es unter Windows gemacht werden kann.
$ python setup.py build_ext --inplace
Schreiben Sie danach das Hauptskript, um es auszuführen.
#main.py
import monte
monte.monte()
Lass es uns bewegen.
$ time python main.py
real 0m2.081s
user 0m1.935s
sys 0m0.070s
Ich habe es eingestellt und es ist viel schneller! Wir konnten der Implementierung von Numba und der Implementierung von C ++ so nahe wie möglich kommen.
Reference: