ALGORITMO GENÉTICO
Los algoritmos genéticos son métodos sistemáticos para la resolución de problemas de
búsqueda y optimización que aplican a éstos los principios de la evolución biológica: selección
basada en la población, reproducción sexual y mutación.
Los algoritmos genéticos son métodos de optimización, que tratan de resolver el conjunto de
problemas formulados como: hallar (x_1,…, x_n) tales que F(x_1,…, x_n) sea máximo. En un
algoritmo genético, tras parametrizar el problema en una serie de variables (x_1,…, x_n), se
codifican en un cromosoma. Todos los operadores utilizados por un algoritmo genético se
aplicarán sobre estos cromosomas, o sobre poblaciones de ellos. En el algoritmo genético va
implícito el método para resolver el problema; son sólo parámetros de tal método los que
están codificados - a diferencia de otros algoritmos evolutivos como la programación genética.
Las soluciones codificadas en un cromosoma compiten para ver cuál constituye la mejor
solución (aunque no necesariamente la mejor de todas las soluciones posibles). El ambiente,
constituido por las otras camaradas soluciones, ejercerá una presión selectiva sobre la
población, de forma que sólo los mejor adaptados (aquellos que resuelvan mejor el problema)
sobrevivan o leguen su material genético a las siguientes generaciones, igual que en la
evolución de las especies. La diversidad genética se introduce mediante mutaciones y
reproducción sexual. En la Naturaleza lo único que hay que optimizar es la supervivencia, y eso
significa a su vez maximizar diversos factores y minimizar otros. Un algoritmo genético, sin
embargo, se usará habitualmente para optimizar sólo una función, no diversas funciones
relacionadas entre sí simultáneamente. Este tipo de optimización, denominada optimización
multimodal, también se suele abordar con un algoritmo genético especializado.
Algoritmo genético estándar y variaciones
Existen muchas variaciones del algoritmo genético original \cite[Holland, 1975]{Holland75}.
Los genes no tienen por qué ser bits, también pueden ser números, por ejemplo. El operador
de inversión rara vez se usa hoy en día \cite[Mitchell M., 1996]{Mitchell96}. Algunas modifican
el operador de cruce o crossover de forma que preduzca cruces entre individuos con fitness
similares para obtener búsquedas más locales. Otros directamente implementan nuevos
operadores como la recombinación (cambiar la posición de los genes en un mismo individuo).
En general, no hay una definición universal de algoritmo genético que especifique los
operadores concretos que debe tener.
También existen diferencias en la forma de gestionar los individuos de la población. No sólo en
el número de individuos de ésta. Algunos algoritmos compartimentalizan poblaciones
separadas denominadas islas, que no pueden cuzarse entre sí o lo hacen de forma más
restringida. El algoritmo genético original adoptaba la política de reemplazo generacional, con
el que la población completa es reemplazada en cada generación. En cambio, la política de
estado estacionario, adoptada por varios algoritmos genéticos posteriores, reemplaza la
población selectivamente. Es posible mantener un miembro de la población sin modificarlo por
varias generaciones, siempre que estos mantengan un fiteness que esté por encima de otros
individuos de la población. Esta es la aproximación de GENITOR \cite[Whitley,
1989]{Whitley89}, que combina el estado estacionario con una selección por ranking. Incluso
existen aproximaciones en que los genes bloques de genes que no conforman un indidividuo
completo reciben un fitness y compiten como otra población por ser usados por los individuos
de la población de individuos \cite[Mitchell A. and De Jong, 2000]{Mitchell2000}.
Fortalezas y deficiencias
Un algoritmo genético es independiente del problema, lo cual lo hace un algoritmo robusto,
por ser útil para cualquier problema, pero a la vez débil, pues no está especializado en
ninguno. Hay que elegir la codificación de los cromosomas para cada caso concreto. Esto
puede requerir cierto grado de conocimiento acerca del dominio de aplicación concreto a la
hora de definir esta codificación.
Sin embargo, con nuestro método siempre códificaremos los cromosomas de manera similar
(con una red neuronal) y sólo será necesario definir la función de fitness usando las entradas y
las salidas de una red nueronal y elegir su topología (una librería suficientemente flexible
constituye una herramienta ideal para tratar de automatizar este último proceso). Aunque la
codificación de las entradas pueda admitir varias posibilidades (y algunas puedan ser más
ventajosas que otras) la red debe aprender a interpretar las correctas relaciones entre
entradas y salidas por sí misma. Así, podemos aprovechar el hecho de que las redes
neuronales son aproximadores universales de funciones para ahorrarnos el esfuerzo de
analizar cada problema por separado y en detalle.
Neuro-evolución
La evolución se ha aplicado las redes neuronales artificiales en tres niveles muy diferentes: a
los pesos de las conexiones, la arquitectura de la red y a las reglas de aprendizaje. La evolución
de los pesos de las conexiones introduce una aproximación global y adaptable al
entrenamiento, especialmente para el aprendizaje por refuerzo o para el entrenamiento de
redes recursivas, donde los métodos basados en el gradiente experimentan grandes
dificultades. La evolución de las arquitecturas permite a las redes neuronales adaptar su
topología a diferentes problemas sin intervención humana y con esto se consigue un diseño
automático de redes neuronales, dado que tanto la arquitectura como los pesos pueden ser
evolucionados. La evolución de las reglas de aprendizaje puede ser considerada como un
proceso de “aprender a aprender” en redes neuronales que luego aprenderan de forma
autónoma utilizando esas reglas. Puede ser contemplada como un proceso de descubrimiento
automático de nuevas reglas de aprendizaje.
Nos centraremos en la evolución de los pesos de las conexiones, por ser la evolución que
utilizaremos. Pero comentaremos algunas aproximaciones en el campo de la evolución de las
topologías, para el que la librería implementada puede ser de utilidad.
La evolución de los pesos de las conexiones se puede realizar en el aprendizaje supervisado
(con ejemplos) definiendo la función de fitness como el error global obtenido por la red
(invirtiendo el signo), comparando las salidas de la red y la salida deseada para cada ejemplo.
También se puede utilizar para el aprendizaje por refuerzo definiendo con una función de
fitness (un problema) que no requiera ejemplos.
En general, los pasos a seguir son dos: decidir la codificación de los pesos de las conexiones (si
se hará mediante cadenas binarias o no) y la ejecución del algoritmo genético propiamente
dicho. Para el primer paso, las opciones más extendidas son la representación binaria y la
representación con números reales.
El algoritmo genético canónico siempre usa cadenas de bits para codificar las diferentes
soluciones. Por ello, algunos trabajos tempranos de evolución de los pesos de las conexiones
siguen esta aproximación \cite[Yao99]{Yao99}. Las ventajas son la fácil aplicación de los
operadores genéticos y su posible implementación digital. Habría que elegir la representación
de los números reales. Aquí hay un compromiso para la precisión con que se quieran
representar los números reales. Si se usan muy pocos bits para representar cada conexión, el
entrenamiento puede fallar porque algunas combinaciones de pesos no se pueden aproximar
con suficiente precisión por valores discretos. Por otra parte, si se usan demasiados bits, los
cromosomas que representen a redes neuronales grandes se volverán demasiado largos y la
evolución en proceso resultará muy ineficiente.
Especificaciones de la librería a implementar
se pretende construir una librería de programación para el lenguaje C++ en un entorno
GNU/Linux que permita el entrenamiento de redes neuronales utilizando algoritmos genéticos.
La librería tendrá una licencia de software libre, en concreto, la GPLv3.
Se quiere que sea lo más flexible posible en cuanto a la estructura de la red, para poder, en un
futuro, determinar la topología también de forma genética. Como los entrenamientos pueden
ser costosos en tiempo de ejecución, la librería debe estar paralelizada internamente al menos
para la ejecución de redes neuronales. Esta paralelización debe poder aprovecharse por los
sistemas más extendidos para que pueda ser utilizada en proyectos que aprovechen la
computación voluntaria. El compromiso entre flexibilidad y rendimiento computacional
obedece a las siguientes exigencias:
El bloque de construcción básico de redes serán capas de neuronas que comparten las mismas
conexiones de entrada y las optimizaciones paralelizadas podrán aprovechar la paralelización
de los datos a este nivel.
Una capa puede tomar como entrada cualquier número de capas, estableciendo una conexión
con cada una. Deben ser posibles conexiones recurrentes y una capa debe incluso poder tomar
su propia salida como entrada.
Debe existir un enumerado o entidad tipo de implementación. No debe existir acoplamiento
entre la interfaz externa de la librería y las implementaciones optizadas. Incluir una nueva
implementación optimizada debe poder ser suficientemente simple. Se implementarán al
menos dos optimizaciones diferentes para garantizar esto. Ambas optimizaciones deben
superar en rendimento a la implementación no optimizada de referencia descrita en el punto
siguiente.
La librería debe incorporar una implementación no optimizada de referencia con la que
comparar el resto de tipos de implementación para comprobar la corrección de sus cálculos.
También debe incorporar herramientas para que esta comprobación pueda hacerse de forma
automática.
Se desecha la representación binaria de los genes en favor de usar números. Sin embargo,
estos números no tienen por qué ser siempre floats, si no que podrían ser de otros tipos más
grandes (double) o incluso números enteros y con rangos más pequeños (short, byte) para
aproximaciones más cercanas a la lógica difusa. Aunque no se implementen todos los ”tipos de
pesos”, la arquitectura debe ser tal que la librería pueda extenderse fácilmente para
incorporar un nuevo tipo. Sin embargo, cada implementación optimizada puede requerir un
tratamiento especial para el nuevo tipo o directamente no soportarlo.
Cada capa de poder utilizar una función de activación diferente. Se define un tipo de
activación.
Para poder explorar las posibilidades de incremento de rendimiento para funciones de
activación concretas, En lugar de definirse un ”tipo de pesos” para el punto 5, se define un tipo
de neurona, en el que va implicito el tipo de peso y puede ir o no también implicito el tipo de
activación. Es decir, un tipo de neurona en la capa de entrada tiene siempre un tipo de peso
asociado, pero ese tipo de neuronas puede soportar sólo un tipo de activación (o un
subbconjunto de todas las definidas a partir del punto anterior).
Una capa puede conectarse con capas cuyo tipo de neurona es diferente al suyo. Incluso debe
poder tomar como entrada varias capas con tipos de neurona diferentes. Cuando un tipo de
implementación no soporte conexiones entre un par de tipos de neurona concretos, debe
lanzarse una excepción en el mismo momento en que se trata de crear dicha conexión, no
cuando se vaya a activar.
Las capas no tienen que ser compatibles con otras capas de diferente tipo de implementación,
sin embargo, las entradas y salidas de una red neuronal completa deben ser accedidas y
manipuladas de forma completamente transparente con respecto al tipo de implementación.
Las diferentes implementaciones de las capas deben implementar también la gestión genética
de los pesos y umbrales, pero se debe definir una interfaz lo suficientemente genérica para
que puedan implementarse distintos esquemas de cruza y mutación sin que estos tengan que
ser implementados una vez por cada tipo de implementación. Por tanto los diferentes tipos de
operadores genéticos definidos en el punto 14 no deben ser necesarios desde la
implementación de la capa.
Una red neuronal debe poder incorporar nuevas capas y conexiones una vez creada, incluso en
medio de un entrenamiento.
La entidad que se ocupa de la evolución es la población, que contiene una lista ordenada de
individuos, que a su vez contienen una red neuronal completa.
La población debe poder ser gestionada de forma generacional o con el estado estacionario
mencionado en la sección \ref{basTeoGenetEstan}.
Para garantizar cierta flexibilidad en el algoritmo genético se definen varios enumerados con el
fin de poder variar y extender los diferentes aspectos del algoritmos genético. Se debe
implementar más de una opción para cada uno de los tipos listados a continuación:
Tipo de selección: determina los individuos que serán utilizados para generar nuevos
genotipos.
Tipo de cruce: determina qué genes de los padres serán utilizados para generar un nuevo
individuo.
Nivel de cruce: determina qué partes del genotipo representan una unidad indivisible (un gen)
para el cruce.
Tipo de mutación: determina qué individuos cambiarán sus genes aleatoriamente y cómo.
Todas las combinaciones de los enumerados descritos en el punto anterior deben ser
permitidas. Se debe permitir también que la población combine varios esquemas del mismo
tipo simultáneamente.
Las poblaciones evolucionan a sus individuos para realizar una determinada tarea. La tarea
toma a un individuo y puede presentarle cualquier número de entradas y activar la red para
tomar las salidas cualquier número de veces y en cualquier orden (esto puede influir en las
salidas si hay conexiones recurrentes) dependiendo de las características concretas del
problema a optimizar y al final debe evaluar al individuo estableciendo el valor del campo
fitness de la entidad individuo, que será un número real cuanto más positivo mejor.
La población debe tratar a todas las tareas de forma similar para que crear nuevas tareas sea
una tarea relativamente sencilla. Por supuesto, sencilla sin tener en cuenta las complejidades
que cada función de fitness pueda requerir. La clase tarea debe ser una interfaz para la clase
población, pero con un comportamiento interno configurable y extensible. Para la
implementación de la población nunca debe ser necesario el tipo de tarea para la que se está
evolucionando.
Se implementarán varias tareas de clasificación para ser aprendidas por las redes utilizando
entrañamiento supervisado.
Se implementará un juego de estrategia como ejemplo de tarea con aprendizaje por refuerzo
para ser aprendida por las redes.
La librería debe incorporar herramientas para la exploración gráfica de los resultados. Se
deben poder generar gráficas de rendimiento computacional y de la evolución del fitness de
una población.
Diseño general
Como se definió en la sección \ref{anaEspecLib}, la librería debe poder construir redes
neuronales de cualquier topología y, al mismo tiempo, debe poder ser paralelizada usando
diferentes tecnologías. Además, en la sección \ref{anaObjetivos} establecimos que las
neuronas pueden ser de varios tipos (binarias, bipolares y reales).
Para soportar las diferentes implementaciones y tipos de neuronas sin incrementar la
complejidad de la API de la librería, se definirán clases abstractas como interfaces de las que
luego heredarán las diferentes implementaciones. Para independizar completamente el
manejo de estas clases de fachada, las implementaciones concretas sólo serán visibles a una
clase factoría que será el único método para instanciar las implementaciones siguiendo el
patrón de diseño de factoría abstracta \cite{gof94}. Para las diferentes implementaciones
paralelas descritas en el capítulo \ref{disenoParal}, se crearán diferentes clases que extiendan
de las fachadas. Para soportar los diferentes tipos de neuronas, estas clases paralelizadas se
implementarán usando plantillas. Sólo serán utilizadas directamente las clases fachada y los
métodos específicos de cada implementación concreta serán llamados utilizando la técnica
que en el contexto de análisis, diseño y desarrollo orientado a objetos se denomina
polimorfismo.
Primero se describirán las clases fachada y el resto de clases utilizadas para la implementación
de las redes neuronales en la sección \ref{disenoRedes}. Las implementaciones concretas de
las fachadas para la factoría se describirán con más detalle en la sección \ref{disenoFactoria}.
https://github.com/jtimon/preann/blob/master/doc/pfc-jorge-timon.org
Algoritmo de Deutsch-Jozsa(1992)
Sea el conjunto de valores de verdad clásicos. De
las funciones booleanas dos son constantes y las otras dos
son equilibradas. Al nombrarlas
se tiene que las funciones constantes son y , y las equilibradas son y .
El propósito del algoritmo de Deutsch-Jozsa es decidir, para una dada, si acaso es constante
o equilibrada ``utilizando un solo paso de cómputo''.
Sea una matriz permutación de orden tal
que . es pues unitaria. De hecho es muy similar
al funcionamiento de la compuerta ``negación controlada'', salvo que en aquella, la
función es propiamente la identidad. En la tabla 1 ilustramos la acción de refiriéndonos
solamente a los índices de vectores básicos.
Acción de la matriz unitaria en el algoritmo de Deutsch-Jozsa.
(0,0)
(0, )
(0,1)
(0, )
(1,0)
(1, )
(1,1)
(1, )
Considerando el operador de Hadamard , hagamos . Primero se
tiene, y y
luego .
Claramente, Por tanto,
En consecuencia
vale decir, al aplicar el algoritmo cuántico (nótese que utilizamos
notación algebraica: los operadores se aplican de derecha a izquierda),
partiendo del vector básico se obtiene un vector de la
forma donde es un signo y es una señal que indica si
acaso es o no equilibrada. En otras palabras, la respuesta coincide
con , donde es la disyunción excluyente, XOR. La auscultación
del valor se realiza siguiendo el postulado de medición, y su valor está
apareciendo leyendo sólo el primer qubit. Al efectuar la medición se elige al
vector básico con probabilidad .
http://delta.cs.cinvestav.mx/~gmorales/quantum/node10.html
Algoritmo Chiara Macchiavello(1998)
Un algoritmo cuántico es un algoritmo que se ejecuta en un modelo realista de computación
cuántica, como el modelo de circuito cuántico, como el que se ilustra en la figura.[1] La teoría
de la complejidad computacional le asigna la clase BQP a los algoritmos que pueden ser
resueltos en un computador cuántico en tiempo polinómico con un margen de error promedio
inferior a 1/4. En el análisis de los algoritmos cuánticos es habitual comparar la cota superior
asintótica con el mejor algoritmo clásico conocido, o, si el problema está resuelto, con el mejor
algoritmo clásico posible. Se usa la notación de Landau para definir la relación entre la talla de
la entrada del problema y el número de pasos necesarios para resolverlo, o el número de
posiciones de memoria que se utilizan durante su resolución.
El algoritmo de Deutsch-Jozsa fue propuesto por David Deutsch y Richard Jozsa en 1992[2] y
fue mejorado posteriormente por Richard Cleve, Artur Ekert, Chiara Macchiavello, y Michele
Mosca en 1998.[3] Su función es determinar si una función de tipo caja negra {\displaystyle
f:\{0,1\}^{n}\rightarrow \{0,1\)) es «constante» o «balanceada». Esto es, dada una función que
para una entrada de n bits da un solo bit de salida, determinar si la salida es independiente de
la entrada o si para la mitad de las entradas es 0 y para la otra mitad es 1. El planteamiento del
problema excluye todas las otras posibles funciones. El algoritmo no tiene apenas utilidad
práctica, pero es uno de los primeros ejemplos de un algoritmo cuántico que se ha
demostrado que es exponencialmente más rápido que cualquier posible algoritmo clásico
determinista.
El algoritmo de Shor, propuesto por Peter Shor en 1995 y relacionado con la aritmética
modular, descompone en factores un número N en tiempo {\displaystyle {\mathcal {O))(\log
N)^{3)) y espacio {\displaystyle {\mathcal {O))(\log N)}.[4] Es responsable de buena parte de la
atención que se le ha dedicado a la computación cuántica, por su relación con el problema RSA
de importancia fundamental en criptografía.
El algoritmo de Grover, publicado por Lov Grover en 1996,[5] demostró que un problema de
utilidad práctica podía ser resuelto más rápidamente que el mejor algoritmo clásico posible. El
algoritmo realiza una búsqueda en una base de datos desordenada con N entradas en un
número de pasos de orden {\displaystyle {\mathcal {O))({\sqrt {N)))}, consumiendo un espacio
de memoria de orden {\displaystyle {\mathcal {O))(\log N)}.
El desarrollo de la primera corrección de errores cuántica, propuesta también por Peter Shor
en 1995,[6] fue el primer paso hacia la computación cuántica a prueba de errores. Supuso un
avance significativo porque por las leyes mecánica cuántica no es posible usar las estrategias
habituales para la detección y corrección de errores de la computación clásica.
https://www.wikiwand.com/es/Algoritmo_cu%C3%A1ntico
algoritmo cuántico
transformada cuántica de Fourier
En computación cuántica, la transformada cuántica de Fourier es una transformación sobre
bits cuánticos, y es la analogía cuántica de la transformada de Fourier discreta. La
transformada de Fourier es una parte de muchos algoritmos cuánticos, el algoritmo de
factorización de Shor y el cálculo del logaritmo discreto, el algoritmo de estimación de fase
para estimar los eigenvalores de un operador unitario, y logaritmos para HSP (hidden subgroup
problem).
La transformada de Fourier puede ser realizada eficientemente en un ordenador cuántico, con
una particular descomposición en un producto de matrices unitarias simples. Usando una
descomposición simple, la trasformación discreta de Fourier puede ser implementada como un
circuito cuántico que tiene solo {\displaystyle O(n^{2})}O(n^2) puertas Hadamard y puertas de
desplazamiento de fase controladas, donde {\displaystyle n}n es el número de qubits.1 Esto
puede ser comparado con la transformada de Fourier discreta, que utiliza {\displaystyle
O(n2^{n})}{\displaystyle O(n2^{n})} puertas (donde {\displaystyle n}n es el número de bits), lo
cual es exponencialmente mejor que {\displaystyle O(n^{2})}O(n^2). Sin embargo, la
transformada cuántica de Fourier actúa sobre un estado cuántico, mientras que la trasformada
de Fourier clásica actúa sobre un vector, así que no todas las tareas que usan la transformada
de Fourier clásica pueden utilizar la ventaja de esta aceleración exponencial.
Los mejores algoritmos cuánticos de transformada de Fourier conocidos actualmente
requieren solo {\displaystyle O(n\log n)}{\displaystyle O(n\log n)} puertas para alcanzar una
aproximación eficiente.
La transformada de Fourier cuántica es la transformada de Fourier discreta clásica
aplicada al vector de amplitudes de un estado cuántico. La transformada de Fourier clásica
(unitaria) actúa sobre un vector en , (x0,..., xN−1) y lo mapea al vector (y0,..., yN−1) de
acuerdo con la fórmula:
Donde es una raíz de la unidad Nth primitiva.
De forma similar, la transformada cuántica de Fourier actúa sobre un estado cuántico y lo
mapea a un estado cuántico de acuerdo con la fórmula:
Esto puede ser expresado como la aplicación
De forma equivalente, la transformada de Fourier cuántica puede ser vista como una
matriz unitaria actuando sobre vectores estado cuántico, donde la matriz unitaria está
dada por
Propiedades
Unitaria
Muchas de las propiedades de la transformada de Fourier surgen del hecho de que es una
transformación unitaria. Esto puede ser comprobado realizando la multiplicación de matrices y
verificando la relación
Alternativamente, podemos comprobar que los vectores de norma 1 son transformados a su
vez en vectores de norma 1.
De las propiedades unitarias surge que la inversa de la transformada cuántica de Fourier es la
hermítica adjunta de la matriz de Fourier, así Existe un circuito cuántico eficiente
que implementa la transformada inversa cuántica de Fourier. Así que ambas transformaciones
pueden ser realizadas en un ordenador cuántico.
Ejemplo
https://es.wikipedia.org/wiki/Transformada_cu%C3%A1ntica_de_Fourier
puerta cuántica
Una puerta cuántica o puerta lógica cuántica es un circuito cuántico básico que opera sobre un
pequeño número de qubits. Son para los ordenadores cuánticos lo que las puertas lógicas son
para los ordenadores digitales. Las puertas lógicas cuánticas son reversibles, al contrario que
muchas puertas lógicas clásicas. Algunas puertas lógicas clásicas, como la puerta de Toffoli,
proporcionan reversibilidad y pueden ser transformadas en puertas lógicas cuánticas. Las
puertas lógicas cuánticas son representadas mediante matrices unitarias.
Las puertas cuánticas más comunes operan en espacios de uno o dos qubits. Esto significa que,
como matrices, las puertas cuánticas pueden ser descritas por matrices 2×2 o 4×4 con filas
ortonormales.
Lógica cuántica puede referirse tanto al comportamiento de las puertas lógicas cuánticas como
al formalismo para mecánica cuántica llamado lógica cuántica, basado en la modificación de
algunas de las reglas de la lógica proposicional.
Puerta de Hadamard
Esta compuerta es fundamental y su importancia es comparable al de una compuerta AND en
un circuito clásico. Opera sobre un solo qubit o dos qubits. Se denota con el símbolo H cuando
opera sobre un solo qubit.
Funciona de la siguiente forma si en la entrada se tiene un 0 ,la compuerta da como resultado:
H (0) = ⅟√2 |0〉 + ⅟√2 |1〉
Y para la entrada 1 :
H (1) = ⅟√2 |0〉 - ⅟√2 |1〉
Funcionamiento de una compuerta Hadamard
Aplicación de la compuerta Hadamard
Otras puertas son la “negación” (N), “cambio de fase” (Z) y la “negación con cambio de fase”
(Y), que se ilustran a continuación .
Las matrices de las compuertas Negación (N), Negación con cambio de fase por un coeficiente
imaginario negativo -iY y cambio de fase (Z), se conocen con el nombre de matrices de Pauli las
cuales se representan por la letra griega sigma ( σ ), las cuales son:
Matrices de Pauli
dentro de este conjunto también se considera a la matriz identidad algunas veces nombrada
como matriz cero pauli σ0.
CNOT
Esta compuerta opera sobre dos qubits, con el primero actuando como un qubit de control y el
segundo como el qubit sobre el que se realiza la operación, similar a un transistor de
conmutación. La puerta CNOT invierte el valor del segundo bit si y solo si el primer qubit es un
1. De esta forma, tenemos que :
CNOT (|00〉) =|00〉 : CNOT (|01〉) =|01〉
y
CNOT (|10〉) =|11〉 : CNOT (|11〉) =|10〉
funcionamiento de una compuerta CNOT
Nos podemos dar cuenta que el funcionamiento de la compuerta CNOT es muy similar al de
una compuerta XOR de la computación clásica, con la diferencia de que la puerta CNOT genera
dos salidas en lugar de una.
Similitud entre compuertas
Las matrices que realizan transformaciones unitarias en sistemas de dos qubits deben ser
matrices de dimensión 4x4.Tomando en cuenta que:
Representación vectorial de un 2-qubit.
Definicion de la compuerta CNOT
Aplicación de la compuerta CNOT
Estas compuertas son las básicas dentro de la computación cuántica, aunque existen aún mas
compuertas con estas es posible realizar múltiples tipos de operaciones al combinarlas , como
por ejemplo la CNOT con la Hadamard , nos permite invertir el qubit de control :
https://medium.com/@josueacevedo/computaci%C3%B3n-cu%C3%A1ntica-compuertas-o-
circuitos-cu%C3%A1nticos-27910f5338c8
Algoritmo del temple cuántico
El algoritmo del temple cuántico (en inglés, quantum annealing), también llamado aleación,
cristalización o recocido, es análogo al temple simulado pero sustituyendo la activación
térmica por el efecto túnel.
QA es una clase algorítmica parecida al temple simulado (“Simulated Annealing” o 'SA' de
Kirkpatrick y otros) que consiste en una adaptación del algoritmo clásico de Metropolis-
Hastings. Sin embargo, QA emplea un campo cuántico en lugar de un gradiente térmico. Para
explorar el paisaje del problema de optimización, SA y sus variantes (como el Temple Paralelo)
aprovechan las fluctuaciones “térmicas” correspondientes a gradientes de temperatura,
mientras que QA utiliza para ello fluctuaciones “cuánticas”. Una fluctuación cuántica es un
cambio en la cantidad de energía de un punto del espacio durante brevísimos lapsos de
tiempo, como resultado del principio de incertidumbre enunciado por Heisemberg.
En cierto modo, los métodos de temple, cristalización o 'annealing' son una metáfora de la
naturaleza que trata de imitar la forma en que se ordenan las moléculas de un metal al
magnetizarse, o de un cristal durante la transición de fase, que ocurre por ejemplo, al enfriarse
el agua o el dióxido de silicio tras haber sido previamente calentados: si el enfriamiento fuese
lento, habitualmente el cristal así generado tendrá pocas imperfecciones (es decir, se
encontrará en un metaestado de baja energía) que si se enfriara demasiado rápido
(metaestado de alta energía). Este modelo físico natural se basa en la propensión a minimizar
su energía libre (en el sentido de Helmholtz) de un sistema ergódico, tal como un sistema
termodinámico cerrado en que todos los estados configuracionales sean equiprobables.
Los métodos de temple se basan por lo general en el algoritmo de Monte Carlo, que repite una
gran cantidad de muestreos aleatorios sobre un hipercubo de dimensión 'N' (espacio de
soluciones del problema), a fin de generar estados muestrales y permitiendo reducir mucho la
complejidad de cómputo a costa de perder algo de precisión estadística.
https://es.wikipedia.org/wiki/Algoritmo_del_temple_cu%C3%A1ntico
La criptografía cuántica
utiliza la física para desarrollar un criptosistema completamente seguro para evitar verse
comprometido si se desconoce el remitente o del destinatario del mensaje. Una de las
acepciones de la palabra cuanto hace referencia a la conducta más fundamental de las
partículas más pequeñas de la materia y la energía.
La criptografía cuántica es distinta de los sistemas criptográficos tradicionales porque depende
más de la física que de las matemáticas, como un aspecto clave de su modelo de seguridad.
En esencia, la criptografía cuántica se basa en el uso de partículas/ondas luminosas (fotones)
individuales y sus propiedades cuánticas intrínsecas para desarrollar un criptosistema
inquebrantable (porque es imposible medir el estado cuántico de cualquier sistema sin
perturbarlo).
La criptografía cuántica usa fotones para transmitir una clave. Una vez transmitida la clave, se
puede codificar y encriptar mediante el método normal de clave secreta. Pero, ¿cómo se
convierte en clave un fotón? ¿Cómo se adjunta información a un espín de fotón?
Y aquí es donde el código binario entra en juego. Cada tipo de espín de fotón representa
información, normalmente un 1 ó un 0, para un código binario. Este código usa cadenas de
unos y ceros para crear un mensaje coherente. Por ejemplo, 11100100110 podría
corresponderse con «h-o-l-a». Por tanto, un código binario puede asignarse a cada fotón, por
ejemplo, a un fotón que tiene un espín vertical ( | ) se le puede asignar un 1.
La codificación normal, no cuántica, puede funcionar de diversas formas, pero normalmente se
cifra un mensaje que solo se puede descifrar mediante una clave secreta. El truco es
asegurarse de que a quien quiera que se intente ocultar la comunicación no meta mano a la
clave secreta. Descifrar la clave privada en un sistema criptográfico moderno normalmente
exigiría descubrir los factores de un número que es el producto de dos números primos
increíblemente enormes. Los números se eligen para ser tan grandes que, con la potencia de
procesamiento de los ordenadores, podría tardarse más tiempo que toda la vida del universo
para que un algoritmo divida su producto.
Pero dichas técnicas de cifrado tienen sus vulnerabilidades. Algunos productos, llamados
claves débiles, resultan ser más fáciles de dividir que otros. Asimismo, la ley de Moore sube
continuamente la potencia de procesamiento de nuestros ordenadores. Y lo que es más
importante, los matemáticos están desarrollando constantemente nuevos algoritmos que
permiten factorizar más fácilmente.
La criptografía cuántica evita todos estos problemas. Con ella, la clave se codifica en una serie
de fotones que van pasando entre dos partes que intentan compartir información secreta. El
principio de incertidumbre de Heisenberg preceptúa que un adversario no puede mirar estos
fotones sin cambiarlos o destruirlos.
«En tal caso, no importa qué tecnología tenga el adversario, nunca podrá romper las leyes de
la física», afirma el físico Richard Hughes del Laboratorio Nacional de Los Álamos en Nuevo
México, que trabaja con la criptografía cuántica.
https://www.bbvaopenmind.com/tecnologia/mundo-digital/entender-la-criptografia-
cuantica/
proyecto 1 evidencias
Proyecto 2 evidencias