আমি মিলার-রবিন আদিমতার পরীক্ষাটি বাস্তবায়নের চেষ্টা করছিলাম , এবং বিস্মিত হয়েছিলাম যে এটি কেন মাঝারি আকারের সংখ্যা (~ 7 ডিজিট) জন্য এত দীর্ঘ (> 20 সেকেন্ড) সময় নিচ্ছে? অবশেষে আমি নীচের কোডের লাইনটি সমস্যার উত্স হিসাবে পেয়েছি:
x = a**d % n
(যেখানে a
, d
এবং n
সবগুলি সমান, তবে অসম, মিডসাইজ সংখ্যা **
হ'ল এক্সপেনসেন্টেশন অপারেটর এবং %
এটি মডুলো অপারেটর)
আমি তখন নিম্নলিখিতটি দিয়ে এটি প্রতিস্থাপনের চেষ্টা করেছি:
x = pow(a, d, n)
এবং এটি তুলনা করে এটি প্রায় তাত্ক্ষণিক।
প্রসঙ্গে, এখানে মূল ফাংশনটি রয়েছে:
from random import randint
def primalityTest(n, k):
if n < 2:
return False
if n % 2 == 0:
return False
s = 0
d = n - 1
while d % 2 == 0:
s += 1
d >>= 1
for i in range(k):
rand = randint(2, n - 2)
x = rand**d % n # offending line
if x == 1 or x == n - 1:
continue
for r in range(s):
toReturn = True
x = pow(x, 2, n)
if x == 1:
return False
if x == n - 1:
toReturn = False
break
if toReturn:
return False
return True
print(primalityTest(2700643,1))
সময় নিরূপণের একটি উদাহরণ:
from timeit import timeit
a = 2505626
d = 1520321
n = 2700643
def testA():
print(a**d % n)
def testB():
print(pow(a, d, n))
print("time: %(time)fs" % {"time":timeit("testA()", setup="from __main__ import testA", number=1)})
print("time: %(time)fs" % {"time":timeit("testB()", setup="from __main__ import testB", number=1)})
আউটপুট (পাইপাই 1.9.0 দিয়ে চালানো):
2642565
time: 23.785543s
2642565
time: 0.000030s
আউটপুট (পাইথন ৩.৩.০ দিয়ে চালানো, ২.7.২ খুব একই সময়ে ফিরে আসে):
2642565
time: 14.426975s
2642565
time: 0.000021s
এবং একটি সম্পর্কিত প্রশ্ন, পাইথন 2 বা 3 পিপাইয়ের সাথে চালানোর সময় এই গণনাটি কেন দ্বিগুণ দ্রুত হয়, যখন সাধারণত পাইপি আরও দ্রুত হয় ?
>>> print pow.__doc__ pow(x, y[, z]) -> number With two arguments, equivalent to x**y. With three arguments, equivalent to (x**y) % z, but may be more efficient (e.g. for longs).