Files

92 lines
3.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Алгоритм Бернштейна–Вазирани в 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()