Алгоритм Бернштейна–Вазирани
This commit is contained in:
91
task4/main.py
Normal file
91
task4/main.py
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
"""Алгоритм Бернштейна–Вазирани в Cirq."""
|
||||||
|
|
||||||
|
import random
|
||||||
|
|
||||||
|
import cirq
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Выполняет алгоритм BV."""
|
||||||
|
# Количество кубитов
|
||||||
|
qubit_count = 8
|
||||||
|
# Количество выборок из схемы
|
||||||
|
circuit_sample_count = 3
|
||||||
|
|
||||||
|
# Выберите кубиты для использования
|
||||||
|
input_qubits = [cirq.GridQubit(i, 0) for i in range(qubit_count)]
|
||||||
|
output_qubit = cirq.GridQubit(qubit_count, 0)
|
||||||
|
|
||||||
|
# Выберите коэффициенты для оракула и создайте схему для его запроса
|
||||||
|
secret_bias_bit = random.randint(0, 1)
|
||||||
|
secret_factor_bits = [random.randint(0, 1) for _ in range(qubit_count)]
|
||||||
|
|
||||||
|
oracle = make_oracle(
|
||||||
|
input_qubits, output_qubit, secret_factor_bits, secret_bias_bit
|
||||||
|
)
|
||||||
|
|
||||||
|
print(
|
||||||
|
"Secret function:\nf(x) = x*<{}> + {} (mod 2)".format(
|
||||||
|
", ".join(str(e) for e in secret_factor_bits), secret_bias_bit
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Встраиваем оракул в специальную квантовую схему, запрашивая ее ровно один раз
|
||||||
|
circuit = make_bernstein_vazirani_circuit(input_qubits, output_qubit, oracle)
|
||||||
|
print("\nCircuit:")
|
||||||
|
print(circuit)
|
||||||
|
|
||||||
|
# Выберем из схемы пару раз
|
||||||
|
simulator = cirq.Simulator()
|
||||||
|
result = simulator.run(circuit, repetitions=circuit_sample_count)
|
||||||
|
frequencies = result.histogram(key="result", fold_func=bitstring)
|
||||||
|
print("\nSampled results:\n{}".format(frequencies))
|
||||||
|
|
||||||
|
# Проверить, действительно ли мы нашли секретное значение
|
||||||
|
most_common_bitstring = frequencies.most_common(1)[0][0]
|
||||||
|
print(
|
||||||
|
"\nMost common matches secret factors:\n{}".format(
|
||||||
|
most_common_bitstring == bitstring(secret_factor_bits)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def make_oracle(input_qubits, output_qubit, secret_factor_bits, secret_bias_bit):
|
||||||
|
"""Вентили, реализующие функцию f(a) = a*factors + bias (mod 2)."""
|
||||||
|
if secret_bias_bit:
|
||||||
|
yield cirq.X(output_qubit)
|
||||||
|
|
||||||
|
for qubit, bit in zip(input_qubits, secret_factor_bits):
|
||||||
|
if bit:
|
||||||
|
yield cirq.CNOT(qubit, output_qubit)
|
||||||
|
|
||||||
|
|
||||||
|
def make_bernstein_vazirani_circuit(input_qubits, output_qubit, oracle):
|
||||||
|
"""Находит множители в f (a) = a * factors + bias (mod 2) с помощью одного запроса."""
|
||||||
|
c = cirq.Circuit()
|
||||||
|
|
||||||
|
# Инициализировать кубиты
|
||||||
|
c.append(
|
||||||
|
[
|
||||||
|
cirq.X(output_qubit),
|
||||||
|
cirq.H(output_qubit),
|
||||||
|
cirq.H.on_each(*input_qubits),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Запрос оракула
|
||||||
|
c.append(oracle)
|
||||||
|
|
||||||
|
# Измерение по оси X
|
||||||
|
c.append([cirq.H.on_each(*input_qubits), cirq.measure(*input_qubits, key="result")])
|
||||||
|
|
||||||
|
return c
|
||||||
|
|
||||||
|
|
||||||
|
def bitstring(bits):
|
||||||
|
"""Создает битовую строку из итерации битов."""
|
||||||
|
return "".join(str(int(b)) for b in bits)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user