Skip to main content
IBM Quantum Platform

O algoritmo de Deutsch-Jozsa

O algoritmo de Deutsch supera todos os algoritmos clássicos para um problema de consulta, mas a vantagem é bastante modesta: uma consulta contra duas. O algoritmo Deutsch-Jozsa amplia essa vantagem e, de fato, pode ser usado para resolver alguns problemas de consulta diferentes.

Aqui está uma descrição do circuito quântico do algoritmo Deutsch-Jozsa. Uma etapa adicional clássica de pós-processamento, não mostrada na figura, também pode ser necessária, dependendo do problema específico que está sendo resolvido.

Algoritmo Deutsch-Jozsa

É claro que ainda não discutimos quais problemas esse algoritmo resolve; isso será feito nas duas seções a seguir.


O problema de Deutsch-Jozsa

Começaremos com o problema de consulta que o algoritmo Deutsch-Jozsa foi originalmente planejado para resolver, conhecido como o problema Deutsch-Jozsa.

A função de entrada para esse problema tem o formato f:ΣnΣf:\Sigma^n \rightarrow \Sigma para um número inteiro positivo arbitrário n.n. Como no problema de Deutsch, a tarefa é produzir 00 se ff for constante e 11 se ff for equilibrado, o que significa novamente que o número de cadeias de caracteres de entrada nas quais a função assume o valor 00 é igual ao número de cadeias de caracteres de entrada nas quais a função assume o valor 11.

Observe que, quando nn é maior que 1,1,, há funções do formato f:ΣnΣf:\Sigma^n \rightarrow \Sigma que não são constantes nem equilibradas. Por exemplo, a função f:Σ2Σf:\Sigma^2\rightarrow\Sigma definida como

f(00)=0f(01)=0f(10)=0f(11)=1\begin{aligned} f(00) & = 0 \\ f(01) & = 0 \\ f(10) & = 0 \\ f(11) & = 1 \end{aligned}

não se enquadra em nenhuma dessas duas categorias. No caso do problema Deutsch-Jozsa, simplesmente não nos preocupamos com funções como essa - elas são consideradas entradas "indiferentes". Ou seja, para esse problema, temos a promessa de que ff é constante ou equilibrado.

Deutsch-Jozsa problem

Entrada: uma função f:{0,1}n{0,1}f:\{0,1\}^n\rightarrow\{0,1\} \ Promessa: ff é constante ou equilibrada \ Saída: 00 se ff for constante, 11 se ff for equilibrado

O algoritmo de Deutsch-Jozsa, com sua única consulta, resolve esse problema da seguinte maneira: se todos os resultados das medições nn forem 0,0,, então a função ff é constante; caso contrário, se pelo menos um dos resultados das medições for 1,1,, então a função ff é equilibrada. Outra forma de expressar isso é dizer que o circuito descrito acima é seguido por uma etapa clássica de pós-processamento, na qual se calcula a operação OR dos resultados das medições para produzir o bit de saída do problema de Deutsch-Jozsa.

Análise de algoritmos

Para analisar o desempenho do algoritmo Deutsch-Jozsa para o problema Deutsch-Jozsa, é útil começar pensando na ação de uma única camada de portas Hadamard. Uma operação Hadamard pode ser expressa como uma matriz da maneira usual,

H=(12121212),H = \begin{pmatrix} \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} \\[2mm] \frac{1}{\sqrt{2}} & -\frac{1}{\sqrt{2}} \end{pmatrix},

mas também podemos expressar essa operação em termos de sua ação nos estados da base padrão:

H0=120+121H1=120121.\begin{aligned} H \vert 0\rangle & = \frac{1}{\sqrt{2}} \vert 0 \rangle + \frac{1}{\sqrt{2}} \vert 1 \rangle\\[3mm] H \vert 1\rangle & = \frac{1}{\sqrt{2}} \vert 0 \rangle - \frac{1}{\sqrt{2}} \vert 1 \rangle. \end{aligned}

Essas duas equações podem ser combinadas em uma única fórmula,

Ha=120+12(1)a1=12b{0,1}(1)abb,H \vert a \rangle = \frac{1}{\sqrt{2}} \vert 0 \rangle + \frac{1}{\sqrt{2}} (-1)^a \vert 1 \rangle = \frac{1}{\sqrt{2}} \sum_{b\in\{0,1\}} (-1)^{ab} \vert b\rangle,

o que é verdadeiro para ambas as opções de aΣ.a\in\Sigma.

Agora, suponha que, em vez de apenas um único qubit, tenhamos nn qubits e que uma operação Hadamard seja realizada em cada um deles. A operação combinada nos nn qubits é descrita pelo produto tensorial HHH\otimes \cdots \otimes H ( nn vezes), que escrevemos como HnH^{\otimes n} para fins de concisão e clareza. Usando a fórmula acima, seguida de expansão e simplificação, podemos expressar a ação dessa operação combinada nos estados da base padrão dos nn qubits da seguinte forma:

Hnxn1x1x0=(Hxn1)(Hx0)=(12yn1Σ(1)xn1yn1yn1)(12y0Σ(1)x0y0y0)=12nyn1y0Σn(1)xn1yn1++x0y0yn1y0.\begin{aligned} & H^{\otimes n} \vert x_{n-1} \cdots x_1 x_0 \rangle \\ & \qquad = \bigl(H \vert x_{n-1} \rangle \bigr) \otimes \cdots \otimes \bigl(H \vert x_{0} \rangle \bigr) \\ & \qquad = \Biggl( \frac{1}{\sqrt{2}} \sum_{y_{n-1}\in\Sigma} (-1)^{x_{n-1} y_{n-1}} \vert y_{n-1} \rangle \Biggr) \otimes \cdots \otimes \Biggl( \frac{1}{\sqrt{2}} \sum_{y_{0}\in\Sigma} (-1)^{x_{0} y_{0}} \vert y_{0} \rangle \Biggr) \\ & \qquad = \frac{1}{\sqrt{2^n}} \sum_{y_{n-1}\cdots y_0 \in \Sigma^n} (-1)^{x_{n-1}y_{n-1} + \cdots + x_0 y_0} \vert y_{n-1} \cdots y_0 \rangle. \end{aligned}

Aqui, a propósito, estamos escrevendo strings binárias de comprimento nn como xn1x0x_{n-1}\cdots x_0 e yn1y0,y_{n-1}\cdots y_0, seguindo a convenção de indexação do Qiskit.

Essa fórmula nos fornece uma ferramenta útil para analisar o circuito quântico acima. Após a execução da primeira camada de portas Hadamard, o estado dos n+1n+1 qubits (incluindo o qubit mais à esquerda/inferior, que é tratado separadamente do restante) é

(H1)(Hn00)=12nxn1x0Σnxn1x0.\bigl( H \vert 1 \rangle \bigr) \bigl( H^{\otimes n} \vert 0 \cdots 0 \rangle \bigr) = \vert - \rangle \otimes \frac{1}{\sqrt{2^n}} \sum_{x_{n-1}\cdots x_0 \in \Sigma^n} \vert x_{n-1} \cdots x_0 \rangle.

Quando a operação UfU_f é realizada, esse estado é transformado em

12nxn1x0Σn(1)f(xn1x0)xn1x0\vert - \rangle \otimes \frac{1}{\sqrt{2^n}} \sum_{x_{n-1}\cdots x_0 \in \Sigma^n} (-1)^{f(x_{n-1}\cdots x_0)} \vert x_{n-1} \cdots x_0 \rangle

exatamente pelo mesmo fenômeno de retorno de fase que vimos na análise do algoritmo de Deutsch.

Em seguida, a segunda camada de portas Hadamard é executada, o que (pela fórmula acima) transforma esse estado em

12nxn1x0Σnyn1y0Σn(1)f(xn1x0)+xn1yn1++x0y0yn1y0.\vert - \rangle \otimes \frac{1}{2^n} \sum_{x_{n-1}\cdots x_0 \in \Sigma^n} \sum_{y_{n-1}\cdots y_0 \in \Sigma^n} (-1)^{f(x_{n-1}\cdots x_0) + x_{n-1}y_{n-1} + \cdots + x_0 y_0} \vert y_{n-1} \cdots y_0 \rangle.

Essa expressão parece um pouco complicada, e não se pode concluir muito sobre as probabilidades de obter diferentes resultados de medição sem saber mais sobre a função f.f.

Felizmente, tudo o que precisamos saber é a probabilidade de que cada um dos resultados da medição seja 00 - porque essa é a probabilidade de que o algoritmo determine que ff é constante. Essa probabilidade tem uma fórmula simples.

12nxn1x0Σn(1)f(xn1x0)2={1if f is constant0if f is balanced\Biggl\vert \frac{1}{2^n} \sum_{x_{n-1}\cdots x_0 \in \Sigma^n} (-1)^{f(x_{n-1}\cdots x_0)} \Biggr\vert^2 = \begin{cases} 1 & \text{if $f$ is constant}\\[1mm] 0 & \text{if $f$ is balanced} \end{cases}

Observe que esses valores correspondem à probabilidade de se medir o estado 0n\vert 0^{\otimes n} \rangle, e não diretamente ao bit de saída clássico final do problema de Deutsch-Jozsa. O algoritmo gera o resultado “ 00 ” quando todos os resultados das medições são “ 00 ” (indicando que “ ff ” é constante) e, caso contrário, gera “ 11 ” (indicando que “ ff ” está em equilíbrio).

Mais detalhadamente, se ff for constante, então f(xn1x0)=0f(x_{n-1}\cdots x_0) = 0 para cada string xn1x0,x_{n-1}\cdots x_0, caso em que o valor da soma é 2n,2^n, ou f(xn1x0)=1f(x_{n-1}\cdots x_0) = 1 para cada string xn1x0,x_{n-1}\cdots x_0, e, nesse caso, o valor da soma é 2n.-2^n. Dividindo por 2n2^n e tomando o quadrado do valor absoluto, obtém-se 1.1.

Se, por outro lado, ff estiver equilibrado, então ff assume o valor 00 em metade das cadeias de caracteres xn1x0x_{n-1}\cdots x_0 e o valor 11 na outra metade, de modo que os termos +1+1 e 1-1 na soma se cancelam e ficamos com o valor 0.0.

Concluímos que o algoritmo funciona corretamente desde que a promessa seja cumprida.

Dificuldade clássica

O algoritmo Deutsch-Jozsa funciona todas as vezes, sempre nos dando a resposta correta quando a promessa é cumprida, e requer uma única consulta. Como isso se compara aos algoritmos de consulta clássicos para o problema Deutsch-Jozsa?

Primeiro, qualquer algoritmo clássico determinístico que resolva corretamente o problema Deutsch-Jozsa deve fazer um número exponencial de consultas: 2n1+12^{n-1} + 1 consultas são necessárias no pior dos casos. O raciocínio é que, se um algoritmo determinístico consultar ff em 2n12^{n-1} ou menos cadeias de caracteres diferentes e obtiver o mesmo valor de função todas as vezes, então ambas as respostas ainda serão possíveis. A função pode ser constante ou equilibrada, mas, por azar, todas as consultas retornam o mesmo valor de função.

A segunda possibilidade pode parecer improvável, mas para algoritmos determinísticos não há aleatoriedade ou incerteza, portanto, eles falharão sistematicamente em determinadas funções. Portanto, temos uma vantagem significativa dos algoritmos quânticos em relação aos clássicos nesse aspecto.

No entanto, há um problema: os algoritmos clássicos probabilísticos podem resolver o problema Deutsch-Jozsa com uma probabilidade muito alta usando apenas algumas consultas. Em particular, se simplesmente escolhermos algumas cadeias diferentes de comprimento nn aleatoriamente e consultarmos ff nessas cadeias, é improvável que obtenhamos o mesmo valor de função para todas elas quando ff estiver equilibrado.

Para ser mais específico, se escolhermos as cadeias de entrada kk x1,,xkΣnx^1,\ldots,x^k \in \Sigma^n uniformemente ao acaso, avaliarmos f(x1),,f(xk),f(x^1),\ldots,f(x^k), e respondermos 00 se os valores da função forem todos iguais e 11 se não forem, então sempre estaremos corretos quando ff for constante e errados no caso de ff ser equilibrado com probabilidade igual a 2k+1.2^{-k + 1}. Se considerarmos k=11,k = 11,, por exemplo, esse algoritmo responderá corretamente com probabilidade maior que 99.999.9 %.

Por esse motivo, ainda temos uma vantagem bastante modesta dos algoritmos quânticos em relação aos clássicos, mas, ainda assim, é uma vantagem quantificável que representa um aprimoramento em relação ao algoritmo de Deutsch.


Deutsch-Jozsa com Qiskit

from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator
import numpy as np

Para implementar o algoritmo Deutsch-Jozsa no Qiskit, começaremos definindo uma função dj_query que gera um circuito quântico implementando uma porta de consulta, para uma função selecionada aleatoriamente que satisfaça a promessa do problema Deutsch-Jozsa. Com 50% de chance, a função é constante, e com 50% de mudança, a função é equilibrada. Para cada uma dessas duas possibilidades, a função é selecionada uniformemente entre as funções desse tipo. O argumento é o número de bits de entrada da função.

def dj_query(num_qubits):
    # Create a circuit implementing for a query gate for a random function
    # satisfying the promise for the Deutsch-Jozsa problem.

    qc = QuantumCircuit(num_qubits + 1)

    if np.random.randint(0, 2):
        # Flip output qubit with 50% chance
        qc.x(num_qubits)
    if np.random.randint(0, 2):
        # return constant circuit with 50% chance
        return qc

    # Choose half the possible input strings
    on_states = np.random.choice(
        range(2**num_qubits),  # numbers to sample from
        2**num_qubits // 2,  # number of samples
        replace=False,  # makes sure states are only sampled once
    )

    def add_cx(qc, bit_string):
        for qubit, bit in enumerate(reversed(bit_string)):
            if bit == "1":
                qc.x(qubit)
        return qc

    for state in on_states:
        qc.barrier()  # Barriers are added to help visualize how the functions are created.
        qc = add_cx(qc, f"{state:0b}")
        qc.mcx(list(range(num_qubits)), num_qubits)
        qc = add_cx(qc, f"{state:0b}")

    qc.barrier()

    return qc

Podemos mostrar a implementação do circuito quântico da porta de consulta usando o método draw como de costume.

display(dj_query(3).draw(output="mpl"))

Output:

Output of the previous code cell

Em seguida, definimos uma função que cria o circuito Deutsch-Jozsa, tendo como argumento uma implementação de circuito quântico de uma porta de consulta.

def compile_circuit(function: QuantumCircuit):
    # Compiles a circuit for use in the Deutsch-Jozsa algorithm.

    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

Por fim, é definida uma função que executa o circuito Deutsch-Jozsa uma vez.

def dj_algorithm(function: QuantumCircuit):
    # Determine if a function is constant or balanced.

    qc = compile_circuit(function)

    result = AerSimulator().run(qc, shots=1, memory=True).result()
    measurements = result.get_memory()
    if "1" in measurements[0]:
        return "balanced"
    return "constant"

Podemos testar nossa implementação escolhendo uma função aleatoriamente, exibindo a implementação do circuito quântico de uma porta de consulta para essa função e, em seguida, executando o algoritmo Deutsch-Jozsa nessa função.

f = dj_query(3)
display(f.draw("mpl"))
display(dj_algorithm(f))

Output:

Output of the previous code cell
'balanced'

O problema de Bernstein-Vazirani

A seguir, discutiremos um problema conhecido como problema de Bernstein-Vazirani. Ele também é chamado de problema de amostragem de Fourier, embora existam formulações mais gerais desse problema que também têm esse nome.

Primeiro, vamos introduzir algumas notações. Para quaisquer duas cadeias binárias x=xn1x0x = x_{n-1} \cdots x_0 e y=yn1y0y = y_{n-1}\cdots y_0 de comprimento n,n,, definimos

xy=xn1yn1x0y0.x \cdot y = x_{n-1} y_{n-1} \oplus \cdots \oplus x_0 y_0.

Vamos nos referir a essa operação como o produto de ponto binário. Uma maneira alternativa de defini-lo é assim.

xy={1xn1yn1++x0y0 is odd0xn1yn1++x0y0 is evenx \cdot y = \begin{cases} 1 & x_{{n-1}} y_{n-1} + \cdots + x_0 y_0 \text{ is odd}\\[0.5mm] 0 & x_{{n-1}} y_{n-1} + \cdots + x_0 y_0 \text{ is even} \end{cases}

Observe que essa é uma operação simétrica, o que significa que o resultado não muda se trocarmos xx e y,y,, portanto, podemos fazer isso sempre que for conveniente. Às vezes, é útil pensar no produto de ponto binário xyx \cdot y como sendo a paridade dos bits de xx nas posições em que a cadeia de caracteres yy tem um 1,1, ou, de forma equivalente, a paridade dos bits de yy nas posições em que a cadeia de caracteres xx tem um 1.1.

Com essa notação em mãos, podemos agora definir o problema de Bernstein-Vazirani.

Bernstein-Vazirani problem

Entrada: uma função f:{0,1}n{0,1}f:\{0,1\}^n\rightarrow\{0,1\} \ Promessa: existe uma string binária s=sn1s0s = s_{n-1} \cdots s_0 para a qual f(x)=sxf(x) = s\cdot x para todos os xΣnx\in\Sigma^n \ Saída: a string ss

Na verdade, não precisamos de um novo algoritmo quântico para esse problema; o algoritmo Deutsch-Jozsa o resolve. Para fins de clareza, vamos nos referir ao circuito quântico acima, que não inclui a etapa clássica de pós-processamento de computação do OU, como o circuito Deutsch-Jozsa.

Análise de algoritmos

Para analisar como o circuito Deutsch-Jozsa funciona para uma função que satisfaz a promessa do problema Bernstein-Vazirani, começaremos com uma observação rápida. Usando o produto de ponto binário, podemos, alternativamente, descrever a ação de nn Hadamard gates nos estados de base padrão de nn qubits da seguinte forma.

Hnx=12nyΣn(1)xyyH^{\otimes n} \vert x \rangle = \frac{1}{\sqrt{2^n}} \sum_{y\in\Sigma^n} (-1)^{x\cdot y} \vert y\rangle

Semelhante ao que vimos ao analisar o algoritmo de Deutsch, isso ocorre porque o valor (1)k(-1)^k para qualquer número inteiro kk depende apenas do fato de kk ser par ou ímpar.

Voltando ao circuito Deutsch-Jozsa, após a execução da primeira camada de portas Hadamard, o estado dos n+1n+1 qubits é

12nxΣnx.\vert - \rangle \otimes \frac{1}{\sqrt{2^n}} \sum_{x \in \Sigma^n} \vert x \rangle.

A porta de consulta é então executada, o que (por meio do fenômeno de retrocesso de fase) transforma o estado em

12nxΣn(1)f(x)x.\vert - \rangle \otimes \frac{1}{\sqrt{2^n}} \sum_{x \in \Sigma^n} (-1)^{f(x)} \vert x \rangle.

Usando nossa fórmula para a ação de uma camada de portas Hadamard, vemos que a segunda camada de portas Hadamard transforma esse estado em

12nxΣnyΣn(1)f(x)+xyy.\vert - \rangle \otimes \frac{1}{2^n} \sum_{x \in \Sigma^n} \sum_{y \in \Sigma^n} (-1)^{f(x) + x \cdot y} \vert y \rangle.

Agora podemos fazer algumas simplificações, no expoente de 1-1 dentro da soma. Prometemos que f(x)=sxf(x) = s\cdot x para alguma string s=sn1s0,s = s_{n-1} \cdots s_0, para que possamos expressar o estado como

12nxΣnyΣn(1)sx+xyy.\vert - \rangle \otimes \frac{1}{2^n} \sum_{x \in \Sigma^n} \sum_{y \in \Sigma^n} (-1)^{s\cdot x + x \cdot y} \vert y \rangle.

Como sxs\cdot x e xyx\cdot y são valores binários, podemos substituir a adição pelo exclusivo-OR - novamente porque a única coisa que importa para um número inteiro no expoente de 1-1 é se ele é par ou ímpar. Usando a simetria do produto de ponto binário, obtemos essa expressão para o estado:

12nxΣnyΣn(1)(sx)(yx)y.\vert - \rangle \otimes \frac{1}{2^n} \sum_{x \in \Sigma^n} \sum_{y \in \Sigma^n} (-1)^{(s\cdot x) \oplus (y \cdot x)} \vert y \rangle.

(Os parênteses foram adicionados para fins de clareza, embora não sejam realmente necessários, pois é convencional tratar o produto de ponto binário como tendo precedência mais alta do que o exclusivo-OR)

Neste ponto, usaremos a seguinte fórmula.

(sx)(yx)=(sy)x(s\cdot x) \oplus (y \cdot x) = (s \oplus y) \cdot x

Podemos obter a fórmula por meio de uma fórmula semelhante para bits,

(ac)(bc)=(ab)c,(a c) \oplus (b c) = (a \oplus b) c,

juntamente com uma expansão do produto de ponto binário e do bitwise exclusive-OR:

(sx)(yx)=(sn1xn1)(s0x0)(yn1xn1)(y0x0)=(sn1yn1)xn1(s0y0)x0=(sy)x\begin{aligned} (s\cdot x) \oplus (y \cdot x) & = (s_{n-1} x_{n-1}) \oplus \cdots \oplus (s_{0} x_{0}) \oplus (y_{n-1} x_{n-1}) \oplus \cdots \oplus (y_{0} x_{0}) \\ & = (s_{n-1} \oplus y_{n-1}) x_{n-1} \oplus \cdots \oplus (s_{0} \oplus y_{0}) x_{0} \\ & = (s \oplus y) \cdot x \end{aligned}

Isso nos permite expressar o estado do circuito imediatamente antes das medições da seguinte forma:

12nxΣnyΣn(1)(sy)xy.\vert - \rangle \otimes \frac{1}{2^n} \sum_{x \in \Sigma^n} \sum_{y \in \Sigma^n} (-1)^{(s\oplus y)\cdot x} \vert y \rangle.

A etapa final é usar outra fórmula, que funciona para cada string binária z=zn1z0.z = z_{n-1}\cdots z_0.

12nxΣn(1)zx={1if z=0n0if z0n\frac{1}{2^n} \sum_{x \in \Sigma^n} (-1)^{z \cdot x} = \begin{cases} 1 & \text{if $z = 0^n$}\\ 0 & \text{if $z\neq 0^n$} \end{cases}

Aqui estamos usando uma notação simples para cadeias de caracteres que usaremos várias outras vezes na lição: 0n0^n é a cadeia de caracteres totalmente zero de comprimento n.n.

Uma maneira simples de argumentar que essa fórmula funciona é considerar os dois casos separadamente. Se z=0n,z = 0^n,, então zx=0z\cdot x = 0 para cada cadeia de caracteres xΣn,x\in\Sigma^n,, então o valor de cada termo na soma é 1,1, e obtemos 11 somando e dividindo por 2n.2^n. Por outro lado, se qualquer um dos bits de zz for igual a 1,1,, então o produto de ponto binário zxz\cdot x é igual a 00 para exatamente metade das escolhas possíveis para xΣnx\in\Sigma^n e 11 para a outra metade - porque o valor do produto de ponto binário zxz\cdot x inverte (de 00 para 11 ou de 11 para 00 ) se invertermos qualquer bit de xx em uma posição em que zz tenha um 1.1.

Se agora aplicarmos essa fórmula para simplificar o estado do circuito antes das medições, obteremos

12nxΣnyΣn(1)(sy)xy=s,\vert - \rangle \otimes \frac{1}{2^n} \sum_{x \in \Sigma^n} \sum_{y \in \Sigma^n} (-1)^{(s\oplus y)\cdot x} \vert y \rangle = \vert - \rangle \otimes \vert s \rangle,

devido ao fato de que sy=0ns\oplus y = 0^n se e somente se y=s.y = s. Portanto, as medições revelam precisamente a string ss que estamos procurando.

Dificuldade clássica

Enquanto o circuito Deutsch-Jozsa resolve o problema Bernstein-Vazirani com uma única consulta, qualquer algoritmo de consulta clássico precisa fazer pelo menos nn consultas para resolver esse problema.

Isso pode ser explicado por meio do chamado argumento da teoria da informação, que é muito simples nesse caso. Cada consulta clássica revela um único bit de informação sobre a solução, e há nn bits de informação que precisam ser descobertos - portanto, são necessárias pelo menos nn consultas.

De fato, é possível resolver o problema de Bernstein-Vazirani de forma clássica, consultando a função em cada uma das cadeias de caracteres nn com um único 1,1, em cada posição possível e 00 para todos os outros bits, o que revela os bits de ss um de cada vez. Portanto, a vantagem do quantum sobre os algoritmos clássicos para esse problema é 11 query versus nn queries.


Bernstein-Vazirani com Qiskit

Já implementamos o circuito Deutsch-Jozsa acima e aqui o utilizaremos para resolver o problema Bernstein-Vazirani. Primeiro, definiremos uma função que implementa uma porta de consulta para o problema de Bernstein-Vazirani com qualquer string binária s.s.

def bv_query(s):
    # Create a quantum circuit implementing a query gate for the
    # Bernstein-Vazirani problem.

    qc = QuantumCircuit(len(s) + 1)
    for index, bit in enumerate(reversed(s)):
        if bit == "1":
            qc.cx(index, len(s))
    return qc


display(bv_query("1011").draw(output="mpl"))

Output:

Output of the previous code cell

Agora podemos criar uma função que executa o circuito Deutsch-Jozsa na função, usando a função compile_circuit que foi definida anteriormente.

def bv_algorithm(function: QuantumCircuit):
    qc = compile_circuit(function)
    result = AerSimulator().run(qc, shots=1, memory=True).result()
    return result.get_memory()[0]


display(bv_algorithm(bv_query("1011")))

Output:

'1011'

Observação sobre a nomenclatura

No contexto do problema Bernstein-Vazirani, é comum que o algoritmo Deutsch-Jozsa seja chamado de "algoritmo Bernstein-Vazirani" Isso é um pouco enganoso, pois o algoritmo é o algoritmo Deutsch-Jozsa, como Bernstein e Vazirani deixaram bem claro em seu trabalho.

O que Bernstein e Vazirani fizeram depois de mostrar que o algoritmo Deutsch-Jozsa resolve o problema de Bernstein-Vazirani (como foi dito acima) foi definir um problema muito mais complicado, conhecido como problema de amostragem recursiva de Fourier. Esse é um problema altamente planejado em que as soluções para diferentes instâncias do problema efetivamente desbloqueiam novos níveis do problema organizados em uma estrutura semelhante a uma árvore. O problema de Bernstein-Vazirani é essencialmente apenas o caso básico desse problema mais complicado.

O problema de amostragem recursiva de Fourier foi o primeiro exemplo conhecido de um problema de consulta em que os algoritmos quânticos têm a chamada vantagem superpolinomial sobre os algoritmos probabilísticos, superando assim a vantagem do quântico sobre o clássico oferecida pelo algoritmo Deutsch-Jozsa. Intuitivamente falando, a versão recursiva do problema amplia a vantagem 11 versus nn dos algoritmos quânticos para algo muito maior.

O aspecto mais desafiador da análise matemática que estabelece essa vantagem é mostrar que os algoritmos de consulta clássicos não conseguem resolver o problema sem fazer muitas consultas. Isso é bastante comum; para muitos problemas, pode ser muito difícil descartar abordagens clássicas criativas que os resolvam de forma eficiente.

O problema de Simon e o algoritmo para ele descrito na próxima seção fornecem um exemplo muito mais simples de uma vantagem superpolinomial (e, na verdade, exponencial) do quantum em relação aos algoritmos clássicos e, por esse motivo, o problema de amostragem recursiva de Fourier é discutido com menos frequência. No entanto, esse é um problema computacional interessante por si só.

Esta página foi útil?
Relate um bug, erro de digitação ou solicite conteúdo no GitHub.