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