больше кодовввв
This commit is contained in:
118
task10/grover.py
Normal file
118
task10/grover.py
Normal file
@@ -0,0 +1,118 @@
|
||||
# pylint: disable=wrong-or-nonexistent-copyright-notice
|
||||
"""Demonstrates Grover algorithm.
|
||||
|
||||
The Grover algorithm takes a black-box oracle implementing a function
|
||||
{f(x) = 1 if x==x', f(x) = 0 if x!= x'} and finds x' within a randomly
|
||||
ordered sequence of N items using O(sqrt(N)) operations and O(N log(N)) gates,
|
||||
with the probability p >= 2/3.
|
||||
|
||||
At the moment, only 2-bit sequences (for which one pass through Grover operator
|
||||
is enough) are considered.
|
||||
|
||||
=== REFERENCE ===
|
||||
Coles, Eidenbenz et al. Quantum Algorithm Implementations for Beginners
|
||||
https://arxiv.org/abs/1804.03719
|
||||
|
||||
=== EXAMPLE OUTPUT ===
|
||||
Secret bit sequence: [1, 0]
|
||||
Circuit:
|
||||
(0, 0): ───────H───────@───────H───X───────@───────X───H───M───
|
||||
│ │ │
|
||||
(1, 0): ───────H───X───@───X───H───X───H───X───H───X───H───M───
|
||||
│
|
||||
(2, 0): ───X───H───────X───────────────────────────────────────
|
||||
Sampled results:
|
||||
Counter({'10': 10})
|
||||
Most common bitstring: 10
|
||||
Found a match: True
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import random
|
||||
|
||||
import cirq
|
||||
|
||||
|
||||
def set_io_qubits(qubit_count):
|
||||
"""Add the specified number of input and output qubits."""
|
||||
input_qubits = [cirq.GridQubit(i, 0) for i in range(qubit_count)]
|
||||
output_qubit = cirq.GridQubit(qubit_count, 0)
|
||||
return (input_qubits, output_qubit)
|
||||
|
||||
|
||||
def make_oracle(input_qubits, output_qubit, x_bits):
|
||||
"""Implement function {f(x) = 1 if x==x', f(x) = 0 if x!= x'}."""
|
||||
# Make oracle.
|
||||
# for (1, 1) it's just a Toffoli gate
|
||||
# otherwise negate the zero-bits.
|
||||
yield (cirq.X(q) for (q, bit) in zip(input_qubits, x_bits) if not bit)
|
||||
yield (cirq.TOFFOLI(input_qubits[0], input_qubits[1], output_qubit))
|
||||
yield (cirq.X(q) for (q, bit) in zip(input_qubits, x_bits) if not bit)
|
||||
|
||||
|
||||
def make_grover_circuit(input_qubits, output_qubit, oracle):
|
||||
"""Find the value recognized by the oracle in sqrt(N) attempts."""
|
||||
# For 2 input qubits, that means using Grover operator only once.
|
||||
c = cirq.Circuit()
|
||||
|
||||
# Initialize qubits.
|
||||
c.append([cirq.X(output_qubit), cirq.H(output_qubit), cirq.H.on_each(*input_qubits)])
|
||||
|
||||
# Query oracle.
|
||||
c.append(oracle)
|
||||
|
||||
# Construct Grover operator.
|
||||
c.append(cirq.H.on_each(*input_qubits))
|
||||
c.append(cirq.X.on_each(*input_qubits))
|
||||
c.append(cirq.H.on(input_qubits[1]))
|
||||
c.append(cirq.CNOT(input_qubits[0], input_qubits[1]))
|
||||
c.append(cirq.H.on(input_qubits[1]))
|
||||
c.append(cirq.X.on_each(*input_qubits))
|
||||
c.append(cirq.H.on_each(*input_qubits))
|
||||
|
||||
# Measure the result.
|
||||
c.append(cirq.measure(*input_qubits, key='result'))
|
||||
|
||||
return c
|
||||
|
||||
|
||||
def bitstring(bits):
|
||||
return ''.join(str(int(b)) for b in bits)
|
||||
|
||||
|
||||
def main():
|
||||
qubit_count = 2
|
||||
circuit_sample_count = 10
|
||||
|
||||
# Set up input and output qubits.
|
||||
(input_qubits, output_qubit) = set_io_qubits(qubit_count)
|
||||
|
||||
# Choose the x' and make an oracle which can recognize it.
|
||||
x_bits = [random.randint(0, 1) for _ in range(qubit_count)]
|
||||
print(f'Secret bit sequence: {x_bits}')
|
||||
|
||||
# Make oracle (black box)
|
||||
oracle = make_oracle(input_qubits, output_qubit, x_bits)
|
||||
|
||||
# Embed the oracle into a quantum circuit implementing Grover's algorithm.
|
||||
circuit = make_grover_circuit(input_qubits, output_qubit, oracle)
|
||||
print('Circuit:')
|
||||
print(circuit)
|
||||
|
||||
# Sample from the circuit a couple times.
|
||||
simulator = cirq.Simulator()
|
||||
result = simulator.run(circuit, repetitions=circuit_sample_count)
|
||||
|
||||
frequencies = result.histogram(key='result', fold_func=bitstring)
|
||||
print(f'Sampled results:\n{frequencies}')
|
||||
|
||||
# Check if we actually found the secret value.
|
||||
most_common_bitstring = frequencies.most_common(1)[0][0]
|
||||
print(f'Most common bitstring: {most_common_bitstring}')
|
||||
print(f'Found a match: {most_common_bitstring == bitstring(x_bits)}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user