Алгоритм Бернштейна–Вазирани

This commit is contained in:
2025-09-30 18:50:00 +03:00
parent ac2f465ae2
commit b85f09e680

91
task4/main.py Normal file
View 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()