Ivankilin commited on
Commit
51bb945
·
verified ·
1 Parent(s): 60b54ae

Create goldbahc_core.py

Browse files
Files changed (1) hide show
  1. goldbahc_core.py +84 -0
goldbahc_core.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sympy, math, itertools, time
2
+ from qiskit import QuantumCircuit, Aer, execute
3
+ from qiskit.circuit.library import QFT
4
+
5
+ def generate_qsieve_mask(max_val):
6
+ return [1 if sympy.isprime(i) else 0 for i in range(max_val + 1)]
7
+
8
+ def build_grover_circuit(N):
9
+ """Возвращает схему + результат измерения."""
10
+ n = math.ceil(math.log2(N // 2 + 1))
11
+ qa = list(range(n))
12
+ qb = list(range(n, 2 * n))
13
+ anc = list(range(2 * n, 2 * n + 4))
14
+ qc = QuantumCircuit(2 * n + 4, 2 * n)
15
+
16
+ # суперпозиция
17
+ qc.h(qa + qb)
18
+
19
+ # решето
20
+ mask = generate_qsieve_mask(N // 2)
21
+ def apply_mask(qr, flag):
22
+ for val, is_prime in enumerate(mask):
23
+ if is_prime:
24
+ ctrl = [qr[i] for i in range(n) if not (val >> i) & 1]
25
+ if ctrl:
26
+ qc.x(ctrl)
27
+ qc.mcx(qr, flag)
28
+ if ctrl:
29
+ qc.x(ctrl)
30
+ apply_mask(qa, anc[0])
31
+ apply_mask(qb, anc[1])
32
+
33
+ # сложение p+q=N
34
+ def adder(a, b, carry):
35
+ for i in range(n):
36
+ qc.cx(a[i], b[i])
37
+ tgt = [b[i] for i in range(n)]
38
+ bits = [(N >> i) & 1 for i in range(n)]
39
+ for i, bit in enumerate(bits):
40
+ if not bit:
41
+ qc.x(tgt[i])
42
+ qc.mcx(tgt, carry)
43
+ for i, bit in enumerate(bits):
44
+ if not bit:
45
+ qc.x(tgt[i])
46
+ for i in reversed(range(n)):
47
+ qc.cx(a[i], b[i])
48
+ adder(qa, qb, anc[2])
49
+
50
+ # oracle
51
+ qc.mcx([anc[0], anc[1], anc[2]], anc[3])
52
+ qc.z(anc[3])
53
+ qc.mcx([anc[0], anc[1], anc[2]], anc[3])
54
+
55
+ # uncompute
56
+ adder(qa, qb, anc[2])
57
+ apply_mask(qa, anc[0])
58
+ apply_mask(qb, anc[1])
59
+
60
+ # diffusion
61
+ qc.h(qa + qb)
62
+ qc.x(qa + qb)
63
+ qc.h(qa[-1])
64
+ qc.mcx(qa[:-1], qa[-1])
65
+ qc.h(qa[-1])
66
+ qc.x(qa + qb)
67
+ qc.h(qa + qb)
68
+
69
+ qc.measure(qa + qb, list(range(2 * n)))
70
+ return qc
71
+
72
+ def run_quantum(N, shots=1024):
73
+ """Запускает схему и возвращает найденную пару."""
74
+ qc = build_grover_circuit(N)
75
+ backend = Aer.get_backend('qasm_simulator')
76
+ counts = execute(qc, backend, shots=shots).result().get_counts()
77
+ valid = {k: v for k, v in counts.items()
78
+ if int(k[:len(k)//2], 2) + int(k[len(k)//2:], 2) == N}
79
+ if not valid:
80
+ return None
81
+ best = max(valid, key=valid.get)
82
+ p = int(best[:len(best)//2], 2)
83
+ q = int(best[len(best)//2:], 2)
84
+ return p, q