Skip to content

Commit c1f6881

Browse files
authored
Create Prime Numbers Counting Algorithm
.
1 parent 2078ba6 commit c1f6881

1 file changed

Lines changed: 131 additions & 0 deletions

File tree

Prime Numbers Counting Algorithm

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import numpy as np
2+
from multiprocessing import Pool
3+
from functools import lru_cache
4+
from typing import Set, List, Generator
5+
import time
6+
7+
8+
9+
# Бързо намиране на числа до определена граница
10+
finder = PrimeNumberFinder(10000)
11+
results = finder.find_p2_plus_4q2_primes_parallel()
12+
13+
# Генериране на безкраен поток от такива числа
14+
generator = generate_p2_plus_4q2_primes_stream()
15+
next_number = next(generator)
16+
17+
# Оптимизирана проверка за простота с кеширане
18+
@lru_cache(maxsize=10000)
19+
def is_prime(n: int) -> bool:
20+
"""Кеширана проверка за простота."""
21+
if n < 2:
22+
return False
23+
if n == 2:
24+
return True
25+
if n % 2 == 0:
26+
return False
27+
for i in range(3, int(np.sqrt(n)) + 1, 2):
28+
if n % i == 0:
29+
return False
30+
return True
31+
32+
def generate_primes_numpy(limit: int) -> np.ndarray:
33+
"""Генерира прости числа използвайки numpy."""
34+
sieve = np.ones(limit, dtype=bool)
35+
sieve[0] = sieve[1] = False
36+
37+
for i in range(2, int(np.sqrt(limit)) + 1):
38+
if sieve[i]:
39+
sieve[i*i::i] = False
40+
41+
return np.nonzero(sieve)[0]
42+
43+
def process_prime_chunk(args: tuple) -> Set[int]:
44+
"""Обработва част от простите числа за паралелизация."""
45+
p_chunk, q_primes, limit = args
46+
results = set()
47+
48+
for p in p_chunk:
49+
p_squared = p * p
50+
if p_squared >= limit:
51+
break
52+
53+
q_values = q_primes[q_primes * q_primes * 4 + p_squared < limit]
54+
results_array = p_squared + 4 * np.square(q_values)
55+
56+
for result in results_array:
57+
if is_prime(int(result)):
58+
results.add(int(result))
59+
60+
return results
61+
62+
class PrimeNumberFinder:
63+
def __init__(self, limit: int, num_processes: int = 4):
64+
self.limit = limit
65+
self.num_processes = num_processes
66+
self.primes_cache = None
67+
68+
def generate_primes(self) -> np.ndarray:
69+
"""Кеширано генериране на прости числа."""
70+
if self.primes_cache is None:
71+
self.primes_cache = generate_primes_numpy(int(np.sqrt(self.limit)) + 1)
72+
return self.primes_cache
73+
74+
def find_p2_plus_4q2_primes_parallel(self) -> Set[int]:
75+
"""Паралелно намиране на специални прости числа."""
76+
primes = self.generate_primes()
77+
78+
# Разделяме простите числа на chunks за паралелна обработка
79+
chunk_size = max(1, len(primes) // self.num_processes)
80+
chunks = [primes[i:i + chunk_size] for i in range(0, len(primes), chunk_size)]
81+
82+
# Подготвяме аргументите за паралелна обработка
83+
args = [(chunk, primes, self.limit) for chunk in chunks]
84+
85+
# Паралелна обработка
86+
with Pool(processes=self.num_processes) as pool:
87+
results = pool.map(process_prime_chunk, args)
88+
89+
# Обединяваме резултатите
90+
return set().union(*results)
91+
92+
def benchmark_comparison(limit: int):
93+
"""Сравнява производителността на различни методи."""
94+
95+
# Тест на паралелната версия
96+
start_time = time.time()
97+
finder = PrimeNumberFinder(limit)
98+
parallel_results = finder.find_p2_plus_4q2_primes_parallel()
99+
parallel_time = time.time() - start_time
100+
101+
print(f"\nРезултати до {limit}:")
102+
print(f"Брой намерени числа: {len(parallel_results)}")
103+
print(f"Време за паралелно изпълнение: {parallel_time:.2f} секунди")
104+
print(f"Първите 10 намерени числа: {sorted(list(parallel_results))[:10]}")
105+
106+
# Генератор версия с numpy оптимизация
107+
def generate_p2_plus_4q2_primes_stream() -> Generator[int, None, None]:
108+
"""Оптимизиран генератор за специални прости числа."""
109+
seen = set()
110+
primes = generate_primes_numpy(1000) # Начален набор от прости числа
111+
112+
for p in primes:
113+
p_squared = p * p
114+
q_values = primes[primes < np.sqrt(10**6 - p_squared) // 2]
115+
116+
results = p_squared + 4 * np.square(q_values)
117+
for result in results:
118+
if int(result) not in seen and is_prime(int(result)):
119+
seen.add(int(result))
120+
yield int(result)
121+
122+
# Пример за използване
123+
if __name__ == '__main__':
124+
# Тестване на различни граници
125+
for limit in [1000, 10000, 100000]:
126+
benchmark_comparison(limit)
127+
128+
print("\nГенериране на поток от специални прости числа:")
129+
generator = generate_p2_plus_4q2_primes_stream()
130+
first_10 = [next(generator) for _ in range(10)]
131+
print(f"Първите 10 числа от генератора: {first_10}")

0 commit comments

Comments
 (0)