diff --git a/challenges/PIQUE challenge/qaticos-PIQUE-challenge.ipynb b/challenges/PIQUE challenge/qaticos-PIQUE-challenge.ipynb
new file mode 100644
index 0000000..8a23acf
--- /dev/null
+++ b/challenges/PIQUE challenge/qaticos-PIQUE-challenge.ipynb
@@ -0,0 +1,35 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "2106b786-99cc-4316-9784-3107c91bfd9d",
+ "metadata": {},
+ "source": [
+ "# PIQUE CHALLENGE\n",
+ "\n",
+ "The educational resource about how to solve a Knapsack problem using QAOA, is located in [this Drive](https://drive.google.com/file/d/1p-1dzkRJDAQTkMKjFAkwFjYFTKeH3hNK/view?usp=sharing)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/hackathon/qaticos-IBM-challenge.ipynb b/hackathon/qaticos-IBM-challenge.ipynb
new file mode 100644
index 0000000..cd99dc1
--- /dev/null
+++ b/hackathon/qaticos-IBM-challenge.ipynb
@@ -0,0 +1,639 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#
Hackathon Qiskit Fall Fest Latino 2023\n",
+ "# IBM Challenge\n",
+ "# Solución de un problema de la mochila (Knapsack Problem) con QAOA\n",
+ "\n",
+ "> Integrantes del equipo: Jorge Luis Pérez Ramírez, Mariana F. Portugal Moreyra, Luis Leon Ortega, Hillary Temaxte Cano."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Descripción del problema"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Los desastres naturales, como terremotos, inundaciones, huracanes y incendios forestales, pueden tener devastadoras consecuencias en las localidades afectadas. Estos eventos suelen provocar la destrucción de viviendas, infraestructuras y servicios básicos, dejando a las comunidades en una situación de vulnerabilidad extrema. Además, pueden causar lesiones y pérdida de vidas humanas, generando un profundo impacto emocional y físico en la población. \n",
+ "\n",
+ "En este contexto, el envío de víveres e insumos adquiere una importancia fundamental, ya que proporciona a las víctimas acceso a alimentos, agua limpia, refugio temporal y suministros médicos esenciales. La entrega oportuna y eficiente de estos suministros es crucial para mitigar el impacto de los desastres naturales y ayudar a las comunidades a reconstruirse y recuperarse.\n",
+ "\n",
+ "Dicho envío de insumos se lleva a cabo por distintos medios de transporte, siendo el helicóptero fundamental por su versatilidad. Esto ya que existen desastres naturales que ocasionan daños en las vías terrestres y puertos marítimos, lo cual obstaculiza la llegada de los suministros a las localidades afectadas.\n",
+ "\n",
+ "De acuerdo a publicaciones realizadas por el gobierno de Texas [**[1]**](https://texasready.gov/build-a-kit/disaster-supply-checklist-es.html), la Agencia Federal de Gestión de Emergencias (FEMA, por sus siglas en inglés) [**[2]**]((https://www.fema.gov/es/blog/10-items-include-your-emergency-kit)) y el gobierno de México [**[3]**](https://www.gob.mx/cenapred/articulos/sacate-un-10-en-tu-mochila-de-emergencia), algunos de los artículos que más se requieren ante una emergencia causada por un desastre natural son:\n",
+ "\n",
+ "- Agua, alimentos no perecederos, botiquín de primeros auxilios, medicamentos, jabón, blanqueador (para purificar el agua), linternas, radios, cerillos y ropa.\n",
+ "\n",
+ "Así, surge un gran problema de optimización, ya que cada medio de transporte que se mande, debe contener los víveres e insumos que brinden el mayor beneficio a la población. Otro de los retos que esto conlleva, es que la carga total de dichos suministros no exceda el peso máximo permitido del medio de transporte.\n",
+ "\n",
+ "Para efectos del problema propuesto, se considera una escala de valores enteros entre 1 a 10 para representar el beneficio de cada suministro, siendo 10 el que provee mayor beneficio y 1 el que menor beneficio brinda. Asignando los valores más altos a los artículos vitales, el beneficio asociado a cada uno quedaría como:\n",
+ "\n",
+ "$$\\text{Agua} = 10, \\, \\text{Alimentos} = 9, \\, \\text{Botiquín} = 8, \\, \\text{Medicamentos} = 7, \\, \\text{Blanqueador} = 6, \\\\\n",
+ " \\text{Linternas} = 5, \\, \\text{Ropa} = 4, \\, \\text{Jabón} = 3, \\, \\text{Cerillos} = 2, \\, \\text{Radios} = 1$$\n",
+ "\n",
+ "**Nota: esta asignación puede ser subjetiva, por lo que se pueden cambiar los valores dependiendo del contexto o preferencias**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "El peso asociado a cada suministro está dado por:\n",
+ "\n",
+ "$$\\text{Agua} = 1400\\, kg, \\, \\text{Alimentos} = 2000\\, kg, \\, \\text{Botiquín} = 1100\\, kg, \\, \\text{Medicamentos} = 1000\\, kg, \\, \\text{Blanqueador} = 1800\\, kg, \\\\\n",
+ " \\text{Linternas} = 1300\\, kg, \\, \\text{Ropa} = 1200\\, kg, \\, \\text{Jabón} = 1600\\, kg, \\, \\text{Cerillos} = 1000\\, kg, \\, \\text{Radios} = 1100\\, kg$$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Suponiendo que el medio de transporte es un helicóptero militar H225M, entonces, de acuerdo a su [ficha técnica](https://www.airbus.com/sites/g/files/jlcbta136/files/2021-07/Carte-Correspondance-2017.pdf), su máxima capacidad de carga (interna + carga suspendida) es de $W \\approx 8800 \\ \\text{kg}$.\n",
+ "\n",
+ "Asignando cada suministro a una variable $x_i, \\, i=1,...,10$ tal que\n",
+ "\n",
+ "$$x_1 = \\text{Botiquín}, x_2 = \\text{Cerillos}, x_3 = \\text{Agua}, x_4 = \\text{Radios}, x_5 = \\text{Blanqueador}, \\\\ \n",
+ "x_6 = \\text{Alimentos}, x_7 = \\text{Ropa}, x_8 = \\text{Medicamentos}, x_9 = \\text{Linternas}, x_{10} = \\text{Jabón.}$$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Entonces, se sigue que la función a maximizar es\n",
+ "$$f(x) = 8x_1 + 2x_2 + 10x_3 + x_4 + 6x_5 + 9x_6 + 4x_7 + 7x_8 + 5x_9 + 3x_{10}\\, ,$$\n",
+ "\n",
+ "con la restricción de que la suma de los pesos asociadas a cada suministro, no puede exceder la máxima capacidad de carga del helicóptero; es decir\n",
+ "\n",
+ "$$ 1100x_1 + 1000x_2 + 1400x_3 + 1100x_4 + 1800x_5 + 2000x_6 + 1200x_7 + 1000x_8 + 1300x_9 + 1600x_{10} \\leq 8800 \\, ,$$\n",
+ "\n",
+ "y donde cada suministro ($x_i$) únicamente puede ser incluido (o no) dentro del helicóptero; es decir\n",
+ "\n",
+ "$$x_i \\in \\{0,1\\}$$\n",
+ "\n",
+ "Por tanto, se puede observar que el problema de optimización sigue la estructura del problema de la mochila (knapsack problem), y por tanto se puede resolver con Qiskit usando QAOA."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Marco teórico"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### ¿Qué es un problema de la mochila (Knapsack problem)?\n",
+ "\n",
+ "El problema de la mochila (KP, por sus siglas en inglés Knapsack Problem) es un problema de optimización combinatoria de formulación sencilla, aunque de resolución compleja y que aparece directamente o como un subproblema en una gran variedad de aplicaciones incluyendo planificación de la producción, muestreo estratificado, planificación de la capacidad de instalaciones, etc.\n",
+ "Sea un conjunto de objetos finito $$J={x_1, x_2 ,x_3,...,x_n}$$ con utilidades unitarias $$p_1, p_2,p_3,...p_n$$ y con pesos $$w_1, w_2, w_3,...,w_n$$ respectivamente. Dado que se tiene como recipiente (la mochila) de capacidad c, el problema entonces consiste en determinar que objetos debo seleccionar para incluir en la mochila, de tal manera que la utilidad total de los objetos que se cargan sea la máxima posible.\n",
+ "Entonces se puede escribir matemáticamente un problema de la mochila de la siguiente forma:\n",
+ "$$Maximizar = \\sum_{i=1}^{n}x_{i}=p_{i}x_{i} $$\n",
+ "con las siguientes restricciones:\n",
+ "$$\\sum_{i=1}^{n} w_{i} x_{i} \\leq c $$ para \n",
+ "$$x_i \\in \\{0,1\\}$$; i=1,2,3,...,n\n",
+ "En donde si $$x_i= 1$$ esté elemento estará en la mochila, de lo contrario $$x_i=0$$ y no estará en la mochila (Sandoya, 2014)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### QAOA\n",
+ "Es un algoritmo cuántico diseñado para abordar problemas de optimización combinatoria. Utiliza una secuencia de operadores cuánticos para evolucionar el estado sistema y busca encontrar soluciones cercanas a la óptima. Inspirado en la idea de combinar optimización clásica con procesos cuánticos, QAOA se ha destacado en la resolución de problemas de la mochila, entre otros. \n",
+ "\n",
+ "\n",
+ " QAOA es especialmente relevante en la resolución de problemas cuadráticos no convexos (QUBO, por sus siglas en inglés: Quadratic Unconstrained Binary Optimization). Un QUBO se formula como la minimización de una función cuadrática sobre variables binarias (que pueden tomar valores de 0 o 1), y estos problemas surgen en una amplia gama de aplicaciones, como la optimización combinatoria, el diseño de circuitos, y la asignación de recursos..\n",
+ "
\n",
+ "La capacidad para abordar QUBOs radica en su habilidad para mapear estos problemas cuadráticos en términos de Hamiltonianos cuánticos. En el contexto de QAOA, el problema QUBO se traduce en un Hamiltoniano que representa la energía total del sistema cuántico, y la tarea del algoritmo es encontrar el estado cuántico de menor energía, equivalente a la solución óptima del problema."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Hamiltoniano del modelo Ising\n",
+ "\n",
+ "Es un concepto fundamental en la física estadística y la teoría de la mecánica estadística. Describe la interacción entre partículas en un sistema magnético en una red cristalina. En esencia, el Hamiltoniano del modelo Ising representa la energía total del sistema y se formula a partir de la suma de interacciones entre espines de partículas vecinas en una red. Los espines pueden tomar valores +1 o -1, y las interacciones entre ellos determinan la contribución a la energía total del sistema. Este modelo es fundamental para entender fenómenos como la transición de fase y los fenómenos magnéticos en materiales. En computación cuántica, el modelo Ising es relevante en la formulación de problemas para algoritmos cuánticos como el recocido cuántico y para abordar problemas de optimización."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### QUBO\n",
+ "Un QUBO (Quadratic Unconstrained Binary Optimization) es un tipo de problema de optimización que busca minimizar una función cuadrática sobre variables binarias, es decir, variables que pueden tomar solo dos valores, 0 o 1. \n",
+ "\n",
+ "$$Minimizar f(x)=\\sum_{i=1}^{N} \\sum_{j=1}^{N} Q_{i,j} x_i x_j + \\sum_{i=1}^{N} c_i x_i + d$$\n",
+ "donde $$x_i$$ son las variables binarias, $$Q_{ii}$$ son los coeficientes lineales, y $$Q_{ij}$$ son los coeficientes cuadráticos. Cada término en la función representa la contribución a la energía total del sistema, y el objetivo es encontrar la configuración de variables binarias que minimiza esta energía. Los problemas QUBO tienen aplicaciones en diversos campos, como la optimización combinatoria, el diseño de circuitos y la asignación de recursos.\n",
+ "\n",
+ "\n",
+ "La relación entre el problema de la mochila y la formulación QUBO radica en la capacidad de representar el problema de la mochila como una función cuadrática sobre variables binarias.\n",
+ "Transicion: \n",
+ "- Variables binarias\n",
+ "- Función objetivo\n",
+ "- Mapeo a Qubo\n",
+ "- La función objetivo resultante representa un problema QUBO. La minimización de esta función sobre las variables binarias da como resultado la configuración óptima de objetos para la mochila, maximizando el valor total y respetando el límite de peso.\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Quadratic Problems"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Los problemas cuadráticos son una clase de problemas de optimización donde el objetivo es maximizar o minimizar una función cuadrática. Estas funciones cuadráticas tienen términos de segundo grado, involucrando variables al cuadrado y términos cruzados.\n",
+ "Estos problemas son fundamentales en optimización y modelado, y se encuentran en diversas aplicaciones, desde la programación cuadrática en matemáticas hasta la formulación de problemas de ingeniería y economía. Un subtipo específico de problemas cuadráticos son los problemas cuadráticos no convexos (QUBO), que son relevantes en la computación cuántica y la optimización combinatoria."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Solución del problema"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Por efectos prácticos en el tiempo de computación, en cada una de las soluciones, tanto los pesos de cada suministro como la máxima capacidad de carga serán expresados implicitamente en notación científica, con orden de magnitud $10^2$ (p. ej. $1800 = 18\\times 10^2$). \n",
+ "\n",
+ "Así, la restricción de la función a optimizar se expresa como\n",
+ "$$ 11\\times 10^2 x_1 + 10\\times 10^2 x_2 + 14\\times 10^2 x_3 + 11\\times 10^2 x_4 + 18\\times 10^2 x_5 \\\\+ 20\\times 10^2 x_6 + 12\\times 10^2 x_7 + 10\\times 10^2 x_8 + 13\\times 10^2 x_9 + 16\\times 10^2 x_{10} \\leq 88\\times 10^2 \\, ,$$\n",
+ "\n",
+ "y en el código se usarán únicamente las mantisas de cada peso."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Para poder solucionar este problema, se tomaron de inspiración los ejercicios de optimización de la Escuela de Computación Cuántica - Qiskit Fall Fest Latino 2023 [**[11]**](https://github.com/fall-fest-latino/escuela-de-computacion-cuantica-2023/blob/main/ejercicios/ejercicio4_optimizacion.ipynb), y de IBM Quantum Challenge Fall 2021. [**[12]**](https://github.com/qiskit-community/ibm-quantum-challenge-fall-2021/blob/main/content/challenge-4/challenge-4.ipynb). Dichos recursos sirvieron de base para poder desarrollar el código descrito a continuación:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit_optimization.algorithms import MinimumEigenOptimizer\n",
+ "from qiskit import Aer\n",
+ "from qiskit.utils import algorithm_globals, QuantumInstance\n",
+ "from qiskit_algorithms.optimizers import COBYLA\n",
+ "from qiskit.algorithms import QAOA, NumPyMinimumEigensolver\n",
+ "from qiskit_optimization.applications import Knapsack\n",
+ "from qiskit_optimization.converters import QuadraticProgramToQubo\n",
+ "from qiskit.primitives import Sampler\n",
+ "\n",
+ "import numpy as np\n",
+ "import warnings\n",
+ "warnings.filterwarnings('ignore')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Solución clásica"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Existen varias maneras de resolver el problema de la mochila de forma clásica. Para este caso, se decidió que una de las implementaciones clásicas a utilizar sería por medio de programación dinámica. [**[13]**](https://medium.com/@fabianterh/how-to-solve-the-knapsack-problem-with-dynamic-programming-eb88c706d3cf)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Antes, definiremos los valores, pesos y nombres de las variables que definen nuestra aplicación del problema de la mochila:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Se definen los beneficios y pesos asociados a cada suministro, así como la máxima capacidad de carga\n",
+ "benft = [8, 2, 10, 1, 6, 9, 4, 7, 5, 3] # los valores de los beneficios asociados a cada suministro\n",
+ "ind_w = [11, 10, 14, 11, 18, 20, 12, 10, 13, 16] # los pesos individuales asociados a cada suministro (el 10^2 está implícito)\n",
+ "W = 88 # La máxima capacidad de carga del helícoptero (el 10^2 está implícito)\n",
+ "\n",
+ "# Creamos una lista con todos los nombres de los suministros\n",
+ "supplies_names = [\"botiquin\", \"cerillos\", \"agua\", \"radios\", \"blanqueador\", \"alimentos\", \"ropa\", \"medicamentos\", \"linternas\", \"jabón\"]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Programación dinámica"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Como cada forma de solucionar el problema devuelve por \"default\" los índices de los suministros seleccionados, definiremos una función que devuelva el nombre asociado al suministro seleccionado. Tal que"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def selected_indexes_to_names(items, selected_indexes_list):\n",
+ " \"\"\"\n",
+ " Muestra los nombres de los suministros seleccionados, a partir de los índices devueltos en cada solución.\n",
+ "\n",
+ " Parámetros:\n",
+ " - items: Lista de los nombres de los suministros.\n",
+ " - selected_indexes_list: Lista de los índices de los suministros seleccionados.\n",
+ "\n",
+ " Returns:\n",
+ " - Una string que devuelve los nombres de los suministros seleccionados.\n",
+ " \"\"\"\n",
+ " # Filtra los elementos seleccionados\n",
+ " selected_supply = [items[i] for i in selected_indexes_list]\n",
+ "\n",
+ " # Crea una cadena descriptiva de los elementos seleccionados\n",
+ " intro_selected_names = \"los suministros seleccionados son: \\n\"\n",
+ " for elemento in selected_supply:\n",
+ " intro_selected_names += str(elemento) + \", \"\n",
+ "\n",
+ " # Devuelve el nombre de los suministros seleccionados que solucionan el problema,\n",
+ " # en formato string\n",
+ " return intro_selected_names[:-2]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "A continuación, se muestra la función que resuelve el problema de la mochila por medio de programación dinámica."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def get_knapsack_dyn_prog(max_weight, weights, values, n):\n",
+ " \"\"\"\n",
+ " Resuelve el problema de la mochila por medio de programación dinámica.\n",
+ "\n",
+ " Parámetros:\n",
+ " - max_weight: Entero. Máxima carga que se puede transportar.\n",
+ " - weights: Lista de los pesos individuales de cada suministro.\n",
+ " - values: Lista del beneficio asociado a cada suministro.\n",
+ " - n: Entero. Longitud de la lista de los pesos individuales.\n",
+ "\n",
+ " Devuelve:\n",
+ " - storage_m[n][max_weight] : valor óptimo\n",
+ " - selected_supplies[::-1] : Lista de índices de los suministros seleccionados\n",
+ "\n",
+ " \"\"\"\n",
+ " # Se crea una matriz, para almacenar los resultados de los subproblemas\n",
+ " storage_m = [[0 for _ in range(max_weight + 1)] for _ in range(n + 1)]\n",
+ "\n",
+ " # Se llena la matriz (usando programación dinámica)\n",
+ " for i in range(n + 1):\n",
+ " for w in range(max_weight + 1):\n",
+ " if i == 0 or w == 0:\n",
+ " storage_m[i][w] = 0\n",
+ " elif weights[i - 1] <= w:\n",
+ " storage_m[i][w] = max(values[i - 1] + storage_m[i - 1][w - weights[i - 1]], storage_m[i - 1][w])\n",
+ " else:\n",
+ " storage_m[i][w] = storage_m[i - 1][w]\n",
+ "\n",
+ " # Se obtienen los suministros seleccionados para la obtimización\n",
+ " selected_supplies = []\n",
+ " i, j = n, max_weight\n",
+ " while i > 0 and j > 0:\n",
+ " if storage_m[i][j] != storage_m[i - 1][j]:\n",
+ " selected_supplies.append(i - 1)\n",
+ " j -= weights[i - 1]\n",
+ " i -= 1\n",
+ "\n",
+ " # Devuelve el valor óptimo, y los índices de los suministros seleccionados\n",
+ " return storage_m[n][max_weight], selected_supplies[::-1]\n",
+ "\n",
+ "# Utiliza la longitud de la lista de los pesos individuales\n",
+ "n = len(ind_w) \n",
+ "# Obtiene el valor óptimo, y los índices de los suministros seleccionados\n",
+ "dyn_prog_result, selected_items_DynProg = get_knapsack_dyn_prog(W, ind_w, benft, n)\n",
+ "# Devuelve el nombre de los suministros seleccionados\n",
+ "selected_names_DynProg = selected_indexes_to_names(supplies_names, selected_items_DynProg)\n",
+ "\n",
+ "\n",
+ "print(\"El beneficio máximo obtenido es de\", dyn_prog_result)\n",
+ "print(\"\\n Los índices de los items seleccionados son: \\n\", selected_items_DynProg)\n",
+ "print(\"\\n Usando programación dinámica, \", selected_names_DynProg)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Programación entera 0-1\n",
+ "Para resolver este tipo de problemas existen distintos algoritmos, uno de ellos por ejemplo es parecido a la estructura de algoritmo de ramificación y acotación. \n",
+ "Para la aplicación de este algoritmo los coeficientes de la función objetivo del modelo lineal entero 0-1 deben cumplir la siguiente condición:\n",
+ "$$\n",
+ "0 \\leq p_1 \\leq p_2 \\leq ... \\leq p_n \n",
+ "$$\n",
+ "Cualquier modelo lineal se puede formular de manera que cumpla la condición anterior haciendo los cambios de variable necesarios. \n",
+ "También es necesario definir lo siguiente: \n",
+ "\n",
+ "**Definición 7.1(Problema relajado)** Dado un modelo lineal 0-1, el problema lineal relajado es el modelo lineal prescindiendo de todas las restricciones del problema excepto de las restricciones de que $$x_i \\in {0,1}$$\n",
+ "\n",
+ "**Definición 7.2(Solución parcial)** Dado un modelo lineal 0-1, se llama solución parcial a una solución donde el valor de alguna variable está sin fijar.\n",
+ "\n",
+ "**Definición 7.3 (Compleción de una solución parcial)** Dado una solución parcial de un modelo lineal 0-1, una complección es una solución obtenida a partir de una solución parcial dando valor a todas las componentes que están sin fijar.\n",
+ "\n",
+ "No obstante se debe de aclarar algo, si relajamos el problema podemos observar que el vector $$(1,1,1,1,1,1,1,1,1,1)$$ no puede ser solución, así como tampoco el $$(0,0,0,0,0,0,0,0,0,0)$$ pues el primero no cumple con la restricción de peso y el segundo no es viable porque implicaría no llevar nada. Por lo que podríamos comenzar con una solución parcial como $$(0,0,0,0,0,0,0,0,-,-)$$ y como complección de una solución parcial a $$(0,0,0,0,0,0,0,0,1,1)$$ que si cumple con la restricción pero no se puede garantizar que la función tenga el valor máximo con estos valores.\n",
+ "Con esto nótese lo siguiente: f es una función que tiene como variable a $$x_i$$ donde i=1,...,10, es decir, el número de combinaciones para los $$x_i$$ que podrían estar o no dentro de la mochila sería $$2^{10}$$ por lo que tratar de encontrar una solución a este problema a mano ocupando el algoritmo anterior sería una tarea nada recomendada. Sin embargo, podríamos ocupar LINGO que es un software muy básico que permite realizar optimización de problemas de programación lineal y cuadrática, definidos sobre variables reales y/o binarias.\n",
+ "el código sería el siguiente:\n",
+ "\n",
+ "model:\n",
+ "\n",
+ "$$Max=8*x_1+2*x_2+10*x_3+x_4+6*x_5+9*x_6+4*x_7+7*x_8+5*x_9+3*x_{10}; $$\n",
+ "\n",
+ "$$1100*x_1+1000*x_2+1400*x_3+1100*x_4+1800*x_5+2000*x_6+1200*x_7+1000*x_8+1300*x_9+1600*x_{10} <= 8800;$$\n",
+ "\n",
+ "@bin(x_1); \n",
+ "\n",
+ "@bin(x_2);\n",
+ "\n",
+ "@bin(x_3);\n",
+ "\n",
+ "@bin(x_4);\n",
+ "\n",
+ "@bin(x_5); \n",
+ "\n",
+ "@bin(x_6); \n",
+ "\n",
+ "@bin(x_7); \n",
+ "\n",
+ "@bin(x_8); \n",
+ "\n",
+ "@bin(x_9); \n",
+ "\n",
+ "@bin(x_10); \n",
+ "\n",
+ "end \n",
+ "\n",
+ "El vector solución es el siguiente: $$x=(1,0,1,0,1,1,0,1,1,0)$$\n",
+ "De modo que el beneficio máximo es 45, y los suministros seleccionados son: botiquin, agua, blanqueador, alimentos, medicamentos y linternas. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "toque aquí para ver la imagen del programa (https://drive.google.com/drive/folders/11Y-_o9ZBCBWfIk-TYiV-naZ-yvBVQNEp?usp=sharing)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Solución con Qiskit"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Clase `Knapsack`"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "La clase `Knapsack` [**[14]**](https://qiskit.org/ecosystem/optimization/stubs/qiskit_optimization.applications.Knapsack.html) permite formular la función de costo del problema, permitiendo obtener además una descripción detallada del problema al usar `.prettyprint()` en su solución. [**[15]**](https://qiskit.org/ecosystem/optimization/tutorials/09_application_classes.html#Knapsack-problem)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "La descripción general del problema es\n",
+ " \n",
+ " Problem name: Knapsack\n",
+ "\n",
+ "Maximize\n",
+ " 8*x_0 + 2*x_1 + 10*x_2 + x_3 + 6*x_4 + 9*x_5 + 4*x_6 + 7*x_7 + 5*x_8 + 3*x_9\n",
+ "\n",
+ "Subject to\n",
+ " Linear constraints (1)\n",
+ " 11*x_0 + 10*x_1 + 14*x_2 + 11*x_3 + 18*x_4 + 20*x_5 + 12*x_6 + 10*x_7\n",
+ " + 13*x_8 + 16*x_9 <= 88 'c0'\n",
+ "\n",
+ " Binary variables (10)\n",
+ " x_0 x_1 x_2 x_3 x_4 x_5 x_6 x_7 x_8 x_9\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Se asignan los argumentos que Knapsack() requeire\n",
+ "kp = Knapsack(values=benft, weights=ind_w, max_weight=W)\n",
+ " \n",
+ "# to_quadratic_program generates a corresponding QuadraticProgram of the instance of the knapsack problem.\n",
+ "qp = kp.to_quadratic_program()\n",
+ "\n",
+ "print(\"La descripción general del problema es\\n \\n\", qp.prettyprint())"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Minimum Eigen Optimizer\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Una vez que tenemos representado el Knapsack problem como un QUBO, se puede utilizar el `MinimumEigenOptimizer`, a partir del cual podemos usar como solver ya sea una forma clásica (`NumPyMinimumEigensolver`) o con `QAOA`"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "##### Numpy Minimum Eigensolver"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "El beneficio máximo obtenido es de 45.0\n",
+ "\n",
+ " Los índices de los items seleccionados son: \n",
+ " [0, 2, 4, 5, 7, 8]\n",
+ "\n",
+ " Usando el método clásico NumPy Minimum Eigensolver, los suministros seleccionados son: \n",
+ "botiquin, agua, blanqueador, alimentos, medicamentos, linternas\n"
+ ]
+ }
+ ],
+ "source": [
+ "algorithm_globals.massive=True # Esto es necesario ya que la magnitud de la matriz a resolver es muy grande\n",
+ "\n",
+ "# Se utiliza el solver clásico de NumPy, Minimum Eigensolver\n",
+ "min_eigop_np = MinimumEigenOptimizer(min_eigen_solver=NumPyMinimumEigensolver())\n",
+ "np_result = min_eigop_np.solve(qp)\n",
+ "\n",
+ "# Obtiene los índices de los suministros seleccionados\n",
+ "selected_items_np = kp.interpret(np_result)\n",
+ "\n",
+ "# Devuelve el nombre de los suministros seleccionados\n",
+ "selected_names_np = selected_indexes_to_names(supplies_names, selected_items_np)\n",
+ "\n",
+ "print(\"El beneficio máximo obtenido es de\",np_result.fval)\n",
+ "print(\"\\n Los índices de los items seleccionados son: \\n\", kp.interpret(np_result)) \n",
+ "print(\"\\n Usando el método clásico NumPy Minimum Eigensolver, \", selected_names_np)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "##### QAOA"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "El beneficio máximo obtenido es de 44.0\n",
+ "\n",
+ " Los índices de los items seleccionados son: [0, 2, 4, 5, 6, 7]\n",
+ "\n",
+ " Usando QAOA, los suministros seleccionados son: \n",
+ "botiquin, agua, blanqueador, alimentos, ropa, medicamentos\n",
+ "\n",
+ " El tiempo que tardó el optimizador fue de 107.62232041358948 s\n"
+ ]
+ }
+ ],
+ "source": [
+ "seed = 123\n",
+ "algorithm_globals.random_seed = seed\n",
+ "q_inst = QuantumInstance(backend=Aer.get_backend('qasm_simulator'), shots=1000, seed_simulator=seed, seed_transpiler=seed)\n",
+ "\n",
+ "# Se utiliza QAOA como solver\n",
+ "min_eigop_qaoa = MinimumEigenOptimizer(min_eigen_solver=QAOA(reps=1, quantum_instance=q_inst))\n",
+ "qaoa_result = min_eigop_qaoa.solve(qp)\n",
+ "\n",
+ "# Obtiene los índices de los suministros seleccionados\n",
+ "selected_items_QAOA = kp.interpret(qaoa_result)\n",
+ "\n",
+ "# Devuelve el nombre de los suministros seleccionados\n",
+ "selected_names_QAOA = selected_indexes_to_names(supplies_names, selected_items_QAOA)\n",
+ "\n",
+ "print(\"El beneficio máximo obtenido es de\",qaoa_result.fval)\n",
+ "print('\\n Los índices de los items seleccionados son:', kp.interpret(qaoa_result)) \n",
+ "print(\"\\n Usando QAOA, \", selected_names_QAOA)\n",
+ "print(f\"\\n El tiempo que tardó el optimizador fue de {qaoa_result.min_eigen_solver_result.optimizer_time} s\")\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Referencias"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Referencias\n",
+ "1. Lista de verificación de kit para desastres. (s. f.). txready.org. https://texasready.gov/build-a-kit/disaster-supply-checklist-es.html\n",
+ "2. 10 artículos para incluir en su kit de suministros de emergencia. (s. f.). FEMA.gov. https://www.fema.gov/es/blog/10-items-include-your-emergency-kit\n",
+ "3. De Prevención De Desastres, C. N. (s. f.). ¡Sácate un 10 en tu mochila de emergencia! gob.mx. https://www.gob.mx/cenapred/articulos/sacate-un-10-en-tu-mochila-de-emergencia\n",
+ "4. What is the QAOA? - OpenQAOA. (s/f). Entropicalabs.com. Recuperado el 10 de noviembre de 2023, de https://openqaoa.entropicalabs.com/what-is-the-qaoa/\n",
+ "5. Bellman R., (1957). Dynamic Programming, Princeton University Press, Princeton, NJ.\n",
+ "6. Universidad Autónoma del Estado de Hidalgo. (s/f). Boletín científico :: UAEH. Edu.Mx. Recuperado el 10 de noviembre de 2023, de https://www.uaeh.edu.mx/scige/boletin/tlahuelilpan/n6/e2.html\n",
+ "7. Pérez, G., & Prefacio, N. (s/f). Modelo de Ising. Uba.ar. Recuperado el 10 de noviembre de 2023, de https://materias.df.uba.ar/ft3a2021c1/files/2012/07/Ising-2.pdf\n",
+ "8. What is a QUBO problem? - MATLAB & Simulink. (s/f). Mathworks.com. Recuperado el 10 de noviembre de 2023, de https://www.mathworks.com/help/matlab/math/what-is-a-qubo.html\n",
+ "9. van Dam, W., & Hallgren, S. (2000). Efficient quantum algorithms for shifted quadratic character problems. En arXiv [quant-ph]. http://arxiv.org/abs/quant-ph/0011067\n",
+ "10. Sandoya, F. (2014). El problema de la mochila, complejidad,cotas y métodos de búsqueda eficientes, Matemática Espol-FCNM Journal. Vol.12 Núm. 2 (2014),43-51. http://www.revistas.espol.edu.ec/index.php/matematica/article/view/504\n",
+ "11. Fall-Fest-Latino. (s. f.). Escuela-de-computacion-Cuantica-2023/ejercicios/ejercicio4_optimizacion.ipynb at main · Fall-fest-Latino/Escuela-de-computacion-Cuantica-2023. GitHub. https://github.com/fall-fest-latino/escuela-de-computacion-cuantica-2023/blob/main/ejercicios/ejercicio4_optimizacion.ipynb\n",
+ "12. Qiskit-Community. (s. f.). IBM-quantum-challenge-fall-2021/content/challenge-4/challenge-4.ipynb at main · qiskit-community/ibM-quantum-challenge-fall-2021. GitHub. https://github.com/qiskit-community/ibm-quantum-challenge-fall-2021/blob/main/content/challenge-4/challenge-4.ipynb\n",
+ "13. Terh, F. (2021, 9 diciembre). How to solve the knapsack problem with dynamic Programming. Medium. https://medium.com/@fabianterh/how-to-solve-the-knapsack-problem-with-dynamic-programming-eb88c706d3cf\n",
+ "14. Knapsack — Qiskit Optimization 0.5.0 Documentation. (s. f.). https://qiskit.org/ecosystem/optimization/stubs/qiskit_optimization.applications.Knapsack.html\n",
+ "15. Application classes for optimization problems — Qiskit Optimization 0.5.0 documentation. (s. f.). https://qiskit.org/ecosystem/optimization/tutorials/09_application_classes.html#Knapsack-problem"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}