Algoritmo de Bernstein-Vazirani
El algoritmo de Bernstein-Vazirani es un algoritmo basado en el de Deutsch-Jozsa en el cual se resuelve un problema diferente, llamado problema de Bernstein-Vazirani ó Fourier sampling problem (problema de muestreo de Fourier). Dicho problema presenta una base de un problema más grande, presentado por los mismos autores, llamado recursive Fourier sampling problem (problema de muestreo de Fourier recursivo).
El Problema de Bernstein-Vazirani
Sección titulada «El Problema de Bernstein-Vazirani»La entrada del problema es una función que se define de forma similar al algoritmo de Deutsch-Jozsa:
Difiere en que en este problema la función tiene como precondición que existe una cadena binaria tal que para todo .
Como salida se debe obtener la cadena .
Solución
Sección titulada «Solución»Utiliza el circuito de Deutsch-Jozsa. Varía en su procesamiento desde la etapa donde se mide el resultado.

Figura (1): Circuito de Deutsch-Jozsa que resuelve el problema de Bernstein-Vazirani con separadores ante la aplicación de cada puerta.
A continuación se analiza paso a paso el estado de los cubits según los separadores provistos en el gráfico, donde \(\psi_i\) es el estado en el paso \(i\), empezando con \(i=0\) y finalizando con \(i=3\):
Un desarrollo elaborado de los pasos se puede observar dentro de la explicación paso a paso del algoritmo de Deutsch-Jozsa. Hasta este punto no existen variaciones con el algoritmo previamente mencionado. Luego se reemplaza con la precondición dada:
Ahora, se mide la amplitud del estado , donde es :
Así, el estado final del algoritmo (luego de la medición) es , ya que el resto de estados tendrán amplitud 0.
Ejemplos
Sección titulada «Ejemplos»Sea la cadena a codificar, se modifica el oráculo con una función que codifica este valor oculto. Se utilizan puertas CNOT para codificar la cadena oculta.
Estado inicial del algoritmo
Aplicación de puertas Hadamard sobre los tres cubits menos significativos.
Aplicación del oráculo. En este ejemplo, el oráculo está implementado con dos puertas . La primera tiene al cubit menos significativo como control y la segunda al tercer cubit menos significativo. En ambos casos, el cubit objetivo es el del oráculo (el más significativo).
Se aplica Hadamard sobre los cubits que no son del oráculo (todos excepto el más significativo). Así se obtiene la respuesta final.
Ignorando el estado del cubit del oráculo (el cubit más significativo), la probabilidad de obtener es del .
from qiskit import QuantumCircuitfrom algorithms import run_circuit, circuit_deutsch_jozsaimport sys
def bv_function(s): """ Crea una función Bernstein-Vazirani desde una cadena de 1s y 0s. """ qc = QuantumCircuit(len(s) + 1) qc.barrier() for index, bit in enumerate(s): if bit == "1": qc.cx(index, len(s)) qc.barrier() return qc
def analyze_bv_results(results): counts = results.get_counts() return counts
s_string = "1010"if len(sys.argv) >= 2: s_string = sys.argv[1] # permite utilizar cadena por parametroprint("Cadena secreta 's':", s_string)print("Oráculo:")oracle = bv_function(s_string) # codifica la función secreta con 's'print(oracle.draw())print("Bernstein-Vazirani con circuito Deutsch-Jozsa:")bv_circuit = circuit_deutsch_jozsa(oracle)print(bv_circuit.draw())print("Corriendo el circuito Bernstein-Vazirani:")print(analyze_bv_results(run_circuit(bv_circuit) ))
Cadena secreta 's': 1010Oráculo: ░ ░q_0: ─░───■────────░─ ░ │ ░q_1: ─░───┼────────░─ ░ │ ░q_2: ─░───┼────■───░─ ░ │ │ ░q_3: ─░───┼────┼───░─ ░ ┌─┴─┐┌─┴─┐ ░q_4: ─░─┤ X ├┤ X ├─░─ ░ └───┘└───┘ ░Bernstein-Vazirani con circuito Deutsch-Jozsa: ┌───┐ ░ ░ ┌───┐┌─┐q_0: ┤ H ├──────░───■────────░─┤ H ├┤M├───────── ├───┤ ░ │ ░ ├───┤└╥┘┌─┐q_1: ┤ H ├──────░───┼────────░─┤ H ├─╫─┤M├────── ├───┤ ░ │ ░ ├───┤ ║ └╥┘┌─┐q_2: ┤ H ├──────░───┼────■───░─┤ H ├─╫──╫─┤M├─── ├───┤ ░ │ │ ░ ├───┤ ║ ║ └╥┘┌─┐q_3: ┤ H ├──────░───┼────┼───░─┤ H ├─╫──╫──╫─┤M├ ├───┤┌───┐ ░ ┌─┴─┐┌─┴─┐ ░ └───┘ ║ ║ ║ └╥┘q_4: ┤ X ├┤ H ├─░─┤ X ├┤ X ├─░───────╫──╫──╫──╫─ └───┘└───┘ ░ └───┘└───┘ ░ ║ ║ ║ ║c: 4/════════════════════════════════╩══╩══╩══╩═ 0 1 2 3Corriendo el circuito Bernstein-Vazirani:{'0101': 1024}
from qiskit import QuantumCircuitfrom qiskit_aer import QasmSimulatorfrom qiskit import transpile
def run_circuit(qc: QuantumCircuit): sim = QasmSimulator() transpiled = transpile(qc) result = sim.run(transpiled).result() return result
def circuit_deutsch_jozsa(function: QuantumCircuit): """ Compila un circuito para usarlo en el algoritmo de Deutsch-Jozsa. """ n = function.num_qubits - 1 qc = QuantumCircuit(n + 1, n) qc.x(n) qc.h(range(n + 1)) qc.compose(function, inplace=True) qc.h(range(n)) qc.measure(range(n), range(n)) return qc