<jupyter_start><jupyter_text>Algorithme Deutsch-Jozsa Dans cette section, nous introduisons d'abord le problème de Deutsch-Jozsa, et les algorithmes classiques et quantiques pour le résoudre. Nous implémentons ensuite l'algorithme quantique à l'aide de Qiskit et l'exécutons sur un simulateur et un appareil.  1. Introduction L'algorithme de Deutsch-Jozsa, introduit pour la première fois dans la référence [1], était le premier exemple d'un algorithme quantique qui fonctionne mieux que le meilleur algorithme classique. Il a montré qu'il peut y avoir des avantages à utiliser un ordinateur quantique comme outil de calcul pour un problème spécifique.  1.1 Problème de Deutsch-Jozsa On nous donne une fonction booléenne cachée $f$, qui prend en entrée une chaîne de bits, et retourne $0$ ou $1$, c'est-à-dire :$$ f({x_0,x_1,x_2,...}) \rightarrow 0 \textrm{ ou } 1 \textrm{ , où } x_n \textrm{ vaut } 0 \textrm{ ou } 1$$La propriété de la fonction booléenne donnée est qu'elle est garantie équilibrée ou constante. Une fonction constante renvoie tous les $0$ ou tous les $1$ pour n'importe quelle entrée, tandis qu'une fonction équilibrée renvoie des $0$ pour exactement la moitié de toutes les entrées et des $1$ pour l'autre moitié. Notre tâche est de déterminer si la fonction donnée est équilibrée ou constante.Notez que le problème de Deutsch-Jozsa est une extension $n$-bit du problème de Deutsch à un seul bit. 1.2 La solution classique Classiquement, dans le meilleur des cas, deux requêtes à l'oracle peuvent déterminer si la fonction booléenne cachée, $f(x)$, est équilibrée : par exemple, si nous obtenons à la fois $f(0,0,0,...)\rightarrow 0$ et $f(1,0,0,...) \rightarrow 1$, alors nous savons que la fonction est équilibrée car nous avons obtenu les deux sorties différentes.Dans le pire des cas, si nous continuons à voir la même sortie pour chaque entrée que nous essayons, nous devrons vérifier exactement la moitié de toutes les entrées possibles plus une afin d'être certain que $f(x)$ est constant. Puisque le nombre total d'entrées possibles est $2^n$, cela implique que nous avons besoin de $2^{n-1}+1$ entrées d'essai pour être certain que $f(x)$ est constant dans le pire des cas. Par exemple, pour une chaîne $4$-bit, si nous avons vérifié $8$ parmi les $16$ combinaisons possibles, obtenant tous les $0$, il est toujours possible que l'entrée $9^\textrm{th}$ renvoie un $1$ et $f(x)$ est équilibré. De manière probabiliste, il s'agit d'un événement très improbable. En fait, si nous obtenons continuellement le même résultat successivement, nous pouvons exprimer la probabilité que la fonction soit constante en fonction de $k$ entrées comme :$$ P_\textrm{constante}(k) = 1 - \frac{1}{2^{k-1}} \qquad \textrm{for } 1 &lt; k \leq 2^{n-1}$$De manière réaliste, nous pourrions choisir de tronquer notre algorithme classique plus tôt, disons si nous étions plus de x % confiants. Mais si nous voulons être sûrs à 100 %, nous devons vérifier les entrées $2^{n-1}+1$.  1.3 Solution quantique En utilisant un ordinateur quantique, nous pouvons résoudre ce problème avec une confiance de 100 % après un seul appel à la fonction $f(x)$, à condition d'avoir la fonction $f$ implémentée comme un oracle quantique, qui mappe l'état $\vert x \rangle \vert y\rangle $ à $ \vert x\rangle \vert y \oplus f(x)\rangle$, où $\oplus$ est l'addition modulo $2$. Vous trouverez ci-dessous le circuit générique de l'algorithme Deutsch-Jozsa.![image1](images/deutsch_steps.png)Passons maintenant aux étapes de l'algorithme :   Préparez deux registres quantiques. Le premier est un registre $n$-qubit initialisé à $|0\rangle$, et le second est un registre à un qubit initialisé à $|1\rangle$ :$$\vert \psi_0 \rangle = \vert0\rangle^{\otimes n} \vert 1\rangle$$      Appliquez une porte Hadamard à chaque qubit :$$\vert \psi_1 \rangle = \frac{1}{\sqrt{2^{n+1}}}\sum_{x=0}^{2^n-1} \vert x\rangle \left( |0\rangle - |1 \rangle \right)$$      Appliquez l'oracle quantique $\vert x\rangle \vert y\rangle$ à $\vert x\rangle \vert y \oplus f(x)\rangle$ : $$ \begin{aligned} \lvert \psi_2 \rangle &amp; = \frac{1}{\sqrt{2^{n+1}}}\sum_{x=0}^{2^n-1} \vert x\rangle (\vert f(x)\rangle - \ vert 1 \oplus f(x)\rangle) \\ &amp; = \frac{1}{\sqrt{2^{n+1}}}\sum_{x=0}^{2^n-1}(- 1)^{f(x)}|x\rangle ( |0\rangle - |1\rangle ) \end{aligné} $$puisque pour chaque $x,f(x)$ vaut $0$ ou $1$.      À ce stade, le deuxième registre de qubit unique peut être ignoré. Appliquez une porte Hadamard à chaque qubit du premier registre : $$ \begin{aligned} \lvert \psi_3 \rangle &amp; = \frac{1}{2^n}\sum_{x=0}^{2^n- 1}(-1)^{f(x)} \left[ \sum_{y=0}^{2^n-1}(-1)^{x \cdot y} \vert y \rangle \right] \\ &amp; = \frac{1}{2^n}\sum_{y=0}^{2^n-1} \left[ \sum_{x=0}^{2^n-1}(-1 )^{f(x)}(-1)^{x \cdot y} \right] \vert y \rangle \end{aligned} $$où $x \cdot y = x_0y_0 \oplus x_1y_1 \oplus \ldots \oplus x_{n-1}y_{n-1}$ est la somme du produit au niveau du bit.      Mesurez le premier registre. Notez que la probabilité de mesurer $\vert 0 \rangle ^{\otimes n} = \lvert \frac{1}{2^n}\sum_{x=0}^{2^n-1}(-1) ^{f(x)} \rvert^2$, qui vaut $1$ si $f(x)$ est constant et $0$ si $f(x)$ est équilibré. 1.4 Pourquoi cela fonctionne-t-il ? - **Oracle constant**Lorsque l'oracle est *constant* , il n'a aucun effet (jusqu'à une phase globale) sur les qubits d'entrée, et les états quantiques avant et après l'interrogation de l'oracle sont les mêmes. Puisque la porte H est son propre inverse, à l'étape 4, nous inversons l'étape 2 pour obtenir l'état quantique initial de $|00\dots 0\rangle$ dans le premier registre. $$ H^{\otimes n}\begin{bmatrix} 1 \ 0 \ 0 \ \vdots \ 0 \end{bmatrix} \tfrac{1}{\sqrt{2^n}}\begin{bmatrix} 1 \ 1 \ 1 \ \vdots \ 1 \end{bmatrix} \quad \xrightarrow{\text{after } U_f} \quad H^ {\otimes n}\tfrac{1}{\sqrt{2^n}}\begin{bmatrix} 1 \ 1 \ 1 \ \vdots \ 1 \end{bmatrix}\begin{bmatrice} 1 \ 0 \ 0 \ \vdots \ 0 \end{bmatrice} $$- **Oracle équilibré**Après l'étape 2, notre registre d'entrée est une superposition égale de tous les états de la base de calcul. Lorsque l'oracle est *équilibré* , le retour de phase ajoute une phase négative à exactement la moitié de ces états : $$ U_f \tfrac{1}{\sqrt{2^n}}\begin{bmatrix} 1 \ 1 \ 1 \ \vdots \ 1 \end{bmatrix}\tfrac{1}{\sqrt{2^n}}\begin{bmatrice} -1 \ 1 \ -1 \ \vdots \ 1 \end{bmatrice} $$L'état quantique après interrogation de l'oracle est orthogonal à l'état quantique avant interrogation de l'oracle. Ainsi, à l'étape 4, lors de l'application des portes H, nous devons nous retrouver avec un état quantique orthogonal à $|00\dots 0\rangle$. Cela signifie que nous ne devrions jamais mesurer l'état tout à zéro.  2. Exemple concretPassons en revue un exemple spécifique pour une fonction équilibrée à deux bits :Considérons une fonction à deux bits $f(x_0,x_1)=x_0 \oplus x_1$ telle que$f(0,0)=0$$f(0,1)=1$$f(1,0)=1$$f(1,1)=0$L'oracle de phase correspondant de cet oracle à deux bits est $U_f \lvert x_1, x_0 \rangle = (-1)^{f(x_1, x_0)}\lvert x \rangle$Nous allons maintenant vérifier si cet oracle fonctionne comme prévu en prenant un exemple d'état $$\lvert \psi_0 \rangle = \lvert 0 0 \rangle_{01} \otimes \lvert 1 \rangle_{2} $$    Le premier registre de deux qubits est initialisé à $|00\rangle$ et le second registre qubit à $|1\rangle$(Notez que nous utilisons les indices 0, 1 et 2 pour indexer les qubits. Un indice de "01" indique l'état du registre contenant les qubits 0 et 1)$$\lvert \psi_0 \rangle = \lvert 0 0 \rangle_{01} \otimes \lvert 1 \rangle_{2} $$      Appliquer Hadamard sur tous les qubits$$\lvert \psi_1 \rangle = \frac{1}{2} \left( \lvert 0 0 \rangle + \lvert 0 1 \rangle + \lvert 1 0 \rangle + \lvert 1 1 \rangle \right) *{01} \otimes \frac{1}{\sqrt{2}} \left( \lvert 0 \rangle - \lvert 1 \rangle \right)* {2} $$      La fonction oracle peut être implémentée sous la forme $\text{Q}_f = CX_{02}CX_{12}$, $$ \begin{aligned} \lvert \psi_2 \rangle = \frac{1}{2\sqrt{2 }} \left[ \lvert 0 0 \rangle_{01} \otimes \left( \lvert 0 \oplus 0 \oplus 0 \rangle - \lvert 1 \oplus 0 \oplus 0 \rangle \right)_{2} \ \ + \lvert 0 1 \rangle_{01} \otimes \left( \lvert 0 \oplus 0 \oplus 1 \rangle - \lvert 1 \oplus 0 \oplus 1 \rangle \right)_{2} \\ + \ lvert 1 0 \rangle_{01} \otimes \left( \lvert 0 \oplus 1 \oplus 0 \rangle - \lvert 1 \oplus 1 \oplus 0 \rangle \right)_{2} \\ + \lvert 1 1 \rangle_{01} \otimes \left( \lvert 0 \oplus 1 \oplus 1 \rangle - \lvert 1 \oplus 1 \oplus 1 \rangle \right)_{2} \right] \end{aligned} $$   En simplifiant cela, nous obtenons ceci : $$ \begin{aligned} \lvert \psi_2 \rangle &amp; = \frac{1}{2\sqrt{2}} \left[ \lvert 0 0 \rangle_{01} \otimes \left( \lvert 0 \rangle - \lvert 1 \rangle \right)_{2} - \lvert 0 1 \rangle_{01} \otimes \left( \lvert 0 \rangle - \lvert 1 \rangle \right) _{2} - \lvert 1 0 \rangle_{01} \otimes \left( \lvert 0 \rangle - \lvert 1 \rangle \right)_{2} + \lvert 1 1 \rangle_{01} \otimes \ gauche( \lvert 0 \rangle - \lvert 1 \rangle \right)_{2} \right] \\ &amp; = \frac{1}{2} \left( \lvert 0 0 \rangle - \lvert 0 1 \ rangle - \lvert 1 0 \rangle + \lvert 1 1 \rangle \right)_{01} \otimes \frac{1}{\sqrt{2}} \left( \lvert 0 \rangle - \lvert 1 \rangle \right)_{2} \\ &amp; = \frac{1}{\sqrt{2}} \left( \lvert 0 \rangle - \lvert 1 \rangle \right)_{0} \otimes \frac{1 }{\sqrt{2}} \left( \lvert 0 \rangle - \lvert 1 \rangle \right)_{1} \otimes \frac{1}{\sqrt{2}} \left( \lvert 0 \ range - \lvert 1 \rangle \right)_{2} \end{aligned} $$   Appliquer Hadamard sur le premier registre$$ \lvert \psi_3\rangle = \lvert 1 \rangle_{0} \otimes \lvert 1 \rangle_{1} \otimes \left( \lvert 0 \rangle - \lvert 1 \rangle \right)_{2} $$      La mesure des deux premiers qubits donnera le $11$ non nul, indiquant une fonction équilibrée.Vous pouvez essayer des exemples similaires en utilisant le widget ci-dessous. Appuyez sur les boutons pour ajouter des portes H et des oracles, relancez la cellule et/ou définissez `case="constant"` pour essayer différents oracles.<jupyter_code>from qiskit_textbook.widgets import dj_widget
dj_widget(size="small", case="balanced")<jupyter_output><empty_output><jupyter_text>3. Création d'oracles quantiques Voyons différentes façons de créer un oracle quantique.Pour une fonction constante, c'est simple :$\qquad$ 1. si f(x) = 0, alors appliquez la porte $I$ au qubit dans le registre 2. $\qquad$ 2. si f(x) = 1, alors appliquez la porte $X$ au qubit dans le registre 2.Pour une fonction équilibrée, il existe de nombreux circuits différents que nous pouvons créer. L'une des façons dont nous pouvons garantir que notre circuit est équilibré consiste à effectuer un CNOT pour chaque qubit dans le registre 1, avec le qubit dans le registre 2 comme cible. Par exemple:![image2](images/deutsch_balanced1.svg)Dans l'image ci-dessus, les trois qubits supérieurs forment le registre d'entrée et le qubit inférieur est le registre de sortie. Nous pouvons voir quels états d'entrée donnent quelle sortie dans le tableau ci-dessous :L'entrée indique que la sortie 0 | États d'entrée qui produisent 1:-: | :-:000 | 001011 | 100101 | 010110 | 111Nous pouvons modifier les résultats tout en les gardant équilibrés en enveloppant les contrôles sélectionnés dans des X-gates. Voir par exemple le circuit et son tableau de résultats ci-dessous :![autre_circuit_équilibré](images/deutsch_balanced2.svg)L'entrée indique que la sortie 0 | L'entrée indique que la sortie 1:-: | :-:001 | 000010 | 011100 | 101111 | 110  4. Mise en œuvre de QiskitNous implémentons maintenant l'algorithme de Deutsch-Jozsa pour l'exemple d'une fonction à trois bits, avec des oracles constants et équilibrés. Faisons d'abord nos importations :<jupyter_code># initialization
import numpy as np

# importing Qiskit
from qiskit import IBMQ, Aer
from qiskit.providers.ibmq import least_busy
from qiskit import QuantumCircuit, transpile

# import basic plot tools
from qiskit.visualization import plot_histogram<jupyter_output><empty_output><jupyter_text>Ensuite, nous définissons la taille du registre d'entrée pour notre oracle :<jupyter_code># set the length of the n-bit input string. 
n = 3<jupyter_output><empty_output><jupyter_text>4.1 Oracle constantCommençons par créer un oracle constant, dans ce cas, l'entrée n'a aucun effet sur la sortie, nous définissons donc au hasard le qubit de sortie sur 0 ou 1 :<jupyter_code># set the length of the n-bit input string. 
n = 3

const_oracle = QuantumCircuit(n+1)

output = np.random.randint(2)
if output == 1:
    const_oracle.x(n)

const_oracle.draw()<jupyter_output><empty_output><jupyter_text>4.2 Oracle équilibré<jupyter_code>balanced_oracle = QuantumCircuit(n+1)<jupyter_output><empty_output><jupyter_text>Ensuite, nous créons un oracle équilibré. Comme nous l'avons vu dans la section 1b, nous pouvons créer un oracle équilibré en effectuant des CNOT avec chaque qubit d'entrée comme contrôle et le bit de sortie comme cible. Nous pouvons faire varier les états d'entrée qui donnent 0 ou 1 en enveloppant certaines des commandes dans des portes X. Choisissons d'abord une chaîne binaire de longueur `n` qui dicte les contrôles à envelopper :<jupyter_code>b_str = "101"<jupyter_output><empty_output><jupyter_text>Maintenant que nous avons cette chaîne, nous pouvons l'utiliser comme clé pour placer nos X-gates. Pour chaque qubit de notre circuit, nous plaçons une porte X si le chiffre correspondant dans `b_str` est `1` , ou ne faisons rien si le chiffre est `0` .<jupyter_code>balanced_oracle = QuantumCircuit(n+1)
b_str = "101"

# Place X-gates
for qubit in range(len(b_str)):
    if b_str[qubit] == '1':
        balanced_oracle.x(qubit)
balanced_oracle.draw()<jupyter_output><empty_output><jupyter_text>Ensuite, nous faisons nos portes NON contrôlées, en utilisant chaque qubit d'entrée comme contrôle et le qubit de sortie comme cible :<jupyter_code>balanced_oracle = QuantumCircuit(n+1)
b_str = "101"

# Place X-gates
for qubit in range(len(b_str)):
    if b_str[qubit] == '1':
        balanced_oracle.x(qubit)

# Use barrier as divider
balanced_oracle.barrier()

# Controlled-NOT gates
for qubit in range(n):
    balanced_oracle.cx(qubit, n)

balanced_oracle.barrier()
balanced_oracle.draw()<jupyter_output><empty_output><jupyter_text>Enfin, nous répétons le code à partir de deux cellules jusqu'à finir d'envelopper les contrôles dans les X-gates :<jupyter_code>balanced_oracle = QuantumCircuit(n+1)
b_str = "101"

# Place X-gates
for qubit in range(len(b_str)):
    if b_str[qubit] == '1':
        balanced_oracle.x(qubit)

# Use barrier as divider
balanced_oracle.barrier()

# Controlled-NOT gates
for qubit in range(n):
    balanced_oracle.cx(qubit, n)

balanced_oracle.barrier()

# Place X-gates
for qubit in range(len(b_str)):
    if b_str[qubit] == '1':
        balanced_oracle.x(qubit)

# Show oracle
balanced_oracle.draw()<jupyter_output><empty_output><jupyter_text>Nous venons de créer un oracle équilibré ! Il ne reste plus qu'à voir si l'algorithme de Deutsch-Jozsa peut le résoudre. 4.3 L'algorithme completMettons maintenant tout ensemble. Cette première étape de l'algorithme consiste à initialiser les qubits d'entrée dans l'état $|{+}\rangle$ et le qubit de sortie dans l'état $|{-}\rangle$ :<jupyter_code>dj_circuit = QuantumCircuit(n+1, n)

# Apply H-gates
for qubit in range(n):
    dj_circuit.h(qubit)

# Put qubit in state |->
dj_circuit.x(n)
dj_circuit.h(n)
dj_circuit.draw()<jupyter_output><empty_output><jupyter_text>Ensuite, appliquons l'oracle. Ici, nous appliquons le `balanced_oracle` que nous avons créé ci-dessus :<jupyter_code>dj_circuit = QuantumCircuit(n+1, n)

# Apply H-gates
for qubit in range(n):
    dj_circuit.h(qubit)

# Put qubit in state |->
dj_circuit.x(n)
dj_circuit.h(n)

# Add oracle
dj_circuit = dj_circuit.compose(balanced_oracle)
dj_circuit.draw()<jupyter_output><empty_output><jupyter_text>Enfin, nous effectuons des portes H sur les qubits d'entrée $n$ et mesurons notre registre d'entrée :<jupyter_code>dj_circuit = QuantumCircuit(n+1, n)

# Apply H-gates
for qubit in range(n):
    dj_circuit.h(qubit)

# Put qubit in state |->
dj_circuit.x(n)
dj_circuit.h(n)

# Add oracle
dj_circuit = dj_circuit.compose(balanced_oracle)

# Repeat H-gates
for qubit in range(n):
    dj_circuit.h(qubit)
dj_circuit.barrier()

# Measure
for i in range(n):
    dj_circuit.measure(i, i)

# Display circuit
dj_circuit.draw()<jupyter_output><empty_output><jupyter_text>Voyons la sortie :<jupyter_code># use local simulator
aer_sim = Aer.get_backend('aer_simulator')
results = aer_sim.run(dj_circuit).result()
answer = results.get_counts()

plot_histogram(answer)<jupyter_output><empty_output><jupyter_text>Nous pouvons voir d'après les résultats ci-dessus que nous avons 0% de chance de mesurer `000` . Cela prédit correctement que la fonction est équilibrée. 4.4 Circuits généralisésCi-dessous, nous fournissons une fonction généralisée qui crée des oracles Deutsch-Jozsa et les transforme en portes quantiques. Il prend le `case` , (soit `'balanced'` ou ' `constant` ', et `n` , la taille du registre d'entrée :<jupyter_code>def dj_oracle(case, n):
    # We need to make a QuantumCircuit object to return
    # This circuit has n+1 qubits: the size of the input,
    # plus one output qubit
    oracle_qc = QuantumCircuit(n+1)
    
    # First, let's deal with the case in which oracle is balanced
    if case == "balanced":
        # First generate a random number that tells us which CNOTs to
        # wrap in X-gates:
        b = np.random.randint(1,2**n)
        # Next, format 'b' as a binary string of length 'n', padded with zeros:
        b_str = format(b, '0'+str(n)+'b')
        # Next, we place the first X-gates. Each digit in our binary string 
        # corresponds to a qubit, if the digit is 0, we do nothing, if it's 1
        # we apply an X-gate to that qubit:
        for qubit in range(len(b_str)):
            if b_str[qubit] == '1':
                oracle_qc.x(qubit)
        # Do the controlled-NOT gates for each qubit, using the output qubit 
        # as the target:
        for qubit in range(n):
            oracle_qc.cx(qubit, n)
        # Next, place the final X-gates
        for qubit in range(len(b_str)):
            if b_str[qubit] == '1':
                oracle_qc.x(qubit)

    # Case in which oracle is constant
    if case == "constant":
        # First decide what the fixed output of the oracle will be
        # (either always 0 or always 1)
        output = np.random.randint(2)
        if output == 1:
            oracle_qc.x(n)
    
    oracle_gate = oracle_qc.to_gate()
    oracle_gate.name = "Oracle" # To show when we display the circuit
    return oracle_gate<jupyter_output><empty_output><jupyter_text>Créons également une fonction qui prend cette porte oracle et exécute l'algorithme Deutsch-Jozsa dessus :<jupyter_code>def dj_algorithm(oracle, n):
    dj_circuit = QuantumCircuit(n+1, n)
    # Set up the output qubit:
    dj_circuit.x(n)
    dj_circuit.h(n)
    # And set up the input register:
    for qubit in range(n):
        dj_circuit.h(qubit)
    # Let's append the oracle gate to our circuit:
    dj_circuit.append(oracle, range(n+1))
    # Finally, perform the H-gates again and measure:
    for qubit in range(n):
        dj_circuit.h(qubit)
    
    for i in range(n):
        dj_circuit.measure(i, i)
    
    return dj_circuit<jupyter_output><empty_output><jupyter_text>Enfin, utilisons ces fonctions pour jouer avec l'algorithme :<jupyter_code>n = 4
oracle_gate = dj_oracle('balanced', n)
dj_circuit = dj_algorithm(oracle_gate, n)
dj_circuit.draw()<jupyter_output><empty_output><jupyter_text>Et voyez les résultats de l'exécution de ce circuit :<jupyter_code>transpiled_dj_circuit = transpile(dj_circuit, aer_sim)
results = aer_sim.run(transpiled_dj_circuit).result()
answer = results.get_counts()
plot_histogram(answer)<jupyter_output><empty_output><jupyter_text>5. Expérimentez avec de vrais appareilsNous pouvons exécuter le circuit sur l'appareil réel comme indiqué ci-dessous. Nous recherchons d'abord l'appareil le moins occupé qui peut gérer notre circuit.<jupyter_code># Load our saved IBMQ accounts and get the least busy backend device with greater than or equal to (n+1) qubits
IBMQ.load_account()
provider = IBMQ.get_provider(hub='ibm-q')
backend = least_busy(provider.backends(filters=lambda x: x.configuration().n_qubits >= (n+1) and
                                   not x.configuration().simulator and x.status().operational==True))
print("least busy backend: ", backend)
# Run our circuit on the least busy backend. Monitor the execution of the job in the queue
from qiskit.tools.monitor import job_monitor

transpiled_dj_circuit = transpile(dj_circuit, backend, optimization_level=3)
job = backend.run(transpiled_dj_circuit)
job_monitor(job, interval=2)
# Get the results of the computation
results = job.result()
answer = results.get_counts()

plot_histogram(answer)<jupyter_output><empty_output><jupyter_text>Comme nous pouvons le voir, le résultat le plus probable est `1111` . Les autres résultats sont dus à des erreurs dans le calcul quantique.   6. Problèmes1. Êtes-vous capable de créer un oracle équilibré ou constant d'une forme différente ?2. La fonction `dj_problem_oracle` (ci-dessous) renvoie un oracle Deutsch-Jozsa pour `n = 4` sous la forme d'une porte. La porte prend 5 qubits en entrée où le qubit final ( `q_4` ) est le qubit de sortie (comme avec l'exemple d'oracles ci-dessus). Vous pouvez obtenir différents oracles en donnant à `dj_problem_oracle` différents entiers entre 1 et 5. Utilisez l'algorithme Deutsch-Jozsa pour décider si chaque oracle est équilibré ou constant ( **Remarque :** il est fortement recommandé d'essayer cet exemple en utilisant `aer_simulator` au lieu d'un appareil réel) .<jupyter_code>from qiskit_textbook.problems import dj_problem_oracle
oracle = dj_problem_oracle(1)<jupyter_output><empty_output><jupyter_text>7. Références1. <NAME> et <NAME> (1992). « Solutions rapides de problèmes par calcul quantique ». Actes de la Royal Society of London A. 439 : 553–558. [doi:10.1098/rspa.1992.0167](https://doi.org/10.1098%2Frspa.1992.0167) .2. <NAME>; A.Ekert; <NAME>; <NAME> (1998). "Algorithmes quantiques revisités". Actes de la Royal Society of London A. 454 : 339–354. [doi:10.1098/rspa.1998.0164](https://doi.org/10.1098%2Frspa.1998.0164) .<jupyter_code>import qiskit.tools.jupyter
%qiskit_version_table<jupyter_output>/usr/local/anaconda3/envs/terra-unstable/lib/python3.9/site-packages/qiskit/aqua/__init__.py:86: DeprecationWarning: The package qiskit.aqua is deprecated. It was moved/refactored to qiskit-terra For more information see <https://github.com/Qiskit/qiskit-aqua/blob/main/README.md#migration-guide>
  warn_package('aqua', 'qiskit-terra')
{'fraction_non_alphanumeric': 0.11242055084745763, 'fraction_numerical': 0.026483050847457626, 'mean_word_length': 4.253188036169719, 'pattern_counts': {'":': 2, '<': 86, '<?xml version=': 0, '>': 90, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '20', 'dir': 'jupyter-structured-clean-dedup', 'id': '368090', 'license': 'Apache-2.0', 'n_tokens_mistral': 8571, 'n_tokens_neox': 7946, 'n_words': 2743, 'path': 'fr/notebooks/ch-algorithms/deutsch-jozsa.ipynb', 'repo_name': 'TanyaJazzTeam/platypus', 'size': '22681'}