{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Algebra Lineal con Python" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*Esta notebook fue creada originalmente como un blog post por [Raúl E. López Briega](http://relopezbriega.com.ar/) en [Mi blog sobre Python](http://relopezbriega.github.io). El contenido esta bajo la licencia BSD.*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\"Algebra" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Introducción\n", "\n", "Una de las herramientas matemáticas más utilizadas en [machine learning](http://es.wikipedia.org/wiki/Machine_learning) y [data mining](http://es.wikipedia.org/wiki/Miner%C3%ADa_de_datos) es el [Álgebra lineal](http://es.wikipedia.org/wiki/%C3%81lgebra_lineal); por tanto, si queremos incursionar en el fascinante mundo del aprendizaje automático y el análisis de datos es importante reforzar los conceptos que forman parte de sus cimientos. \n", "\n", "El [Álgebra lineal](http://es.wikipedia.org/wiki/%C3%81lgebra_lineal) es una rama de las [matemáticas](http://es.wikipedia.org/wiki/Matem%C3%A1ticas) que es sumamente utilizada en el estudio de una gran variedad de ciencias, como ser, ingeniería, finanzas, investigación operativa, entre otras. Es una extensión del [álgebra](http://es.wikipedia.org/wiki/%C3%81lgebra) que aprendemos en la escuela secundaria, hacia un mayor número de dimensiones; en lugar de trabajar con incógnitas a nivel de escalares comenzamos a trabajar con matrices y [vectores](http://es.wikipedia.org/wiki/Vector). \n", "\n", "El estudio del [Álgebra lineal](http://es.wikipedia.org/wiki/%C3%81lgebra_lineal) implica trabajar con varios objetos matemáticos, como ser:\n", "\n", "* **Los Escalares**: Un *escalar* es un solo número, en contraste con la mayoría de los otros objetos estudiados en [Álgebra lineal](http://es.wikipedia.org/wiki/%C3%81lgebra_lineal), que son generalmente una colección de múltiples números.\n", "\n", "* **Los [Vectores](http://es.wikipedia.org/wiki/Vector)**:Un *vector* es una serie de números. Los números tienen una orden preestablecido, y podemos identificar cada número individual por su índice en ese orden. Podemos pensar en los *vectores* como la identificación de puntos en el espacio, con cada elemento que da la coordenada a lo largo de un eje diferente. Existen dos tipos de *vectores*, los *vectores de fila* y los *vectores de columna*. Podemos representarlos de la siguiente manera, dónde *f* es un vector de fila y *c* es un vector de columna:\n", "$$f=\\begin{bmatrix}0&1&-1\\end{bmatrix} ; c=\\begin{bmatrix}0\\\\1\\\\-1\\end{bmatrix}$$\n", "\n", "* **Las Matrices**: Una *matriz* es un arreglo bidimensional de números (llamados entradas de la matriz) ordenados en filas (o renglones) y columnas, donde una fila es cada una de las líneas horizontales de la matriz y una columna es cada una de las líneas verticales. En una *matriz* cada elemento puede ser identificado utilizando dos índices, uno para la fila y otro para la columna en que se encuentra. Las podemos representar de la siguiente manera, *A* es una matriz de 3x2.\n", "$$A=\\begin{bmatrix}0 & 1& \\\\-1 & 2 \\\\ -2 & 3\\end{bmatrix}$$\n", "\n", "* **Los [Tensores](http://es.wikipedia.org/wiki/C%C3%A1lculo_tensorial)**:En algunos casos necesitaremos una matriz con más de dos ejes. En general, una serie de números dispuestos en una cuadrícula regular con un número variable de ejes es conocido como un *tensor*.\n", "\n", "Sobre estos objetos podemos realizar las operaciones matemáticas básicas, como ser [adición](http://es.wikipedia.org/wiki/Adici%C3%B3n), [multiplicación](http://es.wikipedia.org/wiki/Multiplicaci%C3%B3n), [sustracción](http://es.wikipedia.org/wiki/Sustracci%C3%B3n) y división, es decir que vamos a poder sumar [vectores](http://es.wikipedia.org/wiki/Vector) con matrices, multiplicar escalares a [vectores](http://es.wikipedia.org/wiki/Vector) y demás." ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## Librerías de Python para álgebra lineal\n", "\n", "Los principales módulos que [Python](http://python.org/) nos ofrece para realizar operaciones de [Álgebra lineal](http://es.wikipedia.org/wiki/%C3%81lgebra_lineal) son los siguientes:\n", "\n", "* **[Numpy](http://www.numpy.org/)**: El popular paquete matemático de [Python](http://python.org/), nos va a permitir crear *[vectores](http://es.wikipedia.org/wiki/Vector)*, *matrices* y *[tensores](http://es.wikipedia.org/wiki/C%C3%A1lculo_tensorial)* con suma facilidad.\n", "\n", "* **[numpy.linalg](http://docs.scipy.org/doc/numpy/reference/routines.linalg.html)**: Este es un submodulo dentro de [Numpy](http://www.numpy.org/) con un gran número de funciones para resolver ecuaciones de [Álgebra lineal](http://es.wikipedia.org/wiki/%C3%81lgebra_lineal).\n", "\n", "* **[scipy.linalg](http://docs.scipy.org/doc/scipy/reference/tutorial/linalg.html)**: Este submodulo del paquete científico [Scipy](http://docs.scipy.org/doc/scipy/reference/index.html) es muy similar al anterior, pero con algunas más funciones y optimaciones.\n", "\n", "* **[Sympy](http://www.sympy.org/es/)**: Esta librería nos permite trabajar con matemática simbólica, convierte a [Python](http://python.org/) en un [sistema algebraico computacional](http://es.wikipedia.org/wiki/Sistema_algebraico_computacional). Nos va a permitir trabajar con ecuaciones y fórmulas simbólicamente, en lugar de numéricamente.\n", "\n", "* **[CVXOPT](http://cvxopt.org/)**: Este módulo nos permite resolver problemas de optimizaciones de [programación lineal](http://es.wikipedia.org/wiki/Programaci%C3%B3n_lineal). \n", "\n", "* **[PuLP](http://pythonhosted.org//PuLP/)**: Esta librería nos permite crear modelos de [programación lineal](http://es.wikipedia.org/wiki/Programaci%C3%B3n_lineal) en forma muy sencilla con [Python](http://python.org/)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Operaciones básicas" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "### Vectores\n", "\n", "Un *[vector](http://es.wikipedia.org/wiki/Vector)* de largo `n` es una secuencia (o *array*, o *tupla*) de `n` números. La solemos escribir como x=(x1,...,xn) o x=[x1,...,xn]\n", "\n", "En [Python](http://python.org/), un *[vector](http://es.wikipedia.org/wiki/Vector)* puede ser representado con una simple *lista*, o con un *array* de [Numpy](http://www.numpy.org/); siendo preferible utilizar esta última opción." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[2, 4, 6]" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Vector como lista de Python\n", "v1 = [2, 4, 6]\n", "v1" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 1., 1., 1.])" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Vectores con numpy\n", "import numpy as np\n", "\n", "v2 = np.ones(3) # vector de solo unos.\n", "v2" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([1, 3, 5])" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v3 = np.array([1, 3, 5]) # pasando una lista a las arrays de numpy\n", "v3" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([1, 2, 3, 4, 5, 6, 7])" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v4 = np.arange(1, 8) # utilizando la funcion arange de numpy\n", "v4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Representación gráfica\n", "\n", "Tradicionalmente, los *[vectores](http://es.wikipedia.org/wiki/Vector)* son representados visualmente como flechas que parten desde el origen hacia un punto.\n", "\n", "Por ejemplo, si quisiéramos representar graficamente a los vectores v1=[2, 4], v2=[-3, 3] y v3=[-4, -3.5], podríamos hacerlo de la siguiente manera." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "from warnings import filterwarnings\n", "\n", "%matplotlib inline\n", "filterwarnings('ignore') # Ignorar warnings" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def move_spines():\n", " \"\"\"Crea la figura de pyplot y los ejes. Mueve las lineas de la izquierda y de abajo\n", " para que se intersecten con el origen. Elimina las lineas de la derecha y la de arriba.\n", " Devuelve los ejes.\"\"\"\n", " fix, ax = plt.subplots()\n", " for spine in [\"left\", \"bottom\"]:\n", " ax.spines[spine].set_position(\"zero\")\n", " \n", " for spine in [\"right\", \"top\"]:\n", " ax.spines[spine].set_color(\"none\")\n", " \n", " return ax\n", "\n", "def vect_fig(): \n", " \"\"\"Genera el grafico de los vectores en el plano\"\"\"\n", " ax = move_spines()\n", " \n", " ax.set_xlim(-5, 5)\n", " ax.set_ylim(-5, 5)\n", " ax.grid()\n", " vecs = [[2, 4], [-3, 3], [-4, -3.5]] # lista de vectores\n", " for v in vecs:\n", " ax.annotate(\" \", xy=v, xytext=[0, 0],\n", " arrowprops=dict(facecolor=\"blue\",\n", " shrink=0,\n", " alpha=0.7,\n", " width=0.5))\n", " ax.text(1.1 * v[0], 1.1 * v[1], v)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\nRCRD/x+DV+wghA3/vgAAAABJRU5ErkJggg==\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "vect_fig() # crea el gráfico" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Operaciones con vectores\n", "\n", "Las operaciones más comunes que utilizamos cuando trabajamos con *[vectores](http://es.wikipedia.org/wiki/Vector)* son la *suma*, la *resta* y la *multiplicación por escalares*.\n", "\n", "Cuando *sumamos* dos *[vectores](http://es.wikipedia.org/wiki/Vector)*, vamos sumando elemento por elemento de cada\n", "*[vector](http://es.wikipedia.org/wiki/Vector)*.\n", "\n", "$$ \\begin{split}x + y\n", "=\n", "\\left[\n", "\\begin{array}{c}\n", " x_1 \\\\\n", " x_2 \\\\\n", " \\vdots \\\\\n", " x_n\n", "\\end{array}\n", "\\right]\n", "+\n", "\\left[\n", "\\begin{array}{c}\n", " y_1 \\\\\n", " y_2 \\\\\n", " \\vdots \\\\\n", " y_n\n", "\\end{array}\n", "\\right]\n", ":=\n", "\\left[\n", "\\begin{array}{c}\n", " x_1 + y_1 \\\\\n", " x_2 + y_2 \\\\\n", " \\vdots \\\\\n", " x_n + y_n\n", "\\end{array}\n", "\\right]\\end{split}$$\n", "\n", "De forma similar funciona la operación de resta.\n", "\n", "$$ \\begin{split}x - y\n", "=\n", "\\left[\n", "\\begin{array}{c}\n", " x_1 \\\\\n", " x_2 \\\\\n", " \\vdots \\\\\n", " x_n\n", "\\end{array}\n", "\\right]\n", "-\n", "\\left[\n", "\\begin{array}{c}\n", " y_1 \\\\\n", " y_2 \\\\\n", " \\vdots \\\\\n", " y_n\n", "\\end{array}\n", "\\right]\n", ":=\n", "\\left[\n", "\\begin{array}{c}\n", " x_1 - y_1 \\\\\n", " x_2 - y_2 \\\\\n", " \\vdots \\\\\n", " x_n - y_n\n", "\\end{array}\n", "\\right]\\end{split}$$\n", "\n", "La *multiplicación por escalares* es una operación que toma a un número $\\gamma$, y a un *[vector](http://es.wikipedia.org/wiki/Vector)* $x$ y produce un nuevo *[vector](http://es.wikipedia.org/wiki/Vector)* donde cada elemento del vector $x$ es multiplicado por el número $\\gamma$.\n", "\n", "$$\\begin{split}\\gamma x\n", ":=\n", "\\left[\n", "\\begin{array}{c}\n", " \\gamma x_1 \\\\\n", " \\gamma x_2 \\\\\n", " \\vdots \\\\\n", " \\gamma x_n\n", "\\end{array}\n", "\\right]\\end{split}$$\n", "\n", "En [Python](http://python.org/) podríamos realizar estas operaciones en forma muy sencilla:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(array([1, 2, 3, 4]), array([2, 4, 6, 8]))" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Ejemplo en Python\n", "x = np.arange(1, 5)\n", "y = np.array([2, 4, 6, 8])\n", "x, y" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 3, 6, 9, 12])" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# sumando dos vectores numpy\n", "x + y" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([-1, -2, -3, -4])" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# restando dos vectores\n", "x - y" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([2, 4, 6, 8])" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# multiplicando por un escalar\n", "x * 2" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 6, 12, 18, 24])" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y * 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Producto escalar o interior\n", "\n", "El [producto escalar](https://es.wikipedia.org/wiki/Producto_escalar) de dos *[vectores](http://es.wikipedia.org/wiki/Vector)* se define como la suma de los productos de sus elementos, suele representarse matemáticamente como < x, y > o x'y, donde x e y son dos vectores.\n", "\n", "$$< x, y > := \\sum_{i=1}^n x_i y_i$$\n", "\n", "Dos *[vectores](http://es.wikipedia.org/wiki/Vector)* son ortogonales o perpendiculares cuando forman ángulo recto entre sí. Si el producto escalar de dos vectores es cero, ambos vectores son ortogonales.\n", "\n", "Adicionalmente, todo [producto escalar](https://es.wikipedia.org/wiki/Producto_escalar) induce una [norma](https://es.wikipedia.org/wiki/Norma_vectorial) sobre el espacio en el que está definido, de la siguiente manera:\n", "\n", "$$\\| x \\| := \\sqrt{< x, x>} := \\left( \\sum_{i=1}^n x_i^2 \\right)^{1/2}$$\n", "\n", "En [Python](http://python.org/) lo podemos calcular de la siguiente forma:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "60" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Calculando el producto escalar de los vectores x e y\n", "np.dot(x, y)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "60" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# o lo que es lo mismo, que:\n", "sum(x * y)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "5.4772255750516612" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Calculando la norma del vector X\n", "np.linalg.norm(x)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "5.4772255750516612" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# otra forma de calcular la norma de x\n", "np.sqrt(np.dot(x, x))" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# vectores ortogonales\n", "v1 = np.array([3, 4])\n", "v2 = np.array([4, -3])\n", "\n", "np.dot(v1, v2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Matrices\n", "\n", "Las matrices son una forma clara y sencilla de organizar los datos para su uso en operaciones lineales.\n", "\n", "Una matriz `n × k` es una agrupación rectangular de números con n filas y k columnas; se representa de la siguiente forma:\n", "\n", "$$\\begin{split}A =\n", "\\left[\n", "\\begin{array}{cccc}\n", " a_{11} & a_{12} & \\cdots & a_{1k} \\\\\n", " a_{21} & a_{22} & \\cdots & a_{2k} \\\\\n", " \\vdots & \\vdots & & \\vdots \\\\\n", " a_{n1} & a_{n2} & \\cdots & a_{nk}\n", "\\end{array}\n", "\\right]\\end{split}$$\n", "\n", "En la matriz A, el símbolo $a_{nk}$ representa el elemento n-ésimo de la fila en la k-ésima columna. La matriz A también puede ser llamada un *[vector](http://es.wikipedia.org/wiki/Vector)* si cualquiera de n o k son iguales a 1. En el caso de n=1, A se llama un *[vector](http://es.wikipedia.org/wiki/Vector) fila*, mientras que en el caso de k=1 se denomina un *[vector](http://es.wikipedia.org/wiki/Vector) columna*.\n", "\n", "Las matrices se utilizan para múltiples aplicaciones y sirven, en particular, para representar los coeficientes de los sistemas de ecuaciones lineales o para representar transformaciones lineales dada una base. Pueden sumarse, multiplicarse y descomponerse de varias formas." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Operaciones con matrices\n", "\n", "Al igual que con los *[vectores](http://es.wikipedia.org/wiki/Vector)*, que no son más que un caso particular, las matrices se pueden *sumar*, *restar* y la *multiplicar por escalares*.\n", "\n", "Multiplicacion por escalares:\n", "$$\\begin{split}\\gamma A\n", "\\left[\n", "\\begin{array}{ccc}\n", " a_{11} & \\cdots & a_{1k} \\\\\n", " \\vdots & \\vdots & \\vdots \\\\\n", " a_{n1} & \\cdots & a_{nk} \\\\\n", "\\end{array}\n", "\\right]\n", ":=\n", "\\left[\n", "\\begin{array}{ccc}\n", " \\gamma a_{11} & \\cdots & \\gamma a_{1k} \\\\\n", " \\vdots & \\vdots & \\vdots \\\\\n", " \\gamma a_{n1} & \\cdots & \\gamma a_{nk} \\\\\n", "\\end{array}\n", "\\right]\\end{split}$$\n", "\n", "Suma de matrices: $$\\begin{split}A + B =\n", "\\left[\n", "\\begin{array}{ccc}\n", " a_{11} & \\cdots & a_{1k} \\\\\n", " \\vdots & \\vdots & \\vdots \\\\\n", " a_{n1} & \\cdots & a_{nk} \\\\\n", "\\end{array}\n", "\\right]\n", "+\n", "\\left[\n", "\\begin{array}{ccc}\n", " b_{11} & \\cdots & b_{1k} \\\\\n", " \\vdots & \\vdots & \\vdots \\\\\n", " b_{n1} & \\cdots & b_{nk} \\\\\n", "\\end{array}\n", "\\right]\n", ":=\n", "\\left[\n", "\\begin{array}{ccc}\n", " a_{11} + b_{11} & \\cdots & a_{1k} + b_{1k} \\\\\n", " \\vdots & \\vdots & \\vdots \\\\\n", " a_{n1} + b_{n1} & \\cdots & a_{nk} + b_{nk} \\\\\n", "\\end{array}\n", "\\right]\\end{split}$$\n", "\n", "Resta de matrices: $$\\begin{split}A - B =\n", "\\left[\n", "\\begin{array}{ccc}\n", " a_{11} & \\cdots & a_{1k} \\\\\n", " \\vdots & \\vdots & \\vdots \\\\\n", " a_{n1} & \\cdots & a_{nk} \\\\\n", "\\end{array}\n", "\\right]-\n", "\\left[\n", "\\begin{array}{ccc}\n", " b_{11} & \\cdots & b_{1k} \\\\\n", " \\vdots & \\vdots & \\vdots \\\\\n", " b_{n1} & \\cdots & b_{nk} \\\\\n", "\\end{array}\n", "\\right]\n", ":=\n", "\\left[\n", "\\begin{array}{ccc}\n", " a_{11} - b_{11} & \\cdots & a_{1k} - b_{1k} \\\\\n", " \\vdots & \\vdots & \\vdots \\\\\n", " a_{n1} - b_{n1} & \\cdots & a_{nk} - b_{nk} \\\\\n", "\\end{array}\n", "\\right]\\end{split}$$\n", "\n", "Para los casos de suma y resta, hay que tener en cuenta que solo se pueden sumar o restar matrices que tengan las mismas dimensiones, es decir que si tengo una matriz A de dimensión 3x2 (3 filas y 2 columnas) solo voy a poder sumar o restar la matriz B si esta también tiene 3 filas y 2 columnas." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Ejemplo en Python\n", "A = np.array([[1, 3, 2],\n", " [1, 0, 0],\n", " [1, 2, 2]])\n", "\n", "B = np.array([[1, 0, 5],\n", " [7, 5, 0],\n", " [2, 1, 1]])" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[2, 3, 7],\n", " [8, 5, 0],\n", " [3, 3, 3]])" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# suma de las matrices A y B\n", "A + B" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 0, 3, -3],\n", " [-6, -5, 0],\n", " [-1, 1, 1]])" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# resta de matrices\n", "A - B" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[2, 6, 4],\n", " [2, 0, 0],\n", " [2, 4, 4]])" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# multiplicando matrices por escalares\n", "A * 2" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 3, 0, 15],\n", " [21, 15, 0],\n", " [ 6, 3, 3]])" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "B * 3" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(3, 3)" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# ver la dimension de una matriz\n", "A.shape" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "9" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# ver cantidad de elementos de una matriz\n", "A.size" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Multiplicacion o Producto de matrices\n", "\n", "La regla para la [multiplicación de matrices](https://es.wikipedia.org/wiki/Multiplicaci%C3%B3n_de_matrices) generaliza la idea del [producto interior](https://es.wikipedia.org/wiki/Producto_escalar) que vimos con los [vectores](http://es.wikipedia.org/wiki/Vector); y esta diseñada para facilitar las operaciones lineales básicas.\n", "Cuando [multiplicamos matrices](https://es.wikipedia.org/wiki/Multiplicaci%C3%B3n_de_matrices), el número de columnas de la primera matriz debe ser igual al número de filas de la segunda matriz; y el resultado de esta multiplicación va a tener el mismo número de filas que la primer matriz y el número de la columnas de la segunda matriz. Es decir, que si yo tengo una matriz A de dimensión 3x4 y la multiplico por una matriz B de dimensión 4x2, el resultado va a ser una matriz C de dimensión 3x2.\n", "\n", "Algo a tener en cuenta a la hora de [multiplicar matrices](https://es.wikipedia.org/wiki/Multiplicaci%C3%B3n_de_matrices) es que la propiedad [connmutativa](https://es.wikipedia.org/wiki/Conmutatividad) no se cumple. AxB no es lo mismo que BxA.\n", "\n", "Veamos los ejemplos en [Python](http://python.org/)." ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 1, 2, 3, 4],\n", " [ 5, 6, 7, 8],\n", " [ 9, 10, 11, 12]])" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Ejemplo multiplicación de matrices\n", "A = np.arange(1, 13).reshape(3, 4) #matriz de dimension 3x4\n", "A" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[0, 1],\n", " [2, 3],\n", " [4, 5],\n", " [6, 7]])" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "B = np.arange(8).reshape(4,2) #matriz de dimension 4x2\n", "B" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 40, 50],\n", " [ 88, 114],\n", " [136, 178]])" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Multiplicando A x B\n", "A.dot(B) #resulta en una matriz de dimension 3x2" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false }, "outputs": [ { "ename": "ValueError", "evalue": "shapes (4,2) and (3,4) not aligned: 2 (dim 1) != 3 (dim 0)", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# Multiplicando B x A\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mB\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mA\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mValueError\u001b[0m: shapes (4,2) and (3,4) not aligned: 2 (dim 1) != 3 (dim 0)" ] } ], "source": [ "# Multiplicando B x A\n", "B.dot(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Este ultimo ejemplo vemos que la propiedad conmutativa no se cumple, es más, [Python](http://python.org/) nos arroja un error, ya que el número de columnas de B no coincide con el número de filas de A, por lo que ni siquiera se puede realizar la multiplicación de B x A.\n", "\n", "Para una explicación más detallada del proceso de [multiplicación de matrices](https://es.wikipedia.org/wiki/Multiplicaci%C3%B3n_de_matrices), pueden consultar el siguiente [tutorial](http://www.mathsisfun.com/algebra/matrix-multiplying.html)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### La matriz identidad, la matriz inversa, la matrix transpuesta y el determinante\n", "\n", "La [matriz identidad](https://es.wikipedia.org/wiki/Matriz_identidad) es el elemento neutro en la [multiplicación de matrices](https://es.wikipedia.org/wiki/Multiplicaci%C3%B3n_de_matrices), es el equivalente al número 1. Cualquier matriz multiplicada por la [matriz identidad](https://es.wikipedia.org/wiki/Matriz_identidad) nos da como resultado la misma matriz. La [matriz identidad](https://es.wikipedia.org/wiki/Matriz_identidad) es una [matriz cuadrada](https://es.wikipedia.org/wiki/Matriz_cuadrada) (tiene siempre el mismo número de filas que de columnas); y su diagonal principal se compone de todos elementos 1 y el resto de los elementos se completan con 0. Suele representase con la letra I\n", "\n", "Por ejemplo la matriz identidad de 3x3 sería la siguiente:\n", "\n", "$$I=\\begin{bmatrix}1 & 0 & 0 & \\\\0 & 1 & 0\\\\ 0 & 0 & 1\\end{bmatrix}$$\n", "\n", "Ahora que conocemos el concepto de la [matriz identidad](https://es.wikipedia.org/wiki/Matriz_identidad), podemos llegar al concepto de la [matriz inversa](https://es.wikipedia.org/wiki/Matriz_invertible). Si tenemos una matriz A, la [matriz inversa](https://es.wikipedia.org/wiki/Matriz_invertible) de A, que se representa como $A^{-1}$ es aquella [matriz cuadrada](https://es.wikipedia.org/wiki/Matriz_cuadrada) que hace que la multiplicación $A$x$A^{-1}$ sea igual a la [matriz identidad](https://es.wikipedia.org/wiki/Matriz_identidad) I. Es decir que es la matriz recíproca de A.\n", "\n", "$$A × A^{-1} = A^{-1} × A = I$$\n", "\n", "Tener en cuenta que esta [matriz inversa](https://es.wikipedia.org/wiki/Matriz_invertible) en muchos casos puede no existir.En este caso se dice que la matriz es singular o degenerada. Una matriz es singular si y solo si su determinante es nulo.\n", "\n", "El determinante es un número especial que puede calcularse sobre las [matrices cuadradas](https://es.wikipedia.org/wiki/Matriz_cuadrada). Se calcula como la suma de los productos de las diagonales de la matriz en una dirección menos la suma de los productos de las diagonales en la otra dirección. Se represente con el símbolo |A|.\n", "\n", "$$A=\\begin{bmatrix}a_{11} & a_{12} & a_{13} & \\\\a_{21} & a_{22} & a_{23} & \\\\ a_{31} & a_{32} & a_{33} & \\end{bmatrix}$$\n", "\n", "$$|A| = \n", " (a_{11} a_{22} a_{33} \n", " + a_{12} a_{23} a_{31} \n", " + a_{13} a_{21} a_{32} )\n", " - (a_{31} a_{22} a_{13} \n", " + a_{32} a_{23} a_{11} \n", " + a_{33} a_{21} a_{12})\n", " $$\n", "\n", "Por último, la [matriz transpuesta](http://es.wikipedia.org/wiki/Matriz_transpuesta) es aquella en que las filas se transforman en columnas y las columnas en filas. Se representa con el símbolo $A^\\intercal$\n", "\n", "$$\\begin{bmatrix}a & b & \\\\c & d & \\\\ e & f & \\end{bmatrix}^T:=\\begin{bmatrix}a & c & e &\\\\b & d & f & \\end{bmatrix}$$\n", "\n", "Ejemplos en [Python](http://python.org/):" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 1., 0.],\n", " [ 0., 1.]])" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Creando una matriz identidad de 2x2\n", "I = np.eye(2)\n", "I" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[4, 7],\n", " [2, 6]])" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Multiplicar una matriz por la identidad nos da la misma matriz\n", "A = np.array([[4, 7],\n", " [2, 6]])\n", "A" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 4., 7.],\n", " [ 2., 6.]])" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.dot(I) # AxI = A" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "10.000000000000002" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Calculando el determinante de la matriz A\n", "np.linalg.det(A)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 0.6, -0.7],\n", " [-0.2, 0.4]])" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Calculando la inversa de A.\n", "A_inv = np.linalg.inv(A)\n", "A_inv" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 1., 0.],\n", " [ 0., 1.]])" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# A x A_inv nos da como resultado I.\n", "A.dot(A_inv)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[0, 1],\n", " [2, 3],\n", " [4, 5]])" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Trasponiendo una matriz\n", "A = np.arange(6).reshape(3, 2)\n", "A" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[0, 2, 4],\n", " [1, 3, 5]])" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.transpose(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sistemas de ecuaciones lineales\n", "\n", "Una de las principales aplicaciones del [Álgebra lineal](http://es.wikipedia.org/wiki/%C3%81lgebra_lineal) consiste en resolver problemas de sistemas de ecuaciones lineales.\n", "\n", "Una [ecuación lineal](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_de_primer_grado) es una ecuación que solo involucra sumas y restas de una variable o mas variables a la primera potencia. Es la ecuación de la línea recta.Cuando nuestro problema esta representado por más de una [ecuación lineal](https://es.wikipedia.org/wiki/Ecuaci%C3%B3n_de_primer_grado), hablamos de un [sistema de ecuaciones lineales](http://es.wikipedia.org/wiki/Sistema_de_ecuaciones_lineales). Por ejemplo, podríamos tener un sistema de dos ecuaciones con dos incógnitas como el siguiente:\n", "\n", "$$ x - 2y = 1$$ \n", "$$3x + 2y = 11$$\n", "\n", "La idea es encontrar el valor de $x$ e $y$ que resuelva ambas ecuaciones. Una forma en que podemos hacer esto, puede ser representando graficamente ambas rectas y buscar los puntos en que las rectas se cruzan. \n", "\n", "En [Python](http://python.org/) esto se puede hacer en forma muy sencilla con la ayuda de [matplotlib](http://matplotlib.org/)." ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(0.0, 5.0, 0, 6.0)" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\nO8OZBWBn2gAAAABJRU5ErkJggg==\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# graficando el sistema de ecuaciones.\n", "x_vals = np.linspace(0, 5, 50) # crea 50 valores entre 0 y 5\n", "plt.plot(x_vals, (1 - x_vals)/-2) # grafica x - 2y = 1\n", "plt.plot(x_vals, (11 - (3*x_vals))/2) # grafica 3x + 2y = 11\n", "plt.axis(ymin = 0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Luego de haber graficado las funciones, podemos ver que ambas rectas se cruzan en el punto (3, 1), es decir que la solución de nuestro sistema sería $x=3$ e $y=1$. En este caso, al tratarse de un sistema simple y con solo dos incógnitas, la solución gráfica puede ser de utilidad, pero para sistemas más complicados se necesita una solución numérica, es aquí donde entran a jugar las matrices.\n", "\n", "Ese mismo sistema se podría representar como una ecuación matricial de la siguiente forma:\n", "\n", "$$\\begin{bmatrix}1 & -2 & \\\\3 & 2 & \\end{bmatrix} \\begin{bmatrix}x & \\\\y & \\end{bmatrix} = \\begin{bmatrix}1 & \\\\11 & \\end{bmatrix}$$\n", "\n", "Lo que es lo mismo que decir que la matriz A por la matriz $x$ nos da como resultado el [vector](http://es.wikipedia.org/wiki/Vector) b.\n", "\n", "$$ Ax = b$$\n", "\n", "En este caso, ya sabemos el resultado de $x$, por lo que podemos comprobar que nuestra solución es correcta realizando la [multiplicación de matrices](https://es.wikipedia.org/wiki/Multiplicaci%C3%B3n_de_matrices)." ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 1.],\n", " [ 11.]])" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Comprobando la solucion con la multiplicación de matrices.\n", "A = np.array([[1., -2.],\n", " [3., 2.]])\n", "x = np.array([[3.],[1.]])\n", "\n", "A.dot(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para resolver en forma numérica los [sistema de ecuaciones](http://es.wikipedia.org/wiki/Sistema_de_ecuaciones_lineales), existen varios métodos:\n", "\n", "* **El método de sustitución**: El cual consiste en despejar en una de las ecuaciones cualquier incógnita, preferiblemente la que tenga menor coeficiente y a continuación sustituirla en otra ecuación por su valor.\n", "\n", "* **El método de igualacion**: El cual se puede entender como un caso particular del método de sustitución en el que se despeja la misma incógnita en dos ecuaciones y a continuación se igualan entre sí la parte derecha de ambas ecuaciones.\n", "\n", "* **El método de reduccion**: El procedimiento de este método consiste en transformar una de las ecuaciones (generalmente, mediante productos), de manera que obtengamos dos ecuaciones en la que una misma incógnita aparezca con el mismo coeficiente y distinto signo. A continuación, se suman ambas ecuaciones produciéndose así la reducción o cancelación de dicha incógnita, obteniendo una ecuación con una sola incógnita, donde el método de resolución es simple.\n", "\n", "* **El método gráfico**: Que consiste en construir el gráfica de cada una de las ecuaciones del sistema. Este método (manualmente aplicado) solo resulta eficiente en el plano cartesiano (solo dos incógnitas).\n", "\n", "* **El método de Gauss**: El método de eliminación de Gauss o simplemente método de Gauss consiste en convertir un sistema lineal de n ecuaciones con n incógnitas, en uno escalonado, en el que la primera ecuación tiene n incógnitas, la segunda ecuación tiene n - 1 incógnitas, ..., hasta la última ecuación, que tiene 1 incógnita. De esta forma, será fácil partir de la última ecuación e ir subiendo para calcular el valor de las demás incógnitas.\n", "\n", "* **El método de Eliminación de Gauss-Jordan**: El cual es una variante del método anterior, y consistente en triangular la matriz aumentada del sistema mediante transformaciones elementales, hasta obtener ecuaciones de una sola incógnita.\n", "\n", "* **El método de Cramer**: El cual consiste en aplicar la [regla de Cramer](http://es.wikipedia.org/wiki/Regla_de_Cramer) para resolver el sistema. Este método solo se puede aplicar cuando la matriz de coeficientes del sistema es cuadrada y de determinante no nulo.\n", "\n", "La idea no es explicar cada uno de estos métodos, sino saber que existen y que [Python](http://python.org/) nos hacer la vida mucho más fácil, ya que para resolver un [sistema de ecuaciones](http://es.wikipedia.org/wiki/Sistema_de_ecuaciones_lineales) simplemente debemos llamar a la función `solve()`.\n", "\n", "Por ejemplo, para resolver este sistema de 3 ecuaciones y 3 incógnitas.\n", "\n", "$$ x + 2y + 3z = 6$$\n", "$$ 2x + 5y + 2z = 4$$\n", "$$ 6x - 3y + z = 2$$\n", "\n", "Primero armamos la matriz A de coeficientes y la matriz b de resultados y luego utilizamos `solve()` para resolverla." ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 1, 2, 3],\n", " [ 2, 5, 2],\n", " [ 6, -3, 1]])" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Creando matriz de coeficientes\n", "A = np.array([[1, 2, 3],\n", " [2, 5, 2],\n", " [6, -3, 1]])\n", "A" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([6, 4, 2])" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Creando matriz de resultados\n", "b = np.array([6, 4, 2])\n", "b" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 0., 0., 2.])" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Resolviendo sistema de ecuaciones\n", "x = np.linalg.solve(A, b)\n", "x" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ True, True, True], dtype=bool)" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Comprobando la solucion\n", "A.dot(x) == b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Programación lineal\n", "\n", "La [programación lineal](http://es.wikipedia.org/wiki/Programaci%C3%B3n_lineal) estudia las situaciones en las que se exige maximizar o minimizar funciones que se encuentran sujetas a determinadas restricciones.\n", "\n", "Consiste en optimizar (minimizar o maximizar) una función lineal, denominada función objetivo, de tal forma que las variables de dicha función estén sujetas a una serie de restricciones que expresamos mediante un [sistema de inecuaciones lineales](http://es.wikipedia.org/wiki/Inecuaci%C3%B3n#Sistema_de_inecuaciones).\n", "\n", "Para resolver un problema de programación lineal, debemos seguir los siguientes pasos:\n", "\n", "1. Elegir las incógnitas.\n", "\n", "2. Escribir la función objetivo en función de los datos del problema.\n", "\n", "3. Escribir las restricciones en forma de sistema de inecuaciones.\n", "\n", "4. Averiguar el conjunto de soluciones factibles representando gráficamente las restricciones.\n", "\n", "5. Calcular las coordenadas de los vértices del recinto de soluciones factibles (si son pocos).\n", "\n", "6. Calcular el valor de la función objetivo en cada uno de los vértices para ver en cuál de ellos presenta el valor máximo o mínimo según nos pida el problema (hay que tener en cuenta aquí la posible no existencia de solución).\n", "\n", "Veamos un ejemplo y como [Python](http://python.org/) nos ayuda a resolverlo en forma sencilla.\n", "\n", "Supongamos que tenemos la siguiente *función objetivo*:\n", "\n", "$$f(x_{1},x_{2})= 50x_{1} + 40x_{2}$$\n", "\n", "y las siguientes *restricciones*:\n", "\n", "$$x_{1} + 1.5x_{2} \\leq 750$$\n", "$$2x_{1} + x_{2} \\leq 1000$$\n", "$$x_{1} \\geq 0$$\n", "$$x_{2} \\geq 0$$\n", "\n", "Podemos resolverlo utilizando [PuLP](http://pythonhosted.org//PuLP/), [CVXOPT](http://cvxopt.org/) o graficamente (con [matplotlib](http://matplotlib.org/)) de la siguiente forma." ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(375.0, 250.0)" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Resolviendo la optimizacion con pulp\n", "from pulp import *\n", "\n", "# declarando las variables\n", "x1 = LpVariable(\"x1\", 0, 800) # 0<= x1 <= 40\n", "x2 = LpVariable(\"x2\", 0, 1000) # 0<= x2 <= 1000\n", "\n", "# definiendo el problema\n", "prob = LpProblem(\"problem\", LpMaximize)\n", "\n", "# definiendo las restricciones\n", "prob += x1+1.5*x2 <= 750 \n", "prob += 2*x1+x2 <= 1000\n", "prob += x1>=0\n", "prob += x2>=0\n", "\n", "# definiendo la funcion objetivo a maximizar\n", "prob += 50*x1+40*x2\n", "\n", "# resolviendo el problema\n", "status = prob.solve(GLPK(msg=0))\n", "LpStatus[status]\n", "\n", "# imprimiendo los resultados\n", "(value(x1), value(x2))" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " pcost dcost gap pres dres k/t\n", " 0: -2.5472e+04 -3.6797e+04 5e+03 0e+00 3e-01 1e+00\n", " 1: -2.8720e+04 -2.9111e+04 1e+02 3e-16 9e-03 2e+01\n", " 2: -2.8750e+04 -2.8754e+04 1e+00 3e-16 9e-05 2e-01\n", " 3: -2.8750e+04 -2.8750e+04 1e-02 2e-16 9e-07 2e-03\n", " 4: -2.8750e+04 -2.8750e+04 1e-04 3e-16 9e-09 2e-05\n", "Optimal solution found.\n" ] } ], "source": [ "# Resolviendo el problema con cvxopt\n", "from cvxopt import matrix, solvers\n", "\n", "A = matrix([[-1., -2., 1., 0.], # columna de x1\n", " [-1.5, -1., 0., 1.]]) # columna de x2\n", "b = matrix([750., 1000., 0., 0.]) # resultados\n", "c = matrix([50., 40.]) # funcion objetivo\n", "\n", "# resolviendo el problema\n", "sol=solvers.lp(c,A,b)" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "375.00, 250.00\n" ] } ], "source": [ "# imprimiendo la solucion.\n", "print('{0:.2f}, {1:.2f}'.format(sol['x'][0]*-1, sol['x'][1]*-1))" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(0.0, 800.0, 0, 1000.0)" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYEAAAEACAYAAABVtcpZAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAHU9JREFUeJzt3XuwnHWd5/H3BxLuaIhiCBArWbkMcUBFuaygiQgRlEuo\nQSAGZWC8FTOC5QokrLPNU6WziLrqzgiOIJYgRCEwQIZruETYVUC5LIEQQoCoQQiMiDoMDIF894/f\nc0zncHJy0qe7f0/383lVpU53n+5+vjmp9Oc8148iAjMzq6dNcg9gZmb5OATMzGrMIWBmVmMOATOz\nGnMImJnVmEPAzKzGhg0BSRdJWiVpcdNj4yUtlLRM0s2SxjV9b66kxyQtlTSj6fF3S1pcfu/bnfmr\nmJnZxtrQmsAPgEMHPTYHWBgRuwG3lveRNBU4DphavuY8SSpfcz7wNxGxK7CrpMHvaWZmGQwbAhFx\nJ/D7QQ8fCfywvP1DYGZ5+yhgXkSsjogVwHJgP0kTgW0j4p7yeRc3vcbMzDJqZZ/AhIhYVd5eBUwo\nb+8IrGx63kpgpyEef6p83MzMMhvVjuFI15zwdSfMzHrUmBZes0rSDhHxTLmp59ny8aeASU3P25m0\nBvBUebv58aeGemNJDhQzsxZEhDb8rKFfOOwfYDKwuOn+ucCZ5e05wDnl7anAA8BmwBTgcUDl9+4G\n9gMEXA8cup5lBWfzDGczc0Nz5fwDnJ17hn6Zsxdm9Jyes+p/KDfMtPJnQ4eIzgN+Buwu6TeSTgLO\nAQ6RtAw4qLxPRCwBLgeWADcAp0Q5HXAKcCHwGLA8Im4cZrGHA99ToQ8ON5uZmY3esJuDImLWer51\n8Hqe/w/APwzx+L3AniMZKBrxSxX6KDBfhY6IRtw1kteZmdnGq+QZw9GInwJ/DVyjQntlHmcoi3IP\nMEKLcg8wAotyDzBCi3IPMEKLcg8wQotyDzBCi3IP0Glau8UmP0kRTTs3VOh44BvAtGjE8nyTmZlV\n1+DPzo1RyTWBAdGIHwMFsFCFdt7Q883MbONUOgQAohHfA84jBcH2uecxM+snlQ8BgGjE14CrgBtV\n6I255zEz6xc9EQKlLwF3AQtUaKvcw5iZ9YNK7xh+3fcLbUK6aN2bgJnRiFe6NpyZWUX17Y7hwaIR\na4CTgdXAJSq0aeaRzMx6Wk+FAEA0YjWpt2B74Lsq1Nr1MszMrPdCACAa8TKpv2Av4GsOAjOz1vRk\nCABEI/4EHAZ8CDgr8zhmZj2pZ0MAIBrxPDADOEmF/i73PGZmvaanQwAgGvE0cAhwpgp9Ivc8Zma9\npOdDACAa8SRps9C5KuT+YjOzEeqLEACIRizBXQRmZhulb0IAUhcB8FHgxyq0f+55zMyqrq9CAHqi\ni8DMrDL6LgQAohHXAacBN6jQLrnnMTOrqr4MAXAXgZnZSPRtCIC7CMzMNqSvQwDcRWBmNpy+D4GS\nuwjMzIbQU30Co3pvdxGYWZ+qTZ/AaLiLwMzs9WoTAuAuAjOzwWoVAuAuAjOzZrULAXAXgZnZgFqG\nALiLwMwMahwC4C4CM7NahwC4i8DM6q32IQDuIjCz+nIIlNxFYGZ15BBo4i4CM6sbh8Ag7iIwszpx\nCAzBXQRmVhcOgfVwF4GZ1UHLISBprqSHJS2WdJmkzSWNl7RQ0jJJN0saN+j5j0laKmlGe8bvLHcR\nmFm/aykEJE0GPgXsHRF7ApsCxwNzgIURsRtwa3kfSVNJF26bChwKnCepV9ZC3EVgZn2r1Q/iP5Iu\nybyVpDHAVsBvgSNJ1+yn/Dpw8tVRwLyIWB0RK4DlwL6tDt1N0YgAPgf8CpivQptlHsnMrG1aCoGI\neB74BvBr0of/CxGxEJgQEavKp60CJpS3dwRWNr3FSmCnlibOYFAXwcXuIjCzfjGmlRdJehvweWAy\n8AfgCkknND8nIkLScLVlQ35P0tlNdxdFxKJWZmy3aMRqFToOuB44X4U+U64lmJl1laTpwPS2vFcr\n9ZKSjgMOiYhPlvc/DuwPHAR8ICKekTQRuD0i/kLSHICIOKd8/o1AIyLuHvS+HauXbBcV2ha4BbgD\nOMNBYGa55aiXXArsL2lLSQIOBpYAC4ATy+ecCFxd3r4WOF7SZpKmALsC97S47KyauggOBeZmHsfM\nbFRaLpqXdAbpg34NcB/wSWBb4HLgrcAK4NiIeKF8/lmk7eqvAqdFxE1DvGfl1wQGqNBE4E7gm9GI\n7+Sex8zqazSfnS2HQCf0UggAqNAU0mahudGIH+Wex8zqKcfmIGOdLoKvq9BRuecxM9tYDoFRauoi\nuMBdBGbWaxwCbdDURTBPhfbLPY+Z2Ug5BNqk7CI4CbhWhfbMPY+Z2Ug4BNqoqYvgRncRmFkvcAi0\nmbsIzKyXOAQ6wF0EZtYrHAId4i4CM+sFDoHOcheBmVWazxjuMBXahNSt8CZgZjTilcwjmVmf8RnD\nFeYuAjOrModAF0QjVpPqNd9C6iLoq7UdM+tdDoEuiUa8TKrZfAdwroPAzKrAIdBF7iIws6pxCHRZ\nNOJ5YAZwsgr9be55zKzeHAIZRCOeBg4B5qhYt5vZzKybHAKZuIvAzKrAIZCRuwjMLDeHQGbuIjCz\nnBwCFeAuAjPLxSFQEe4iMLMcHAIV4i4CM+s2h0DFuIvAzLrJIVBB7iIws25xCFSXuwjMrOPcJ1Bh\n7iIws5Fwn0CfcheBmXWaQ6Di3EVgZp3kEOgB7iIws05xCPSIQV0EZ2Uex8z6hEOghzR1EZzkLgIz\naweHQI9xF4GZtZNDoAe5i8DM2sUh0KPcRWBm7eAQ6GHuIjCz0Wo5BCSNkzRf0iOSlkjaT9J4SQsl\nLZN0s6RxTc+fK+kxSUslzWjP+OYuAjMbjdGsCXwbuD4i9gD2ApYCc4CFEbEbcGt5H0lTSSc8TSUd\n4nieJK+FtIm7CMysVS19EEt6I/C+iLgIICJejYg/AEeSrnVD+XVmefsoYF5ErI6IFcByYN/RDG7r\ncheBmbWi1d/GpwDPSfqBpPskXSBpa2BCRKwqn7MKmFDe3hFY2fT6lcBOLS7b1sNdBGa2sVoNgTHA\n3sB5EbE38CLlpp8BkS5POtwlSqtz+dI+4i4CM9sYY1p83UpgZUT8orw/H5gLPCNph4h4RtJE4Nny\n+08Bk5pev3P52OtIOrvp7qKIWNTijHX2JWAcqYvg0GjEf+QeyMzaR9J0YHpb3qvVPgFJdwCfjIhl\n5Qf3QPHJ7yLiq5LmAOMiYk65Y/gy0n6AnYBbgF1i0MLdJ9A+7iIwq4/RfHaOJgTeAVwIbAY8TjpM\ncVPgcuCtwArg2Ih4oXz+WaRr478KnBYRNw3xng6BNlKhsaS1tJeA2dGI1zKPZGYdkCUEOsEh0H4q\ntAVwPemIrM9Eo0L/4GbWFm4Ws/VyF4GZDcchUAODugjmZh7HzCrEIVATTV0EJ7uLwMwGOARqxF0E\nZjaYQ6Bm3EVgZs0cAjXkLgIzG+AQqCl3EZgZOARqzV0EZuYQqDl3EZjVm0PA3EVgVmMOAQPcRWBW\nVw4B+zN3EZjVj0PABvsScBepi2CrDT3ZzHqbryJqr+MuArPe4quIWltFI9aQuh9WAxer0KaZRzKz\nDnEI2JCiEauB44C3AOf7EtRm/ckhYOvlLgKz/ucQsGG5i8Csv1UuBCRulThZwocoVoS7CMz6V+VC\nADgfOAL4tcR8iaMlNs89VN25i8CsP1X2EFGJ7YBjgNnAnqSTmC4F7ohgTb4p602FpgK3kUrrr8k9\nj5mN7hDRyobAuo8zCZhFCoTxwDxSIDwYQXX+AjWhQu8BrgdmRSNuzT2PWd31fQis+xz+khQGHwP+\nRAqDyyL4VRdGtJIKTQOuAI6IRtydex6zOqtVCKx9LpsAB5AC4RjgEVIgXBHB7zo3pQ1QoY8AFwEH\nRyMW557HrK5qGQLrvo7NSIcwzi6//hT4EbAggpfaO6U1U6HjgW8A06IRy3PPY1ZHtQ+Bdd+DNwBH\nkwJhH+Aa0hrCbRG8NvopbTAV+jTpHIL3RSNW5p7HrG4cAut9PyaSLn0wG9gZ+DEpEO71DuX2UqHT\nSdcben804rnc85jViUNgRO/N7qSdybOB10hhcGkEj3dieXWkQl8hbY47KBrxh9zzmNWFryI6AhE8\nGkED2BX4BPBm4GcSd0l8TuIteSfsC+4iMOsxtVkTGHp5jAEOJq0dHAH8nLSGcHUE/96tOfqJuwjM\nus+bg9qybLYGjiQFwoGkk6EuBW6OYHWOmXqVCo0F5gMvAbOjEd4hb9ZBDoG2z8H2wEdJgbAr6aSo\nS4Gfe4fyyKjQFqQgXU66xIR/bmYd4hDoIIkprN2hvDlwGWmH8tKsg/UAFdoWuAW4AzjDQWDWGd4x\n3EERPBnBV4C3k85M3hK4VeJeiS9I7Jh3wupyF4FZ9XlNoAUSmwLTgBOAmcB9pM1FV0XgQyMHUaGJ\nwJ3AN6MR38k9j1m/8eagjCS2AA4nbS46CLiZFAg3RPCfOWerEhWaQtosNDca8aPc85j1k2ybgyRt\nKul+SQvK++MlLZS0TNLNksY1PXeupMckLZU0YzTLrZIIXo5gfgRHA5NJIfB54LcS35OYVl7srtai\nEU8CHwK+rkJH5Z7HzJLRfjidBiyBPx8xMwdYGBG7AbeW95E0lXT5hqmk7cPnSeq7D8YIfh/BBRFM\nB95JOjLmfwMrJL4qsVfWATOLRiwhrTVdoEIfzD2PmY0iBCTtDHwYuBAYWA05knSiEOXXmeXto4B5\nEbE6IlaQPhz3bXXZvSCC30RwbgTvIP2c1gALJBZLzJF4a+YRs4hG/JJ0+O08Fdov9zxmdTea38a/\nCZwO61Q9ToiIVeXtVcCE8vaOQPPVJVcCO41i2T0lgocimAtMAU4hbTa6T+IOic9IjM86YJdFI34K\nnARcq0J75p7HrM5aCgFJhwPPRsT9rF0LWEekPc7D7XWuzh7pLolgTQR3RvBZUjB+nbQz+QmJaySO\nldgy75TdEY24DjgVuFGFdsk9j1ldjWnxde8FjpT0YWAL4A2SLgFWSdohIp6RNBF4tnz+U8Ckptfv\nXD72OpLObrq7KCIWtThjpUXwCnAtcG1TB8IngX+W6tGBEI34iQq9AVioQu4iMBshSdOB6W15r9Ee\nIippGvDFiDhC0rnA7yLiq5LmAOMiYk65Y/gy0n6AnUhnke4Sgxbei4eItlsdOxBU6IvA3+AuArOW\nVOGM4YEPp3OAQyQtI23mOAcgIpYAl5OOJLoBOGVwAFgSwdMRfCuCfUhJ/0dSEDwi8T8k3pZ1wA6I\nRnwduJK0aeiNuecxqxOfLNYDJERai5pNWkt4krR28JOIP29y62kqJOAfgb2AQ6MR/5F5JLOe4TOG\na6SfOxDcRWDWGodATZUdCEeRAuEA+qADQYXGkLoIXsZdBGYj4hCwgQ6EY0mBsAs93IFQdhFcBzyO\nuwjMNsghYOuQ+C8M3YHwSNbBNkLZRbCQdPVRdxGYDaMKRwdZhUTwRARfJl2rqbkD4T6J/9YLHQhl\nF8GHcReBWUd5TaAmyg6E6aS1g5nA/aTNRVdWuQPBXQRmG+bNQbZRyktTfIS1HQgLSYFwfRU7EFRo\nMikI3EVgNgSHgLVMYjvSJqPZwJ7AVaRAuCNinYsDZqVCewC3AZ+NRlyTex6zKnEIWFtITAJmkQJh\nPDAP+FEED2YdrKRC7yadcT4rGnFr7nnMqsIhYG0n8ZekMPgY6dIVlwLzIvhV1rkKvZ90HsER0Yi7\nc85iVhUOAeuYshrzAFIgHEO6/tOlwBURPJ9lpkIfBi4CDolGLM4xg1mVOASsKyQ2Ix2yObv8uogU\nCAsieKmrsxQ6DvhfwLRoxPJuLtusahwC1nVNHQizgX2g+x0IKvQp4CzAXQRWaw4ByypnB4K7CMwc\nAlYhEruz9pIVr5HC4NIIHu/YMgt9GTgMOCgaUdkT38w6xZeNsMqI4NEIGsCuwCeANwM/k7hL4nMS\nb+nAYv+edEntBSq0VQfe36xveU3AOk5iLGs7EA6nAx0I7iKwOvPmIOsZnexAcBeB1ZVDwHpSJzoQ\n3EVgdeQQsJ7Xzg4EdxFY3XjHsPW8dnYguIvAbOS8JmCVNdoOBHcRWF14c5D1vVY7ENxFYHXgELBa\n2dgOBHcRWL9zCFhtjbQDwV0E1s8cAmYM2YFwGXDZQAeCuwisXzkEzJoM14HA2dofdxFYn3EImK3H\nkB0IR3zqCfb+/rEo3EVgfcHnCZitRwSvRHBtBMcBk4CrWHDB27nuO+N4cfv7tcfVs8pDUc1qyWsC\nVksSE/mrWd9l57tncOHP/8iLEy6jSx0IZu3mzUFmLVKhL7N6y5n846P/yh8nHUOXOhDM2smbg8xa\n9/eMfWkRX3jre/nihL3oXgeCWSV4TcBqb6gugm50IJi1izcHmY3ScF0EnexAMGsHh4BZG4yki6AT\nHQhmo+UQMGuTjekiaGcHgtlodH3HsKRJkm6X9LCkhySdWj4+XtJCScsk3SxpXNNr5kp6TNJSSTNa\nWa5Zpw3qIjhr2Oe2sQPBLJeW1gQk7QDsEBEPSNoGuJd0vfeTgH+LiHMlnQlsFxFzJE0l/Za0D7AT\ncAuwW0SsGfS+XhOwSmjqIvhWNOKfRvy6UXYgmLWi62sCEfFMRDxQ3v534BHSh/uRpKMsKL/OLG8f\nBcyLiNURsQJYDuzbyrLNuiEa8TTp6KAzVegTI35d8FoEt0ZwMun/xPnAEcCvJeZLHC2xeWemNtt4\noz5PQNJk4F3A3cCEiFhVfmsVMKG8vSOwsullK0n/QcwqKxqxApgBfFWFZm7g6a9/ffBSBPMjOBqY\nDNwEnAb8VuICienlxe7MshkzmheXm4KuBE6LiD9Ja9dGIiIkDbetacjvSTq76e6iiFg0mhnNRiMa\n8YgKHQ7coEJ/arWLIILfAxcAFzR1IHwbGC8N3YFgtj6SppM2O47+vVo9OkjSWOBfgRsi4lvlY0uB\n6RHxjKSJwO0R8ReS5gBExDnl824EGhHrXtPd+wSsqsougitJXQR3te19X9+BcCkwb6ADwWwkchwd\nJOD7wJKBAChdC5xY3j4RuLrp8eMlbSZpCrArcE8ryzbLIRpxB/DXwDUqtFfb3jd4KIK5wBTgFNJm\no3sl7pD4jMT4di3LbCitHh10IHAH8CBrN+vMJX2wXw68FVgBHBsRL5SvOQs4GXiVtPnopiHe12sC\nVmkqdDzwDaBjXQRDdiCkNYQFEbzUiWVab/PJYmZdpEKfJv3S875oxMoNPX9UyxJvAI4mBcI+wDWk\nQLgtgteGe63Vh0PArMtU6HTSmu37oxHPdWWZYiJwHCkQdgZ+jDsQDIeAWRYq9BXS5pqDohFdPRFM\nYnfWXrLCHQg15z4Bszy+BNwFLFChrbq54AgejaBBOsjCHQjWMq8JmI3CUF0E2WYRY1jbgXAE7kCo\nDW8OMstIhcaytovgY81dBLmUHQhHkgLhQNyB0NccAmaZlV0E15O6CD493CWou63sQPgoKRB2xR0I\nfcchYFYBZRfBLaSrj55epSAYIDGFtTuUt8AdCH3BO4bNKqDsIjgM+BAb6CLIJYInI/gK8Hbgr0hB\ncIs7EOrLawJmbdZqF0EuZQfCNNLawdG4A6HneHOQWcWo0BTSpVX+ezTi4tzzjJTEFsDhpEA4iFS1\neSlwfQT/mXM2Wz+HgFkFqdBU4Dbgs9GIqzf0/KqR2I5Umzkb2BO4ihQId0SwZrjXWnc5BMwqSoXe\nQzpqaFarXQRV0NSBMBsYD+5AqBKHgFmFqdA00nkEbe0iyMUdCNXjEDCrOBX6CHARcEg0oi9+ey6r\nMQ8gBcIxwBJSIFwRwfM5Z6sbh4BZD2jqIpgejXgs9zzt5A6EvBwCZj2im10EubgDofscAmY9JEcX\nQS7uQOgOh4BZj8nZRZCLOxA6x5eNMOs92boIcnEHQjV5TcAskyp1EeTiDoT28OYgsx5VxS6CXNyB\n0DqHgFkPq3IXQS7uQNg4DgGzHtcLXQS5uANhw7xj2KzH9UIXQS7uQOgsrwmYVUivdRHk0tSBcAIw\nk5p3IHhzkFkf6dUuglzcgeAQMOs7vd5FkEtdOxAcAmZ9qF+6CHKpUweCQ8CsT/VbF0Eu/d6B4BAw\n62P92EWQS792IDgEzPpcUxfBtGjE8tzz9IN+6kBwCJjVQB26CHLp9Q4Eh4BZTdSpiyCXXuxAcAiY\n1UgduwhyGaIDYeCSFZXaJOfLRpjVS+26CHIZogPhTcD/7acOhK6GgKRDJS2V9JikM7u5bLN+UV5c\n7nPAr4D5KrRZ5pH6XgQRwd0RnArsBJwN7Assk7hB4gSJbbIO2aKuhYCkTYF/Iq3GTgVmSdqjW8tv\nJ0nTc88wEr0wZy/MCNWbMxqxhrRvYDVwiQptCtWbc316ec4IXo3gxgg+TgqEi4HjgZUSl0l8RGJs\nl0dtWTfXBPYFlkfEiohYTdrZclQXl99O03MPMELTcw8wAtNzDzBC03MPMFg0YjVpB+b2wHdVSFRw\nzvWYnnuAEZo+3DcjeDGCeREcTtpk9H9IV4F9SuI7Eu+VqPR+zm6GwE7Ab5rurywfM7MWRSNeJv0y\ntRfwtczj1FoEz0VwXgQHAPsBvwUuBB6X+LJEJbd8dDMEqnMYklkfWaeLYA/el3seG1EHQmV+Ae7a\nIaKS9gfOjohDy/tzgTUR8dWm5zgozMxaUPnzBCSNAR4FPkhaTboHmBURrogzM8tkTLcWFBGvSvo7\n4CZgU+D7DgAzs7wqdcawmZl1VyXOGK7SSWSSLpK0StLipsfGS1ooaZmkmyWNa/re3HLupZJmdHHO\nSZJul/SwpIcknVrFWSVtIeluSQ9IWiLpf1ZxznK5m0q6X9KCCs+4QtKD5Zz3VHjOcZLmS3qk/Hff\nr2pzStq9/DkO/PmDpFOrNmfTch+WtFjSZZI2b9ucUZ4Kl+sPadPQcmAyMBZ4ANgj4zzvA94FLG56\n7FzgjPL2mcA55e2p5bxjy/mXA5t0ac4dgHeWt7ch7W/Zo6KzblV+HUO63MGBFZ3zC6QLhV1b4X/3\nJ4Hxgx6r4pw/BE5u+nd/YxXnbJp3E+BpYFLV5iyX9QSweXn/J8CJ7Zqzaz/kYf6C/xW4sen+HGBO\n5pkms24ILAUmlLd3AJaWt+cCZzY970Zg/0wzXw0cXOVZga2AX5AOm6vUnKSrRd4CfABYUNV/d1II\nvGnQY5Wak/SB/8QQj1dqzkGzzQDurOKcpGrMR4HtSIG6ADikXXNWYXNQL5xENiEiVpW3VwETyts7\nkuYdkGV2SZNJay93U8FZJW0i6YFyntsj4uEKzvlN4HRYp4y8ajNCOt/mFkm/lPSp8rGqzTkFeE7S\nDyTdJ+kCSVtXcM5mx5M6iKFic0bE86RCoV+Tjqx8ISIWtmvOKoRAT+2ZjhStw83c1b+PpG2AK4HT\nIuJP6wxSkVkjYk1EvJP02/b7JX1g0PezzinpcODZiLgfhj7FP/eMTQ6IiHeRTg77W0nrnBxWkTnH\nAHsD50XE3sCLpDX8tUNUY04AJG0GHAFc8bohKjCnpLcBnydtodgR2EbSCesMMYo5qxACT5G2ww2Y\nxLopVgWrJO0AIGki8Gz5+ODZdy4f6wpJY0kBcElEXF3lWQEi4g/AdcC7Kzbne4EjJT1J+m3wIEmX\nVGxGACLi6fLrc8C/kK7JVbU5VwIrI+IX5f35pFB4pmJzDjgMuLf8mUL1fp7vAX4WEb+LiFeBq0ib\n0dvy86xCCPwS2FXS5DKRjwOuzTzTYNeSdsRQfr266fHjJW0maQrpAlL3dGMgSQK+DyyJiG9VdVZJ\nbx44akHSlqRtmfdXac6IOCsiJkXEFNJmgdsi4uNVmhFA0laSti1vb03ajr24anNGxDPAbyTtVj50\nMPAwaVt2ZeZsMou1m4IG5qnSnEuB/SVtWf6/PxhYQrt+nt3c+TLMjo/DSDs+lgNzM88yj7Td7RXS\nvoqTSDtmbgGWATcD45qef1Y591LgQ12c80DS9usHSB+q95Mu012pWYE9gfvKOR8ETi8fr9ScTcue\nxtqjgyo1I2lb+wPln4cG/q9Ubc5yue8gHQTw/0i/ub6xonNuDfwbsG3TY1Wc8wxSkC4mHXk1tl1z\n+mQxM7Maq8LmIDMzy8QhYGZWYw4BM7MacwiYmdWYQ8DMrMYcAmZmNeYQMDOrMYeAmVmN/X/IZroH\nMomzkwAAAABJRU5ErkJggg==\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Resolviendo la optimizacion graficamente.\n", "x_vals = np.linspace(0, 800, 10) # 10 valores entre 0 y 800\n", "plt.plot(x_vals, ((750 - x_vals)/1.5)) # grafica x1 + 1.5x2 = 750\n", "plt.plot(x_vals, (1000 - 2*x_vals)) # grafica 2x1 + x2 = 1000\n", "plt.axis(ymin = 0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Como podemos ver en el gráfico, ambas rectas se cruzan en la solución óptima, x1=375 y x2=250.\n", "\n", "Con esto termino esta introducción al [Álgebra lineal](http://es.wikipedia.org/wiki/%C3%81lgebra_lineal) con [Python](http://python.org/)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Espero que hayan disfurtado de este tutorial tanto como yo disfrute escribirlo!\n", "\n", "Saludos!\n", "\n", "*Este post fue escrito utilizando IPython notebook. Pueden descargar este [notebook](https://github.com/relopezbriega/relopezbriega.github.io/blob/master/downloads/LinearAlgebraPython.ipynb) o ver su version estática en [nbviewer](http://nbviewer.ipython.org/github/relopezbriega/relopezbriega.github.io/blob/master/downloads/LinearAlgebraPython.ipynb).*" ] } ], "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.4.3+" } }, "nbformat": 4, "nbformat_minor": 0 }