<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Método gráfico archivos &#187; Ingenieria Industrial Online</title>
	<atom:link href="https://ingenieriaindustrialonline.com/tag/metodo-grafico/feed/" rel="self" type="application/rss+xml" />
	<link>https://ingenieriaindustrialonline.com/tag/metodo-grafico/</link>
	<description>ingenieriaindustriaonline.com</description>
	<lastBuildDate>Tue, 14 Feb 2023 00:04:02 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>

<image>
	<url>https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/cropped-faVicon-32x32.png</url>
	<title>Método gráfico archivos &#187; Ingenieria Industrial Online</title>
	<link>https://ingenieriaindustrialonline.com/tag/metodo-grafico/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Cambios en el lado derecho de las restricciones (Método gráfico)</title>
		<link>https://ingenieriaindustrialonline.com/investigacion-de-operaciones/cambios-en-el-lado-derecho-de-las-restricciones-metodo-grafico/</link>
					<comments>https://ingenieriaindustrialonline.com/investigacion-de-operaciones/cambios-en-el-lado-derecho-de-las-restricciones-metodo-grafico/#respond</comments>
		
		<dc:creator><![CDATA[Bryan Salazar López]]></dc:creator>
		<pubDate>Tue, 14 Feb 2023 00:04:02 +0000</pubDate>
				<category><![CDATA[Investigación de operaciones]]></category>
		<category><![CDATA[Análisis de sensibilidad]]></category>
		<category><![CDATA[Análisis postóptimo]]></category>
		<category><![CDATA[Cambios en RHS]]></category>
		<category><![CDATA[Método gráfico]]></category>
		<category><![CDATA[Programación lineal]]></category>
		<guid isPermaLink="false">https://www.ingenieriaindustrialonline.com/?p=33214</guid>

					<description><![CDATA[<p>El análisis de sensibilidad mediante método gráfico es una técnica utilizada en modelos matemáticos para determinar cómo los cambios en los valores de entrada afectan a las salidas del modelo. Los resultados estáticos obtenidos a través de un método de solución son una fotografía, corresponden a la optimización de acuerdo a unos parámetros inalterables. Las &#8230;</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/cambios-en-el-lado-derecho-de-las-restricciones-metodo-grafico/">Cambios en el lado derecho de las restricciones (Método gráfico)</a> se publicó primero en <a href="https://ingenieriaindustrialonline.com">Ingenieria Industrial Online</a>.</p>
]]></description>
										<content:encoded><![CDATA[
		<div id="inrtoduccion" data-title="Inrtoducción" class="index-title"></div>
	 El análisis de sensibilidad mediante método gráfico es una técnica utilizada en modelos matemáticos para determinar cómo los cambios en los valores de entrada afectan a las salidas del modelo.</p>
<p>Los resultados estáticos obtenidos a través de un método de solución son una fotografía, corresponden a la optimización de acuerdo a unos parámetros inalterables. Las preguntas que dan pie, tanto al análisis de sensibilidad como al análisis postóptimo son: <em><strong>¿Qué pasaría si los valores de algunos parámetros cambian? ¿Cómo afecta esto a la solución óptima o la factibilidad del modelo? ¿Cómo afecta a las variables de decisión y/o la función objetivo?</strong></em></p>
<p>Para responder a estas preguntas acudimos a los análisis complementarios: <strong>Sensibilidad</strong> y <strong>Postóptimo</strong>.</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2023/02/camara.webp" alt="fotografía" width="236" height="243" class="size-full wp-image-33219 alignleft" />El análisis de sensibilidad determina las condiciones que mantendrán la solución actual sin cambios (desde el punto de vista geométrico, ya que es posible que la función objtivo y las variables de decisión cambien ante los cambios de los parámetros del modelo), mientras que el análisis postóptimo determina la nueva solución óptima cuando los datos del modelo cambian. Las tecnologías actuales, como Geogebra, han reducido la diferencia entre estos dos tipos de análisis, permitiendo una transición fluida desde el análisis de sensibilidad (indicadores lineales) hasta el análisis postóptimo mediante técnicas dinámicas.</p>
<p>Es importante destacar que, aunque el <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/metodo-grafico/"><strong>método gráfico</strong></a> es útil para comprender las relaciones en el sistema, existen otras herramientas más robustas, como la programación paramétrica con lenguajes de programación, que superan las limitaciones de la cantidad máxima de variables que puede manejar el método gráfico. Por lo tanto, el método gráfico puede ser una buena opción para visualizar los resultados, pero no es la herramienta más adecuada para un análisis exhaustivo y detallado de la sensibilidad.</p>
<p>Empezaremos por uno de los casos de análisis de sensibilidad más conocidos:</p>
<h2>Cambios en el lado derecho de las restricciones
		<div id="cambios-en-el-lado-derecho-de-las-restricciones" data-title="Cambios en el lado derecho de las restricciones" class="index-title"></div>
	</h2>
<p>También conocido como «cambio en la disponibilidad de los recursos», este tipo de análisis de sensibilidad es técnicamente definido como «cambio en el lado derecho de las restricciones» y es uno de los más populares. Sin embargo, es importante destacar que las restricciones en un sistema no solo se relacionan con la disponibilidad de recursos, sino que también representan condiciones, relaciones y políticas que rigen al sistema en sí. Por lo tanto, denominar este tipo de análisis como «cambio en la disponibilidad de los recursos» puede generar ambigüedad y no reflejar completamente su alcance.</p>
<p>En palabras más sencillas: Vamos a explorar el impacto que tiene en los resultados del modelo de programación lineal, los cambios en el lado derecho de las restricciones. ¿Cambios en plural? Sí, lea la siguiente advertencia:</p>

		<div class="box warning  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>
<p>En la educación y la literatura sobre este tipo de análisis de sensibilidad, a menudo se encuentra la afirmación equivocada de que «el método gráfico solo permite cambios en un solo parámetro mientras mantiene todos los demás inalterados». Sin embargo, la tecnología actual nos permite explorar el impacto en la solución de cambios simultáneos en los parámetros mediante técnicas dinámicas. Es importante tener en cuenta que estos cambios simultáneos pueden tener efectos combinados en los resultados del modelo.</p>

			</div>
		</div>
	
<p>Los paradigmas de la enseñanza tradicional no paran ahí, también tenemos que:</p>

		<div class="box warning  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>
<p>En la educación y la literatura sobre este tipo de análisis de sensibilidad, a menudo se encuentra la afirmación equivocada de que «el análisis de sensibilidad ante los cambios en el lado derecho de las restricciones se reduce a analizar el intervalo de aquellas restricciones que afectan el punto óptimo». Sin embargo, la tecnología actual nos permite explorar el impacto en la solución de cambios en restricciones que no necesariamente afectan el punto óptimo (tanto sensibilidad como postóptimo).</p>

			</div>
		</div>
	
<p>Con el propósito de evaluar los resultados obtenidos a través del tratamiento de un problema técnicamente formulado y abordado, utilizaremos un caso descrito en el libro Investigación de Operaciones (9na edición), de Hamdy A. Taha (University of Arkansas, Fayetteville), (Ejemplo 3.6-1):</p>
<blockquote class=" quote-simple "><p>JOBCO fabrica dos productos en dos máquinas. Una unidad del producto 1 requiere 2 horas en la máquina 1, y 1 hora en la máquina 2. Una unidad del producto 2 requiere 1 hora en la máquina 1, y 3 horas en la máquina 2. Los ingresos por unidad de los productos 1 y 2 son de $30 y $20, respectivamente. El tiempo de procesamiento diario total disponible en cada máquina es de 8 horas.</p></blockquote>
<p>Si <em><strong>x</strong></em> e <em><strong>y</strong></em> son las cantidades diarias de productos 1 y 2, respectivamente, el modelo se da como:</p>
<p style="text-align: center;"><strong>Zmax</strong> = 30<strong>x</strong> + 20<strong>y</strong></p>
<p>Sujeto a:</p>
<p style="text-align: center;">2<strong>x</strong> + <strong>y</strong> &lt;= 8 (Máquina 1)</p>
<p style="text-align: center;"><strong>x</strong> + 3<strong>y</strong> &lt;= 8 (Máquina 2)</p>
<p style="text-align: center;"><strong>x</strong>, <strong>y</strong> &gt;= 0 (No negatividad)</p>
<p>La solución de este modelo mediante método gráfico nos muestra lo siguiente:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2023/02/optima_jobco.png" alt="óptima_jobco" width="613" height="630" class="size-full wp-image-33222 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2023/02/optima_jobco.png 613w, https://ingenieriaindustrialonline.com/wp-content/uploads/2023/02/optima_jobco-292x300.png 292w" sizes="(max-width: 613px) 100vw, 613px" /></p>
<p>Es decir que tenemos:</p>
<table style="border-collapse: collapse; width: 100%; height: 111px;">
<tbody>
<tr style="height: 37px;">
<td style="width: 50%; text-align: center; height: 37px;"><strong>x (producto 1)</strong></td>
<td style="width: 50%; height: 37px; text-align: center;">3.2</td>
</tr>
<tr style="height: 37px;">
<td style="width: 50%; text-align: center; height: 37px;"><strong>y (producto 2)</strong></td>
<td style="width: 50%; height: 37px; text-align: center;">1.6</td>
</tr>
<tr style="height: 37px;">
<td style="width: 50%; text-align: center; height: 37px;"><strong>Z (ingresos)</strong></td>
<td style="width: 50%; height: 37px; text-align: center;">$ 128</td>
</tr>
</tbody>
</table>
<p>La pregunta que pretende responder este caso de análisis de sensibilidad es <em>¿Qué pasaría con estos resultados si cambia el lado derecho de algunas de sus restricciones? </em>Propiamente, qué pasaría si aumenta o disminuye la disponibilidad de tiempo de alguna de las máquinas de acuerdo al caso planteado (máquina 1 / máquina 2).</p>
<p>Así que, vamos a formular específiamente la pregunta a resolver:</p>
<p><strong>¿Qué pasaría con los resultados del modelo si el tiempo disponible de la máquina 1 aumenta en una hora?</strong></p>
<p>Un cambio en la restricción supone un cambio en la representación gráfica de la misma, en consecuencia, debemos trazar la línea que representa la restricción ante este cambio de disponibilidad.</p>
<table style="border-collapse: collapse; width: 100%; height: 74px;">
<tbody>
<tr style="height: 37px;">
<td style="width: 50%; height: 37px; text-align: center;"><strong>Restricción inicial (R1)</strong></td>
<td style="width: 50%; height: 37px; text-align: center;"><strong>Restricción nueva (R1&#8242;)</strong></td>
</tr>
<tr style="height: 37px;">
<td style="width: 50%; height: 37px; text-align: center;">2x + y &lt;= 8</td>
<td style="width: 50%; height: 37px; text-align: center;">2x + y &lt;= 9</td>
</tr>
</tbody>
</table>
<p style="text-align: left;">La representación gráfica de una línea requiere un mínimo de dos puntos. La representación gráfica de un punto requiere dos coordenadas; por lo tanto vamos a tabular las coordenadas necesarias (en la igualdad).</p>
<table style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<td style="width: 50%; text-align: center;"><strong>¿Qué valor tomaría Y cuando X sea 0?</strong></td>
<td style="width: 50%; text-align: center;"><strong>¿Qué valor tomaría X cuando Y sea 0?</strong></td>
</tr>
<tr>
<td style="width: 50%; text-align: center;">2(0) + y = 9</td>
<td style="width: 50%; text-align: center;">2x + 0 = 9</td>
</tr>
<tr>
<td style="width: 50%; text-align: center;">y = 9</td>
<td style="width: 50%; text-align: center;">2x = 9</td>
</tr>
<tr>
<td style="width: 50%; text-align: center;"></td>
<td style="width: 50%; text-align: center;">x = 9/2</td>
</tr>
<tr>
<td style="width: 50%; text-align: center;"></td>
<td style="width: 50%; text-align: center;">x = 4.5</td>
</tr>
</tbody>
</table>
<p>Así entonces, tenemos nuestras coordenadas:</p>
<table style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<td style="width: 33.3333%; text-align: center;"><strong>R1&#8242;: 2x + y &lt;= 9</strong></td>
<td style="width: 33.3333%; text-align: center;"><strong>x</strong></td>
<td style="width: 33.3333%; text-align: center;"><strong>y</strong></td>
</tr>
<tr>
<td style="width: 33.3333%; text-align: center;"><strong>Punto 1</strong></td>
<td style="width: 33.3333%; text-align: center;">0</td>
<td style="width: 33.3333%; text-align: center;">9</td>
</tr>
<tr>
<td style="width: 33.3333%; text-align: center;"><strong>Punto 2</strong></td>
<td style="width: 33.3333%; text-align: center;">4.5</td>
<td style="width: 33.3333%; text-align: center;">0</td>
</tr>
</tbody>
</table>
<p>Trazamos los puntos y la línea que representan a R1:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2023/02/optima_jobco2.png" alt="óptima_jobco2" width="602" height="634" class="size-full wp-image-33223 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2023/02/optima_jobco2.png 602w, https://ingenieriaindustrialonline.com/wp-content/uploads/2023/02/optima_jobco2-285x300.png 285w" sizes="(max-width: 602px) 100vw, 602px" /></p>
<p>Trazar esta nueva restricción nos muestra que si desplazamos R1 hacia el lugar en el que se muestra R1&#8242; (aumento de la disponibilidad del recurso), tendremos una nueva intersección óptima. Simplificando: El cambio en el lado derecho de esta restricción tendría un efecto sobre los resultados obtenidos inicialmente. ¿Cuál es este efecto? Para saberlo debemos hallar la nueva intersección.</p>
<p>Si usamos técnicas matemáticas, tendremos que recurrir a la solución de ecuaciones de 2 * 2. Se trata de encontrar la intersección entre R1&#8242; y R2. Veamos el método de reducción / eliminación:</p>
<table style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<td style="width: 19.125%; text-align: center;"><strong>R1&#8242;</strong></td>
<td style="width: 45.125%; text-align: center;">2x + y = 9</td>
</tr>
<tr>
<td style="width: 19.125%; text-align: center;"><strong>R2</strong></td>
<td style="width: 45.125%; text-align: center;">x + 3y = 8</td>
</tr>
<tr>
<td style="width: 19.125%; text-align: center;"><strong>R1&#8242; * (-3)</strong></td>
<td style="width: 45.125%; text-align: center;">-6x -3y = -27</td>
</tr>
<tr>
<td style="width: 19.125%; text-align: center;"><strong>R1&#8217;*(-3) + R2</strong></td>
<td style="width: 45.125%; text-align: center;">-5x = -19</td>
</tr>
<tr>
<td style="width: 19.125%; text-align: center;"></td>
<td style="width: 45.125%; text-align: center;">x = -19/-5</td>
</tr>
<tr>
<td style="width: 19.125%; text-align: center;"></td>
<td style="width: 45.125%; text-align: center;">x = 3.8</td>
</tr>
</tbody>
</table>
<p>Si despejamos x = 3.8 en cualquiera de las restricciones tendremos el valor de y:</p>
<p style="text-align: center;">2(3.8) + y = 9</p>
<p style="text-align: center;">7.6 + y = 9</p>
<p style="text-align: center;">y = 9 &#8211; 7.6</p>
<p style="text-align: center;">y = 1.4</p>
<p>Por lo tanto tenemos las coordenadas del nuevo punto óptimo (3.8, 1.4):</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2023/02/optima_jobco3.png" alt="óptima_jobco3" width="605" height="634" class="size-full wp-image-33224 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2023/02/optima_jobco3.png 605w, https://ingenieriaindustrialonline.com/wp-content/uploads/2023/02/optima_jobco3-286x300.png 286w" sizes="(max-width: 605px) 100vw, 605px" /></p>
<p>Si evaluamos la función objetivo en este nuevo punto tendremos que:</p>
<p style="text-align: center;"><strong>Zmáx</strong> = 30(3.8) + 20(1.4)</p>
<p style="text-align: center;"><strong>Zmáx</strong> = 142</p>
<p>Podemos afirmar que un cambio en el lado derecho de la restricción 1 (tiempo disponible en horas de la máquina 1), tuvo un efecto en los resultados de la siguiente manera:</p>
<table style="border-collapse: collapse; width: 100%; height: 148px;">
<tbody>
<tr style="height: 37px;">
<td style="width: 7.4167%; height: 37px;"></td>
<td style="width: 38.7917%; text-align: center; height: 37px;"><strong>Solución inicial</strong></td>
<td style="width: 40.2083%; text-align: center; height: 37px;"><strong>Solución nueva (cambio en el RHS)</strong></td>
<td style="width: 13.5833%; text-align: center; height: 37px;"><strong>Diferencia</strong></td>
</tr>
<tr style="height: 37px;">
<td style="width: 7.4167%; height: 37px;"><strong>x</strong></td>
<td style="width: 38.7917%; text-align: center; height: 37px;">3.2</td>
<td style="width: 40.2083%; text-align: center; height: 37px;">3.8</td>
<td style="width: 13.5833%; text-align: center; height: 37px;"></td>
</tr>
<tr style="height: 37px;">
<td style="width: 7.4167%; height: 37px;"><strong>y</strong></td>
<td style="width: 38.7917%; text-align: center; height: 37px;">1.6</td>
<td style="width: 40.2083%; text-align: center; height: 37px;">1.4</td>
<td style="width: 13.5833%; text-align: center; height: 37px;"></td>
</tr>
<tr style="height: 37px;">
<td style="width: 7.4167%; height: 37px;"><strong>Z</strong></td>
<td style="width: 38.7917%; text-align: center; height: 37px;">$ 128</td>
<td style="width: 40.2083%; text-align: center; height: 37px;">$ 142</td>
<td style="width: 13.5833%; text-align: center; height: 37px;">$14</td>
</tr>
</tbody>
</table>
<p>La diferencia en la función objetivo entre la solución nueva y la solución inicial ante un cambio unitario en el lado derecho de una restricción es un indicador lineal conocido como valor dual. En este caso, el valor dual es de 14 $/hora. Es decir, por cada hora que aumente la disponibilidad de la máquina 1, la utilidad se incrementará en $14. Del mismo modo funciona de manera inversa: Por cada hora que disminuya la disponibilidad de la máquina 1, la utilidad disminuirá en $14.</p>
<p><strong>¿Este valor dual tiene validez ante cualquier cambio en este recurso?</strong> ¡No! Este indicador lineal tiene validez dentro de unos límites denominados límites de factibilidad.</p>
<p><strong>¿Entonces es imposible calcular el impacto por fuera de los límites del valor dual? </strong>¡No! La literatura invita a recalcular todo el modelo. Sin embargo, si utilizamos un software como Geogebra podemos calcular el impacto de un cambio por fuera de los límites de factibilidad:</p>
<h2>Cambios en el lado derecho de las restricciones con Geogebra
		<div id="cambios-en-el-lado-derecho-de-las-restricciones-con-geogebra" data-title="Cambios en el lado derecho de las restricciones con Geogebra" class="index-title"></div>
	</h2>
<p>Utilice los desplazadores para ver el impacto del cambio del lado derecho de las restricciones en los resultados del modelo.</p>
<p><iframe loading="lazy" width="650" height="750" style="border: 1px solid #e4e4e4; border-radius: 4px;" src="https://www.geogebra.org/classic/g3vc2hwb?embed" allowfullscreen="allowfullscreen" frameborder="0"><span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start">﻿</span><span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start">﻿</span><span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start">﻿</span></iframe></p>
<p>De acuerdo a la representación gráfica de Geogebra vemos cómo podemos lograr conocer el impacto de cambios simultáneos en los lados derechos de las restricciones. También podemos validar el resutado obtenido manualmente, validar ese valor dual de $14 si aumentamos la disponibilidad de la máquina 1 a 9 horas y verificar, desde luego, que dicho impacto lineal no es ilimitado, ya que existen límites que abordaremos en un próximo post.</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/cambios-en-el-lado-derecho-de-las-restricciones-metodo-grafico/">Cambios en el lado derecho de las restricciones (Método gráfico)</a> se publicó primero en <a href="https://ingenieriaindustrialonline.com">Ingenieria Industrial Online</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ingenieriaindustrialonline.com/investigacion-de-operaciones/cambios-en-el-lado-derecho-de-las-restricciones-metodo-grafico/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Análisis de sensibilidad gráfica mediante el uso de Python (Caso 1)</title>
		<link>https://ingenieriaindustrialonline.com/investigacion-de-operaciones/analisis-de-sensibilidad-grafica-mediante-el-uso-de-python-caso-1/</link>
					<comments>https://ingenieriaindustrialonline.com/investigacion-de-operaciones/analisis-de-sensibilidad-grafica-mediante-el-uso-de-python-caso-1/#respond</comments>
		
		<dc:creator><![CDATA[Bryan Salazar López]]></dc:creator>
		<pubDate>Sun, 18 Jul 2021 18:57:10 +0000</pubDate>
				<category><![CDATA[Investigación de operaciones]]></category>
		<category><![CDATA[Análisis de sensibilidad]]></category>
		<category><![CDATA[Intervalos de factibilidad]]></category>
		<category><![CDATA[Investigación de Operaciones]]></category>
		<category><![CDATA[Método gráfico]]></category>
		<category><![CDATA[Optimización]]></category>
		<category><![CDATA[Precio dual]]></category>
		<category><![CDATA[Precio sombra]]></category>
		<category><![CDATA[Programación lineal]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Solución gráfica]]></category>
		<guid isPermaLink="false">https://ingenieriaindustrialonline.com/?p=26239</guid>

					<description><![CDATA[<p>¿Qué es el análisis de sensibilidad en programación lineal? Quienes se adentren en los conceptos de la investigación de operaciones, propiamente en los conceptos de la programación lineal, deben considerar que existe algo más allá de la solución óptima. En investigación de operaciones, la solución de un modelo matemático establece una base para la toma &#8230;</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/analisis-de-sensibilidad-grafica-mediante-el-uso-de-python-caso-1/">Análisis de sensibilidad gráfica mediante el uso de Python (Caso 1)</a> se publicó primero en <a href="https://ingenieriaindustrialonline.com">Ingenieria Industrial Online</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>¿Qué es el análisis de sensibilidad en programación lineal?</h2>

		<div id="que-es-el-analisis-de-sensibilidad-en-programacion-lineal" data-title="¿Qué es el análisis de sensibilidad en programación lineal?" class="index-title"></div>
	
<p>Quienes se adentren en los conceptos de la investigación de operaciones, propiamente en los conceptos de la <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/programacion-lineal/"><em><strong>programación lineal</strong></em></a>, deben considerar que existe algo más allá de la solución óptima. En investigación de operaciones, la solución de un modelo matemático establece una base para la toma de decisiones; sin embargo, puede considerarse como esencial el <strong>análisis de los resultados obtenidos</strong>.</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/modelamiento.png" alt="modelamiento" width="565" height="61" class="aligncenter wp-image-26253 size-full" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/modelamiento.png 565w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/modelamiento-300x32.png 300w" sizes="(max-width: 565px) 100vw, 565px" /></p>
<p>Los resultados de un modelo de programación lineal pueden ofrecer mucha información adicional, <em>inputs </em>del análisis de resultados. Existen a grandes rasgos, dos tipos de análisis complementarios en PL:</p>

		<div class="checklist tie-list-shortcode">
<ul>
<li><strong>Análisis de sensibilidad</strong>: El cual determina las condiciones que mantendrán la solución actual sin cambios.</li>
<li><strong>Análisis postóptimo</strong>: El cual determina la nueva solución óptima cuando cambian los datos del modelo</li>
</ul>

		</div>
	
<p>En este artículo abordaremos el <strong>análisis de sensibilidad</strong>.</p>
<p>El análisis de sensibilidad en programación lineal corresponde al examen detallado de los límites dentro de los cuales los parámetros del modelo (recursos, utilidad o costo), pueden cambiar sin que esto afecte a la solución óptima y a la capacidad de calcular el impacto que tienen dichos cambios sobre la misma. Es decir, a partir de los resultados obtenidos de un modelo, podemos establecer una solución óptima y tenemos un rango en el cual podemos medir el impacto de los cambios en la disponibilidad de los recursos y los cambios en los coeficientes de la función objetivo. El análisis de dichas variaciones y el cálculo de los límites dentro de los cuales estas son válidas, es lo que se conoce como análisis de sensibilidad. Todo el análisis que se encuentre fuera de ese rango requeriría recalcular el modelo.</p>
<p>Como tal, constituye una herramienta importante en el análisis de los resultados obtenidos, sobre todo, en dos casos en particular:</p>
<ol>
<li><strong>La sensibilidad de la solución óptima ante los cambios de la disponibilidad de los recursos (lado derecho de las restricciones)</strong>. Es decir, cuáles serían los límites dentro de los cuáles los resultados del modelo me permiten calcular el impacto que tiene sobre la solución óptima, el aumento o la disminución de la disponibilidad de un recurso.</li>
<li><strong>La sensibilidad de la solución óptima ante los cambios en la utilidad unitaria o el costo unitario (coeficientes de las variables de la función objetivo)</strong>. Es decir, cuáles serían los límites dentro de los cuáles los resultados del modelo me permiten calcular el impacto que tiene sobre la solución óptima, el aumento o la disminución de la utilidad unitaria o el costo unitario asociada a las variables que forman parte de la función objetivo.</li>
</ol>
<h3>Análisis de sensibilidad gráfica, caso 1: Cambios en el lado derecho (Disponibilidad de recursos)</h3>

		<div id="analisis-de-sensibilidad-grafica-caso-1-cambios-en-el-lado-derecho" data-title="Análisis de sensibilidad gráfica, caso 1: Cambios en el lado derecho" class="index-title"></div>
	
<p>Con el propósito de evaluar los resultados obtenidos a través del tratamiento de un problema técnicamente formulado y abordado, utilizaremos un caso descrito en el libro Investigación de Operaciones (9na edición), de Hamdy A. Taha (University of Arkansas, Fayetteville), (Ejemplo 3.6-1):</p>
<blockquote class=" quote-simple "><p>JOBCO fabrica dos productos en dos máquinas. Una unidad del producto 1 requiere 2 horas en la máquina 1, y 1 hora en la máquina 2. Una unidad del producto 2 requiere 1 hora en la máquina 1, y 3 horas en la máquina 2. Los ingresos por unidad de los productos 1 y 2 son de $30 y $20, respectivamente. El tiempo de procesamiento diario total disponible en cada máquina es de 8 horas.</p></blockquote>
<p>Si <em><strong>x1</strong></em> y <em><strong>x2</strong></em> son las cantidades diarias de productos 1 y 2, respectivamente, el modelo se da como:</p>
<p style="text-align: center;"><strong>Zmax</strong> = 30<strong>x1</strong> + 20<strong>x2</strong></p>
<p>Sujeto a:</p>
<p style="text-align: center;">2<strong>x1</strong> + <strong>x2</strong> &lt;= 8 (Máquina 1)</p>
<p style="text-align: center;"><strong>x1</strong> + 3<strong>x2</strong> &lt;= 8 (Máquina 2)</p>
<p style="text-align: center;"><strong>x1</strong>, <strong>x2</strong> &gt;= 0 (No negatividad)</p>
<p>La forma en la que abordamos la <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/metodo-grafico-de-la-programacion-lineal-mediante-el-uso-de-python/"><strong>solución gráfica de un modelo de programación lineal mediante <em>Python</em></strong></a>, está ampliamente documentada. El código en <em>Python </em>que resuelve mediante método gráfico el problema anterior, lo presentamos a continuación:</p>
<hr />
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code># Caso JOBCO: Investigación de Operaciones (9na edición), de Hamdy A. Taha 
# (University of Arkansas, Fayetteville), (Ejemplo 3.6-1)
# Autor del código en Python: Bryan Salazar López, Ing. M.Sc. (2021)

#Librerías necesarias
import matplotlib.pyplot as plt
import numpy as np
from shapely.geometry import LineString

#Ecuaciones e intervalos (Para tabular)
x = np.arange(-20, 20, 5)
y = np.arange(-20, 20, 5)
y1 = 8 - (2 * x)
y2 = (8 - x) / 3
y3 = 0 * x
x1 = 0 * y
z = (-30 * x) / 20

#Identificadores para las líneas
primera_linea = LineString(np.column_stack((x, y1)))
segunda_linea = LineString(np.column_stack((x, y2)))
tercera_linea = LineString(np.column_stack((x, y3)))
cuarta_linea = LineString(np.column_stack((x1, y)))
quinta_linea = LineString(np.column_stack((x, z)))

#Graficando las líneas
plt.plot(x, y1, '-', linewidth=2, color='b')
plt.plot(x, y2, '-', linewidth=2, color='g')
plt.plot(x, y3, '-', linewidth=2, color='r')
plt.plot(x1, y, '-', linewidth=2, color='y')
plt.plot(x, z, ':', linewidth=1, color='k')


#Generando las intersecciones (vértices)
primera_interseccion = cuarta_linea.intersection(segunda_linea)
segunda_interseccion = primera_linea.intersection(segunda_linea)
tercera_interseccion = primera_linea.intersection(tercera_linea)
cuarta_interseccion = tercera_linea.intersection(cuarta_linea)
quinta_interseccion = cuarta_linea.intersection(primera_linea)
sexta_interseccion = segunda_linea.intersection(tercera_linea)

#Graficando los vértices
plt.plot(*primera_interseccion.xy, 'o', color='k')
plt.plot(*segunda_interseccion.xy, 'o', color='k')
plt.plot(*tercera_interseccion.xy, 'o', color='k')
plt.plot(*cuarta_interseccion.xy, 'o', color='k')
plt.plot(*quinta_interseccion.xy, 'o', color='silver')
plt.plot(*sexta_interseccion.xy, 'o', color='silver')

#Identificando los valores de las coordenadas x y y de cada vértice
xi1m, yi1m = primera_interseccion.xy
xi2m, yi2m = segunda_interseccion.xy
xi3m, yi3m = tercera_interseccion.xy
xi4m, yi4m = cuarta_interseccion.xy
xi5m, yi5m = quinta_interseccion.xy
xi6m, yi6m = sexta_interseccion.xy

#Cambiamos el formato de matriz a float
xi1 = np.float64(np.array(xi1m))
xi2 = np.float64(np.array(xi2m))
xi3 = np.float64(np.array(xi3m))
xi4 = np.float64(np.array(xi4m))
xi5 = np.float64(np.array(xi5m))
xi6 = np.float64(np.array(xi6m))
yi1 = np.float64(np.array(yi1m))
yi2 = np.float64(np.array(yi2m))
yi3 = np.float64(np.array(yi3m))
yi4 = np.float64(np.array(yi4m))
yi5 = np.float64(np.array(yi5m))
yi6 = np.float64(np.array(yi6m))

#literales de las intersecciones (nombres en el gráfico)
plt.annotate(' A', (xi4, yi4))
plt.annotate(' B', (xi1, yi1))
plt.annotate(' C', (xi2, yi2))
plt.annotate(' D', (xi3, yi3))
plt.annotate(' E', (xi5, yi5))
plt.annotate(' F', (xi6, yi6))

#Evaluando la función objetivo en cada vértice
FOi1 = (xi1 * 30) + (yi1 * 20)
FOi2 = (xi2 * 30) + (yi2 * 20)
FOi3 = (xi3 * 30) + (yi3 * 20)
FOi4 = (xi4 * 30) + (yi4 * 20)

#Calculando el mejor resultado (Maximizar)
ZMAX = max(FOi1, FOi2, FOi3, FOi4)

#Imprimiendo la solución óptima en la consola
print('\n SOLUCIÓN ÓPTIMA')
print('Solución óptima: {} '.format(ZMAX))

#Ordenando las coordenadas de los vértices (Las coordenadas x en m y las coordenadas y en n)
m = [xi1, xi2, xi3, xi4]
n = [yi1, yi2, yi3, yi4]

#Graficando el polígono solución a partir de las coordenadas de los vértices (importante el orden según las manecillas)
plt.fill(m, n, color='silver')

#Identificando el índice del vértice de la mejor solución
dict1 = {0:FOi1, 1:FOi2, 2:FOi3, 3:FOi4}
posicion = max(dict1, key=dict1.get)

#Obteniendo las coordenadas del vértice de la mejor solución de acuerdo al índice del paso anterior
XMAX = m[posicion]
YMAX = n[posicion]

#Imprimiendo las coordenadas del vértice de la mejor solución (variables de decisión)
print('\n VARIABLES DE DECISIÓN')
print('Cantidad de producto X1 a producir: {} unidades'.format(XMAX))
print('Cantidad de producto X2 a producir: {} unidades'.format(YMAX))

#Configuraciones adicionales del gráfico
plt.grid()
plt.xlabel('X1')
plt.ylabel('X2')
plt.title('JOBCO')

plt.show()
</code></pre>
</div>
<p>Al ejecutar este código, de acuerdo a las instrucciones que pueden encontrar en el artículo de<a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/metodo-grafico-de-la-programacion-lineal-mediante-el-uso-de-python/"><strong> introducción al método gráfico mediante Python</strong></a>, obtendrán:</p>
<figure id="attachment_26264" aria-describedby="caption-attachment-26264" style="width: 640px" class="wp-caption aligncenter"><a href="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_metodo_grafico.webp"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_metodo_grafico.webp" alt="jobco_metodo_grafico" width="640" height="480" class="wp-image-26264 size-full" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_metodo_grafico.webp 640w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_metodo_grafico-300x225.webp 300w" sizes="(max-width: 640px) 100vw, 640px" /></a><figcaption id="caption-attachment-26264" class="wp-caption-text">Figura 2: Solución gráfica del caso JOBCO obtenida mediante Python</figcaption></figure>
<p>Así mismo, el siguiente resultado en la consola:</p>
<figure id="attachment_26265" aria-describedby="caption-attachment-26265" style="width: 593px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_solucion_optima.png" alt="jobco_solucion_optima" width="593" height="213" class="wp-image-26265 size-full" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_solucion_optima.png 593w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_solucion_optima-300x108.png 300w" sizes="(max-width: 593px) 100vw, 593px" /><figcaption id="caption-attachment-26265" class="wp-caption-text">Figura 3: Resultados del caso JOBCO en la consola de Windows (Solución óptima)</figcaption></figure>
<p>&nbsp;</p>
<p>Así entonces, tenemos establecido el código base sobre el cual abordaremos este primer caso de <em>análisis de sensibilidad: cambios en el lado derecho (disponibilidad de recursos)</em>.</p>
<p>La pregunta que pretende responder este caso de análisis de sensibilidad es <em>¿Qué pasaría con la función objetivo si cambia la disponibilidad de alguno de los recursos del problema?</em> El cual corresponde a un planteamiento muy lógico de análisis, puesto que nos ampliaría la información relevante para la toma de decisiones.</p>
<p>Acercando este interrogante a nuestro problema de ejemplo, la cuestión podría ser: <em>¿Qué pasaría con los ingresos totales si la máquina 1 cambia su capacidad?</em></p>
<p>Pensemos por un momento cómo podemos abordar este planteamiento de manera gráfica, pensemos por un momento cómo podemos utilizar nuestro código base para abordar este caso.</p>
<p>Y bien, se nos puede ocurrir en primer lugar, graficar la nueva línea que represente la nueva función de disponibilidad de la máquina 1. Recordemos que si la restricción base es la siguiente:</p>
<p style="text-align: center;">2<strong>x1</strong> + <strong>x2</strong> &lt;= 8 (Máquina 1)</p>
<p>Un incremento en la capacidad (variación), por ejemplo, se representaría mediante la siguiente inecuación:</p>
<p style="text-align: center;">2<strong>x1</strong> + <strong>x2</strong> &lt;= 8 + 1</p>
<p>Esto quiere decir que, la nueva disponibilidad de la <em><strong>máquina 1</strong></em> pasará de 8 horas a 9 horas. Y nuestro razonamiento nos indica que esta función, tendrá una representación distinta a la anterior, por ende sería de mucha utilidad graficarla. Veamos el código para adicionar en Python:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Ecuaciones e intervalos (Para tabular)
x = np.arange(-20, 20, 5)
y = np.arange(-20, 20, 5)
y1 = 8 - (2 * x)
y2 = (8 - x) / 3
y3 = 0 * x
x1 = 0 * y
z = (-30 * x) / 20
y1v = (8 + 1) - (2 * x) #Variación en la máquina 1 (8 + 1)

#Identificadores para las líneas
primera_linea = LineString(np.column_stack((x, y1)))
segunda_linea = LineString(np.column_stack((x, y2)))
tercera_linea = LineString(np.column_stack((x, y3)))
cuarta_linea = LineString(np.column_stack((x1, y)))
quinta_linea = LineString(np.column_stack((x, z)))
sexta_linea = LineString(np.column_stack((x, y1v))) #Nueva línea

#Graficando las líneas
plt.plot(x, y1, '-', linewidth=2, color='b')
plt.plot(x, y2, '-', linewidth=2, color='g')
plt.plot(x, y3, '-', linewidth=2, color='r')
plt.plot(x1, y, '-', linewidth=2, color='y')
#plt.plot(x, z, ':', linewidth=1, color='k') #Podemos ocultar esta línea (FO)
plt.plot(x, y1v, ':', linewidth=1, color='b') #Nueva línea
</code></pre>
</div>
<p>Podemos observar cómo agregamos tan solo 3 líneas de código, mediante la inclusión de la variable <em><strong>y1v </strong></em>(variación de la ecuación de la máquina 1).</p>
<p>La ecuación con la cual se representa la restricción de la máquina 1 corresponde a la siguiente:</p>
<p style="text-align: center;"><strong>y1</strong> = 8 &#8211; (2 * <strong>x</strong>)</p>
<p>Por ende, lo que hacemos es aumentar la capacidad de la máquina 1 (8) a una nueva capacidad (9 = 8 + 1):</p>
<p style="text-align: center;"><strong>y1v</strong> = (8 + 1) &#8211; (2 * <strong>x</strong>)</p>
<p>Las dos líneas de código adicionales graficarán esta nueva ecuación.</p>
<p>Al ejecutar nuestro código tendremos:</p>
<figure id="attachment_26266" aria-describedby="caption-attachment-26266" style="width: 640px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_analisis_sensibilidad.png" alt="jobco_analisis_sensibilidad" width="640" height="480" class="wp-image-26266 size-full" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_analisis_sensibilidad.png 640w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_analisis_sensibilidad-300x225.png 300w" sizes="(max-width: 640px) 100vw, 640px" /><figcaption id="caption-attachment-26266" class="wp-caption-text">Figura 3: Representación gráfica de un cambio en la disponibilidad del recurso 1</figcaption></figure>
<p>En este caso, podemos observar cómo una variación en la disponibilidad del recurso 1 (máquina 1), se representa con una línea recta (línea azul punteada) que conserva la misma pendiente de la restricción 1 (línea azul continua), que se mueve paralela a ella, y que en consecuencia, genera una nueva intersección solución (intersección con la restricción 2 &#8211; línea verde).</p>
<p>En este nuevo vértice solución se encuentra un nuevo punto óptimo, es decir, una coordenada diferente en la cual al evaluar la función objetivo, tendremos la respuesta al interrogante planteado: <em>¿Qué pasaría con los ingresos totales si la máquina 1 cambia su capacidad?</em></p>
<p>En consecuencia, utilizaremos nuestro código para:</p>

		<div class="checklist tie-list-shortcode">
<ul>
<li>Establecer gráficamente el nuevo vértice</li>
<li>Nombrarlo gráficamente (Vértice <em>G</em>)</li>
<li>Determinar las coordenadas de este vértice (<em>G</em>)</li>
<li>Evaluar la función objetivo en este nuevo vértice (<em>G</em>)</li>
</ul>

		</div>
	
<p>El siguiente fragmento muestra detalladamente las adiciones al código base:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Generando las intersecciones (vértices)
primera_interseccion = cuarta_linea.intersection(segunda_linea)
segunda_interseccion = primera_linea.intersection(segunda_linea)
tercera_interseccion = primera_linea.intersection(tercera_linea)
cuarta_interseccion = tercera_linea.intersection(cuarta_linea)
quinta_interseccion = cuarta_linea.intersection(primera_linea)
sexta_interseccion = segunda_linea.intersection(tercera_linea)
septima_interseccion = sexta_linea.intersection(segunda_linea) #Nuevo vértice

#Graficando los vértices
plt.plot(*primera_interseccion.xy, 'o', color='k')
plt.plot(*segunda_interseccion.xy, 'o', color='k')
plt.plot(*tercera_interseccion.xy, 'o', color='k')
plt.plot(*cuarta_interseccion.xy, 'o', color='k')
plt.plot(*quinta_interseccion.xy, 'o', color='silver')
plt.plot(*sexta_interseccion.xy, 'o', color='silver')
plt.plot(*septima_interseccion.xy, 'o', color='k') #Graficar nuevo vértice

#Identificando los valores de las coordenadas x y y de cada vértice
xi1m, yi1m = primera_interseccion.xy
xi2m, yi2m = segunda_interseccion.xy
xi3m, yi3m = tercera_interseccion.xy
xi4m, yi4m = cuarta_interseccion.xy
xi5m, yi5m = quinta_interseccion.xy
xi6m, yi6m = sexta_interseccion.xy
xi7m, yi7m = septima_interseccion.xy #Coordenadas del nuevo vértice

#Cambiamos el formato de matriz a float
xi1 = np.float64(np.array(xi1m))
xi2 = np.float64(np.array(xi2m))
xi3 = np.float64(np.array(xi3m))
xi4 = np.float64(np.array(xi4m))
xi5 = np.float64(np.array(xi5m))
xi6 = np.float64(np.array(xi6m))
xi7 = np.float64(np.array(xi7m)) #Nueva coordenada en x
yi1 = np.float64(np.array(yi1m))
yi2 = np.float64(np.array(yi2m))
yi3 = np.float64(np.array(yi3m))
yi4 = np.float64(np.array(yi4m))
yi5 = np.float64(np.array(yi5m))
yi6 = np.float64(np.array(yi6m))
yi7 = np.float64(np.array(yi7m)) #Nueva coordenada en y

#literales de las intersecciones (nombres en el gráfico)
plt.annotate(' A', (xi4, yi4))
plt.annotate(' B', (xi1, yi1))
plt.annotate(' C', (xi2, yi2))
plt.annotate(' D', (xi3, yi3))
plt.annotate(' E', (xi5, yi5))
plt.annotate(' F', (xi6, yi6)) 
plt.annotate(' G', (xi7, yi7)) #Nombrar el nuevo vértice como G

#Evaluando la función objetivo en cada vértice
FOi1 = (xi1 * 30) + (yi1 * 20)
FOi2 = (xi2 * 30) + (yi2 * 20)
FOi3 = (xi3 * 30) + (yi3 * 20)
FOi4 = (xi4 * 30) + (yi4 * 20)
FOi4 = (xi7 * 30) + (yi7 * 20) #Calcular la FO en el nuevo vértice

#Imprimiendo la solución óptima en la consola
print('\n SOLUCIÓN ÓPTIMA')
print('Solución óptima: {} '.format(ZMAX))
print('Función objetivo en punto G: {} '.format(FOi7)) #Mostrar la FO en el punto G
</code></pre>
</div>
<p>Lo que realizamos es muy sencillo, es decir, ya que tenemos una nueva línea, realizamos los mismos procedimientos para identificar y graficar el nuevo vértice generado. Al ejecutar el código obtendremos lo siguiente:</p>
<figure id="attachment_26267" aria-describedby="caption-attachment-26267" style="width: 640px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_analisis_sensibilidad1.png" alt="jobco_analisis_sensibilidad1" width="640" height="480" class="wp-image-26267 size-full" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_analisis_sensibilidad1.png 640w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_analisis_sensibilidad1-300x225.png 300w" sizes="(max-width: 640px) 100vw, 640px" /><figcaption id="caption-attachment-26267" class="wp-caption-text">Figura 4: Representación gráfica de un cambio en la disponibilidad del recurso 1 (Nuevo vértice)</figcaption></figure>
<p>&nbsp;</p>
<figure id="attachment_26268" aria-describedby="caption-attachment-26268" style="width: 597px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_solucion_sensibilidad.png" alt="jobco_solucion_sensibilidad" width="597" height="226" class="wp-image-26268 size-full" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_solucion_sensibilidad.png 597w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_solucion_sensibilidad-300x114.png 300w" sizes="(max-width: 597px) 100vw, 597px" /><figcaption id="caption-attachment-26268" class="wp-caption-text">Figura 5: Resultados del caso JOBCO en la consola de Windows (Función objetivo en punto G)</figcaption></figure>
<p>&nbsp;</p>
<p>La <em>figura 5</em> ilustra el cambio de la solución óptima cuando se cambia la capacidad de la máquina 1. Si la capacidad diaria se incrementa de 8 a 9 horas, el nuevo óptimo se moverá al punto <strong><em>G</em></strong>. Los resultados que se pueden apreciar en la consola, nos permiten conocer que el valor de la función objetivo evaluada en el punto <em><strong>G </strong>(<strong>z</strong> en <strong>G</strong>)</em> equivale a 142,0. Es decir, un valor superior a 128,0 (<em><strong>z</strong></em> en <em><strong>C</strong></em>).</p>
<p>Con los datos obtenidos podemos establecer en este caso la tasa de cambio en la función objetivo a consecuencia del cambio de la capacidad de la máquina 1 de 8 a 9 horas. Esta tasa de cambio se denomina de diversas formas: <em><strong>valor unitario de un recurso </strong></em>(Taha); <em><strong>precio dual </strong></em>(múltiples solucionadores); <em><strong>shadow price </strong></em>(precio sombra).</p>
<p>Esta tasa representa el impacto del incremento unitario en la capacidad de un recurso en la función objetivo; se calcula de la siguiente manera:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/precio_dual.png" alt="precio_dual" width="517" height="59" class="aligncenter size-full wp-image-26269" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/precio_dual.png 517w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/precio_dual-300x34.png 300w" sizes="(max-width: 517px) 100vw, 517px" /></p>
<p>En nuestro ejemplo se calculará así:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/shadow_price.png" alt="shadow_price" width="346" height="232" class="aligncenter size-full wp-image-26270" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/shadow_price.png 346w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/shadow_price-300x201.png 300w" sizes="(max-width: 346px) 100vw, 346px" /></p>
<p>Esto indica que: <em>Un incremento unitario en la capacidad de la máquina 1, aumentará el ingreso en $14,0</em>. O lo que es igual: <em>Una reducción unitaria en la capacidad de la máquina 1, reducirá el ingreso en $14,0.</em></p>
<p>En lo que concierne a nuestro código e Python, es sencillo, resulta que nosotros ya tenemos la función objetivo evaluada en cada uno de los vértices del gráfico. Así entonces, será cuestión de crear una nueva variable que represente el <em><strong>precio dual </strong></em>y la operación correspondiente:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Precio dual (Restricción 1)
Dual1 = (FOi7 - ZMAX) #Calculamos el precio dual para la restricción 1

print('\n ANÁLISIS DE SENSIBILIDAD')
print('Precio dual de la máquina 1: {} $/h'.format(Dual1)) #Imprimimos el precio dual 1
</code></pre>
</div>
<p>Recordemos que la función objetivo del punto <em><strong>G </strong></em>(<em><strong>z</strong></em> en <em><strong>G</strong>) </em>se representa por la variable<em><strong> FOi7</strong></em> (función objetivo en la intersección 7). La operación efectúa la diferencia entre este valor y la función objetivo en el vértice óptimo base (<em><strong>ZMAX</strong></em>).</p>
<p>Al ejecutar el código obtendremos lo siguiente en la consola de Windows:</p>
<figure id="attachment_26271" aria-describedby="caption-attachment-26271" style="width: 592px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/precio_dual1.png" alt="precio_dual1" width="592" height="262" class="wp-image-26271 size-full" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/precio_dual1.png 592w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/precio_dual1-300x133.png 300w" sizes="(max-width: 592px) 100vw, 592px" /><figcaption id="caption-attachment-26271" class="wp-caption-text">Figura 6: Resultados del caso JOBCO (Precio dual máquina 1)</figcaption></figure>
<p>&nbsp;</p>
<p>Ahora bien, debemos recordar que hemos hecho énfasis en que el análisis de sensibilidad del caso 1 (cambios en el lado derecho de las restricciones &#8211; capacidad de los recursos), precisa de unos límites dentro de los cuáles los resultados del modelo me permiten calcular el impacto que tiene sobre la solución óptima. Es decir, para nuestro caso en particular: <em>los límites dentro de los cuales el precio dual para la máquina 1 es 14$/h. </em>Dicho de otra manera, estamos en condiciones de calcular el impacto de una variación en la máquina 1 en los ingresos totales, pero, <em>¿Hasta cuándo esa proyección es válida? </em>Y sí, existen unos límites dentro de los cuales nuestra proyección, tasa o precio dual es válido, por fuera de ellos, sería necesario recalcular.</p>
<p>Revisemos nuevamente la <em>figura 4</em>:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_analisis_sensibilidad1.png" alt="jobco_analisis_sensibilidad1" width="640" height="480" class="aligncenter size-full wp-image-26267" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_analisis_sensibilidad1.png 640w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_analisis_sensibilidad1-300x225.png 300w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<p>Veamos cómo la línea que representa los cambios en la capacidad de la <em><strong>máquina 1 </strong></em>(recurso) se mueve paralela a sí misma, y bien puede hacerlo sobre el segmento de la línea que representa la capacidad de la <em><strong>máquina 2</strong></em> (línea verde, o algebraicamente: <em>línea BF, desde el punto B hasta el punto F</em>). Esa es básicamente la clave para determinar los límites de validez de nuestro precio dual, mejor conocidos como <em><strong>intervalos de factibilidad</strong></em>. Pero <em>¿Cuál es la clave? </em>Sí, la ecuación de la <em><strong>máquina 1</strong></em> puede moverse para formar una intersección con la <em><strong>línea verde</strong></em> (a medida que cambie su capacidad) entre <em><strong>B</strong></em> y <em><strong>F</strong></em>, de manera que en estos vértices se encuentran los límites. Y para ser directos, la idea consiste en calcular la capacidad de la máquina 1 en cada uno de estos vértices. <em>¿Cómo lo hacemos? </em>Veamos:</p>
<p>La ecuación que representa la capacidad de la máquina 1 está dada por:</p>
<p style="text-align: center;">2<strong>x1</strong> + <strong>x2</strong> &lt;= 8 horas (máquina 1)</p>
<p>Por ende, si retiramos el valor de la capacidad del recurso (8 horas), obtendremos la ecuación de la utilización o el uso del recurso:</p>
<p style="text-align: center;">2<strong>x1</strong> + <strong>x2 </strong>= Utilización o uso de la máquina 1</p>
<p>Ahora, teniendo la ecuación de la restricción 1 (máquina 1), podemos evaluar cuál sería su utilización en los vértices <em><strong>B </strong></em>y <em><strong>F</strong></em>. Así encontraríamos los límites de validez para esta restricción (intervalos de factibilidad para nuestro precio dual = 14$/h). Dicho de otro modo, encontraríamos la capacidad mínima y máxima de la máquina 1, para que una variación unitaria en la disponibilidad de la misma (máquina 1), represente una variación de 14$ en la función objetivo. Por fuera de ese intervalo, no podemos asegurar de ninguna manera que el precio dual es de 14$/h, sería necesario recalcular.</p>
<p>Volvamos a la determinación de los límites. Ya tenemos la ecuación de la restricción (la verdad, siempre la hemos tenido), ahora la evaluaremos en los puntos <em><strong>B </strong></em>y <em><strong>F</strong></em>. Para ello es preciso conocer las coordenadas de cada uno de estos puntos. En <em>Python</em> podemos utilizar el siguiente fragmento:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Intervalos de factibilidad
IFmin1 = (2 * xi2) + yi2
IFmax1 = (2 * xi6) + yi6

print('Límite mínimo de factibilidad (PD máquina 1): {} h'.format(IFmin1))
print('Límite máximo de factibilidad (PD máquina 1): {} h'.format(IFmax1))
</code></pre>
</div>
<p>Veamos: El punto <em><strong>B</strong></em> según nuestro código, corresponde a la segunda intersección, por ende sus coordenadas están definidas por las variables <em><strong>xi1 </strong></em>y <em><strong>yi1</strong></em>. Así entonces, evaluamos la capacidad de la <em><strong>máquina 1</strong></em> en estas coordenadas y tenemos el límite mínimo de factibilidad para el precio dual de la máquina 1 <em>(<strong>IFmin1</strong>).</em></p>
<p>Así mismo, el punto <b><i>F </i></b>según nuestro código, corresponde a la sexta intersección, por ende sus coordenadas están definidas por las variables <em><strong>xi6 </strong></em>y <em><strong>yi6</strong></em>. Así entonces, evaluamos la capacidad de la <em><strong>máquina 1</strong></em> en estas coordenadas y tenemos el límite mínimo de factibilidad para el precio dual de la máquina 1 (<em><strong>IFmax1</strong></em>).</p>
<p>Al ejecutar el código obtendremos lo siguiente en la consola de Windows:</p>
<figure id="attachment_26276" aria-describedby="caption-attachment-26276" style="width: 592px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/intervalo_de_factibilidad1_a.png" alt="intervalo_de_factibilidad1_a" width="592" height="327" class="size-full wp-image-26276" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/intervalo_de_factibilidad1_a.png 592w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/intervalo_de_factibilidad1_a-300x166.png 300w" sizes="(max-width: 592px) 100vw, 592px" /><figcaption id="caption-attachment-26276" class="wp-caption-text">Figura 7: Intervalos de factibilidad para la máquina 1 (Caso JOBCO)</figcaption></figure>
<p>&nbsp;</p>
<p>Podemos efectuar nosotros mismos los cálculos correspondientes:</p>
<p>El punto <em><strong>B</strong></em> tiene la siguientes coordenadas (<em><strong>x </strong></em>= 0, <em><strong>y </strong></em>= 2,67)</p>
<p>Evaluando estas coordenadas en la ecuación de la <strong><em>máquina 1</em></strong>, tenemos:</p>
<p style="text-align: center;">2(<strong>0</strong>)+ (<strong>2,67</strong>) = Límite mínimo de factibilidad (máquina 1)</p>
<p style="text-align: center;">2(<strong>0</strong>)+ (<strong>2,67</strong>) = 2,67 horas</p>
<p>El punto <em><strong>F</strong></em> tiene la siguientes coordenadas (<em><strong>x </strong></em>= 8, <em><strong>y </strong></em>= 0)</p>
<p>Evaluando estas coordenadas en la ecuación de la <strong><em>máquina 1</em></strong>, tenemos:</p>
<p style="text-align: center;">2(<strong>8</strong>)+ (<strong>0</strong>) = Límite máximo de factibilidad (máquina 1)</p>
<p style="text-align: center;">2(<strong>8</strong>)+ (<strong>0</strong>) = 16 horas</p>
<p>Ya efectuamos los procedimientos de manera manual y mediante <em>Python</em>. La conclusión es que el precio dual de $14/h permanece válido en el intervalo:</p>
<p style="text-align: center;"><strong>2,67</strong> h &lt;= Capacidad de la <em><strong>máquina 1</strong></em> &lt;= <strong>16</strong> h</p>
<p>Los cambios que se encuentren fuera de esos <em><strong>intervalos de factibilidad</strong> </em>producen un precio dual diferente, y por lo tanto, precisan nuevos cálculos.</p>
<p>En nuestro código, incluiremos las líneas que permitan llegar al precio dual y a los intervalos de factibilidad de la <em><strong>máquina 2</strong>. </em>Al ejecutarlo, obtendremos lo siguiente:</p>
<figure id="attachment_26273" aria-describedby="caption-attachment-26273" style="width: 640px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_analisis_sensibilidad2.png" alt="jobco_analisis_sensibilidad2" width="640" height="480" class="wp-image-26273 size-full" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_analisis_sensibilidad2.png 640w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/jobco_analisis_sensibilidad2-300x225.png 300w" sizes="(max-width: 640px) 100vw, 640px" /><figcaption id="caption-attachment-26273" class="wp-caption-text">Figura 8: Representación gráfica de un cambio en la disponibilidad del recurso 2 (Nuevo vértice H)</figcaption></figure>
<p>&nbsp;</p>
<figure id="attachment_26277" aria-describedby="caption-attachment-26277" style="width: 548px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/intervalo_de_factibilidad2_b.png" alt="intervalo_de_factibilidad2_b" width="548" height="404" class="size-full wp-image-26277" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/intervalo_de_factibilidad2_b.png 548w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/intervalo_de_factibilidad2_b-300x221.png 300w" sizes="(max-width: 548px) 100vw, 548px" /><figcaption id="caption-attachment-26277" class="wp-caption-text">Figura 9: Precio dual e intervalos de factibilidad para la máquina 2 (Caso JOBCO)</figcaption></figure>
<p>&nbsp;</p>
<p>La conclusión es que el precio dual de $2/h permanece válido en el intervalo:</p>
<p style="text-align: center;"><strong>4</strong> h &lt;= Capacidad de la <em><strong>máquina 2</strong></em> &lt;= <strong>24</strong> h</p>
<p>Los precios duales y los intervalos de factibilidad amplían la base que ofrece la solución óptima para la toma de decisiones. <em>Taha </em>propone una serie de preguntas alrededor de este caso (ejercicio 3.6-1), que pueden ser abordadas gracias al análisis de sensibilidad.</p>
<p><em><strong>Pregunta 1</strong></em>: Si JOBCO puede incrementar la capacidad de ambas máquinas, ¿Cuál máquina tendrá la prioridad?</p>
<p><strong>Respuesta: </strong>De acuerdo a los precios duales para las máquinas 1 y 2, cada hora adicional de la máquina 1 incrementa el ingreso total en $14; mientras tanto, cada hora adicional de la máquina 2 incrementa el ingreso total en $2. Por lo tanto, la máquina 1 debe tener la prioridad.</p>
<p><em><strong>Pregunta 2</strong></em>: Se sugiere incrementar las capacidades de las máquinas 1 y 2 al costo adicional de $10/h para cada máquina. ¿Es esto aconsejable?</p>
<p><strong>Respuesta: </strong>De acuerdo a los precios duales para las máquinas 1 y 2.  Los ingresos netos adicionales por hora serían de la siguiente manera:</p>
<p><em>Máquina 1:</em></p>
<p>14$/h (Precio dual máquina 1) &#8211; 10$/h (Costo para aumentar capacidad) = 4 $/h (Ingreso neto)</p>
<p><em>Máquina 2:</em></p>
<p>2$/h (Precio dual máquina 2) &#8211; 10$/h (Costo para aumentar capacidad) = &#8211; 8 $/h (Ingreso neto)</p>
<p>Por consiguiente, solo la <em>máquina 1</em> debe considerarse para el incremento de capacidad.</p>
<p><em><strong>Pregunta 3</strong></em>: Si la capacidad de la máquina 1 se incrementa de 8 a 13 horas, ¿Cómo impactará este incremento al ingreso óptimo?</p>
<p><strong>Respuesta</strong>: Lo primero que debe evaluarse es que la nueva capacidad de la máquina 1 se encuentre dentro del intervalo de factibilidad (2,67 h &#8211; 16 h). Ya que sí se encuentra en dicho intervalo (13 h), el siguiente paso consiste en calcular el <em>cambio en la disponibilidad</em>:</p>
<p style="text-align: center;"><em>Cambio en la capacidad</em> = 13 (Nueva capacidad) &#8211; 8 (Capacidad inicial)</p>
<p style="text-align: center;"><em>Cambio en la capacidad</em> = 5 horas</p>
<p>Por ende, multiplicamos dicho cambio por la tasa de cambio del ingreso (precio dual):</p>
<p style="text-align: center;"><em>Cambio en el ingreso</em> = Precio dual  * Cambio en la capacidad</p>
<p style="text-align: center;"><em>Cambio en el ingreso</em> = 14 $/h * (5 horas)</p>
<p style="text-align: center;"><em>Cambio en el ingreso</em> = 70 $</p>
<p style="text-align: center;"><em>Nuevo ingreso</em> = Ingreso base (Solución óptima) + Cambio en el ingreso</p>
<p style="text-align: center;"><em>Nuevo ingreso</em> = $ 128 + $ 70</p>
<p style="text-align: center;"><em>Nuevo ingreso</em> = $ 198</p>
<p>En el caso de que la nueva capacidad de la máquina se encuentre por fuera del intervalo de factibilidad para dicho recurso, no se dispondría de información suficiente para llegar a una conclusión válida.</p>
<hr />
<p>A continuación, dejamos a disposición el código completo del análisis de sensibilidad gráfica desarrollado en <em>Python</em>:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code># Caso 1: Investigación de Operaciones (9na edición), de Hamdy A. Taha 
# (University of Arkansas, Fayetteville), (Ejemplo 3.6-1)
# Autor del código en Python: Bryan Salazar López, Ing. M.Sc. (2021)

#Librerías necesarias
import matplotlib.pyplot as plt
import numpy as np
from shapely.geometry import LineString

#Ecuaciones e intervalos (Para tabular)
x = np.arange(-20, 20, 5)
y = np.arange(-20, 20, 5)
y1 = 8 - (2 * x)
y2 = (8 - x) / 3
y3 = 0 * x
x1 = 0 * y
z = (-30 * x) / 20
y1v = (8 + 1) - (2 * x) #Variación en la máquina 1 (8 + 1)
y2v = ((8 + 1) - x) / 3 #Variación en la máquina 2 (8 + 1)

#Identificadores para las líneas
primera_linea = LineString(np.column_stack((x, y1)))
segunda_linea = LineString(np.column_stack((x, y2)))
tercera_linea = LineString(np.column_stack((x, y3)))
cuarta_linea = LineString(np.column_stack((x1, y)))
quinta_linea = LineString(np.column_stack((x, z)))
sexta_linea = LineString(np.column_stack((x, y1v))) #Nueva línea Máquina 1 (M1)
septima_linea = LineString(np.column_stack((x, y2v))) #Nueva línea Máquina 2 (M2)

#Graficando las líneas
plt.plot(x, y1, '-', linewidth=2, color='b')
plt.plot(x, y2, '-', linewidth=2, color='g')
plt.plot(x, y3, '-', linewidth=2, color='r')
plt.plot(x1, y, '-', linewidth=2, color='y')
#plt.plot(x, z, ':', linewidth=1, color='k')
plt.plot(x, y1v, ':', linewidth=1, color='b') #Nueva línea M1
plt.plot(x, y2v, ':', linewidth=1, color='g') #Nueva línea M2


#Generando las intersecciones (vértices)
primera_interseccion = cuarta_linea.intersection(segunda_linea)
segunda_interseccion = primera_linea.intersection(segunda_linea)
tercera_interseccion = primera_linea.intersection(tercera_linea)
cuarta_interseccion = tercera_linea.intersection(cuarta_linea)
quinta_interseccion = cuarta_linea.intersection(primera_linea)
sexta_interseccion = segunda_linea.intersection(tercera_linea)
septima_interseccion = sexta_linea.intersection(segunda_linea) #Nuevo vértice M1
octava_interseccion = septima_linea.intersection(primera_linea) #Nuevo vértice M2

#Graficando los vértices
plt.plot(*primera_interseccion.xy, 'o', color='k')
plt.plot(*segunda_interseccion.xy, 'o', color='k')
plt.plot(*tercera_interseccion.xy, 'o', color='k')
plt.plot(*cuarta_interseccion.xy, 'o', color='k')
plt.plot(*quinta_interseccion.xy, 'o', color='silver')
plt.plot(*sexta_interseccion.xy, 'o', color='silver')
plt.plot(*septima_interseccion.xy, 'o', color='k') #Graficar nuevo vértice M1
plt.plot(*octava_interseccion.xy, 'o', color='k') #Graficar nuevo vértice M2

#Identificando los valores de las coordenadas x y y de cada vértice
xi1m, yi1m = primera_interseccion.xy
xi2m, yi2m = segunda_interseccion.xy
xi3m, yi3m = tercera_interseccion.xy
xi4m, yi4m = cuarta_interseccion.xy
xi5m, yi5m = quinta_interseccion.xy
xi6m, yi6m = sexta_interseccion.xy
xi7m, yi7m = septima_interseccion.xy #Coordenadas del nuevo vértice M1
xi8m, yi8m = octava_interseccion.xy #Coordenadas del nuevo vértice M2

#Cambiamos el formato de matriz a float
xi1 = np.float64(np.array(xi1m))
xi2 = np.float64(np.array(xi2m))
xi3 = np.float64(np.array(xi3m))
xi4 = np.float64(np.array(xi4m))
xi5 = np.float64(np.array(xi5m))
xi6 = np.float64(np.array(xi6m))
xi7 = np.float64(np.array(xi7m)) #Nueva coordenada en x (Máquina 1)
xi8 = np.float64(np.array(xi8m)) #Nueva coordenada en x (Máquina 2)
yi1 = np.float64(np.array(yi1m))
yi2 = np.float64(np.array(yi2m))
yi3 = np.float64(np.array(yi3m))
yi4 = np.float64(np.array(yi4m))
yi5 = np.float64(np.array(yi5m))
yi6 = np.float64(np.array(yi6m))
yi7 = np.float64(np.array(yi7m)) #Nueva coordenada en y (Máquina 1)
yi8 = np.float64(np.array(yi8m)) #Nueva coordenada en y (Máquina 2)

#literales de las intersecciones (nombres en el gráfico)
plt.annotate(' A', (xi4, yi4))
plt.annotate(' B', (xi1, yi1))
plt.annotate(' C', (xi2, yi2))
plt.annotate(' D', (xi3, yi3))
plt.annotate(' E', (xi5, yi5))
plt.annotate(' F', (xi6, yi6)) 
plt.annotate(' G', (xi7, yi7)) #Nombrar el nuevo vértice como G
plt.annotate(' H', (xi8, yi8)) #Nombrar el nuevo vértice como H

#Evaluando la función objetivo en cada vértice
FOi1 = (xi1 * 30) + (yi1 * 20)
FOi2 = (xi2 * 30) + (yi2 * 20)
FOi3 = (xi3 * 30) + (yi3 * 20)
FOi4 = (xi4 * 30) + (yi4 * 20)
FOi7 = (xi7 * 30) + (yi7 * 20) #Calcular la FO en el nuevo vértice G
FOi8 = (xi8 * 30) + (yi8 * 20) #Calcular la FO en el nuevo vértice H

#Calculando el mejor resultado (Maximizar)
ZMAX = max(FOi1, FOi2, FOi3, FOi4)

#Imprimiendo la solución óptima en la consola
print('\n SOLUCIÓN ÓPTIMA')
print('Solución óptima: {} '.format(ZMAX))
print('Función objetivo en punto G: {} '.format(FOi7))
print('Función objetivo en punto H: {} '.format(FOi8))

#Ordenando las coordenadas de los vértices (Las coordenadas x en m y las coordenadas y en n)
m = [xi1, xi2, xi3, xi4]
n = [yi1, yi2, yi3, yi4]

#Graficando el polígono solución a partir de las coordenadas de los vértices (importante el orden según las manecillas)
plt.fill(m, n, color='silver')

#Identificando el índice del vértice de la mejor solución
dict1 = {0:FOi1, 1:FOi2, 2:FOi3, 3:FOi4}
posicion = max(dict1, key=dict1.get)

#Obteniendo las coordenadas del vértice de la mejor solución de acuerdo al índice del paso anterior
XMAX = m[posicion]
YMAX = n[posicion]

#Imprimiendo las coordenadas del vértice de la mejor solución (variables de decisión)
print('\n VARIABLES DE DECISIÓN')
print('Cantidad de producto X1 a producir: {} unidades'.format(XMAX))
print('Cantidad de producto X2 a producir: {} unidades'.format(YMAX))

#Precio dual (Restricción 1)
Dual1 = (FOi7 - ZMAX) #Calculamos el precio dual para la restricción 1
Dual2 = (FOi8 - ZMAX) #Calculamos el precio dual para la restricción 1

#Imprimir los precios duales
print('\n ANÁLISIS DE SENSIBILIDAD')
print('Precio dual de la máquina 1: {} $/h'.format(Dual1)) #Imprimimos el precio dual 1
print('Precio dual de la máquina 2: {} $/h'.format(Dual2)) #Imprimimos el precio dual 2

#Intervalos de factibilidad (Máquina 1)
IFmin1 = (2 * xi1) + yi1
IFmax1 = (2 * xi6) + yi6

#Intervalos de factibilidad (Máquina 2)
IFmin2 = xi3 + (3 * yi3)
IFmax2 = xi5 + (3 * yi5)

#Imprimir los intervalos de factibilidad
print('\n INTERVALOS DE FACTIBILIDAD')
print('Límite mínimo de factibilidad (PD máquina 1): {} h'.format(IFmin1))
print('Límite máximo de factibilidad (PD máquina 1): {} h'.format(IFmax1))
print('Límite mínimo de factibilidad (PD máquina 2): {} h'.format(IFmin2))
print('Límite máximo de factibilidad (PD máquina 2): {} h'.format(IFmax2))


#Configuraciones adicionales del gráfico
plt.grid()
plt.xlabel('X1')
plt.ylabel('X2')
plt.title('JOBCO')

plt.show()
</code></pre>
</div>
<hr />
<p>En el próximo artículo desarrollaremos el segundo caso de análisis de sensibilidad: <em>cambios en la utilidad unitaria o el costo unitario.</em></p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/analisis-de-sensibilidad-grafica-mediante-el-uso-de-python-caso-1/">Análisis de sensibilidad gráfica mediante el uso de Python (Caso 1)</a> se publicó primero en <a href="https://ingenieriaindustrialonline.com">Ingenieria Industrial Online</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ingenieriaindustrialonline.com/investigacion-de-operaciones/analisis-de-sensibilidad-grafica-mediante-el-uso-de-python-caso-1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Método gráfico de la programación lineal mediante el uso de Python</title>
		<link>https://ingenieriaindustrialonline.com/investigacion-de-operaciones/metodo-grafico-de-la-programacion-lineal-mediante-el-uso-de-python/</link>
					<comments>https://ingenieriaindustrialonline.com/investigacion-de-operaciones/metodo-grafico-de-la-programacion-lineal-mediante-el-uso-de-python/#comments</comments>
		
		<dc:creator><![CDATA[Bryan Salazar López]]></dc:creator>
		<pubDate>Sat, 17 Jul 2021 19:50:16 +0000</pubDate>
				<category><![CDATA[Investigación de operaciones]]></category>
		<category><![CDATA[Investigación de Operaciones]]></category>
		<category><![CDATA[Método gráfico]]></category>
		<category><![CDATA[Optimización]]></category>
		<category><![CDATA[Programación lineal]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Solución gráfica]]></category>
		<guid isPermaLink="false">https://ingenieriaindustrialonline.com/?p=26194</guid>

					<description><![CDATA[<p>Tal como lo mencionamos en el artículo en el que abordamos inicialmente los pasos de resolución gráfica de los modelos de programación lineal; dada la limitación en la cantidad de variables que puede soportar el método gráfico (2 variables), y dada la forma manual de resolución del mismo, este es difícilmente útil en la práctica. &#8230;</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/metodo-grafico-de-la-programacion-lineal-mediante-el-uso-de-python/">Método gráfico de la programación lineal mediante el uso de Python</a> se publicó primero en <a href="https://ingenieriaindustrialonline.com">Ingenieria Industrial Online</a>.</p>
]]></description>
										<content:encoded><![CDATA[
		<div id="introduccion" data-title="Introducción" class="index-title"></div>
	
<p>Tal como lo mencionamos en el artículo en el que abordamos inicialmente los pasos de <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/metodo-grafico/"><em><strong>resolución gráfica</strong></em></a> de los modelos de <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/programacion-lineal/"><strong>programación lineal</strong></a>; dada la limitación en la cantidad de variables que puede soportar el método gráfico (2 variables), y dada la forma manual de resolución del mismo, este es difícilmente útil en la práctica.</p>
<h3>¿Por qué debería aprender a solucionar gráficamente un modelo de PL?</h3>

		<div id="por-que-deberia-aprender-a-solucionar-graficamente-un-modelo-de-pl" data-title="¿Por qué debería aprender a solucionar gráficamente un modelo de PL?" class="index-title"></div>
	
<p>La solución gráfica de los modelos de programación lineal, puede proporcionar una perspectiva que permita un entendimiento más amplio de los métodos generales de resolución (<a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/metodo-simplex/"><strong>método simplex</strong></a> o solucionadores). Del mismo modo, permite una mayor comprensión de los diversos elementos que componen un modelo de PL (dado su componente visual), siendo especialmente útil en el aprendizaje de diferentes tópicos como pueden ser: <em>tipos de solución, tipos de restricciones y análisis de sensibilidad</em>.</p>
<h3>¿Solo puedo solucionar gráficamente un modelo de PL de manera manual?</h3>
<p>Si bien hemos reconocido las bondades del aprendizaje de la solución gráfica, razón por la cual su enseñanza perdura en la academia; también hemos de reconocer que la naturaleza manual de sus cálculos y procedimientos gráficos, pueden hacer tedioso su aprendizaje.</p>
<p>Ahora bien, es preciso considerar que gran parte de los programas solucionadores de modelos PL cuentan con algún módulo gráfico interactivo (TORA, WinQSB, por ejemplo), que puede remplazar los procedimientos manuales. Así entonces, existen otras alternativas a los procedimientos y cálculos manuales, que permiten lograr un acercamiento más ágil al método de solución gráfica de PL.</p>
<h2>Solución gráfica de programación lineal mediante Python</h2>
<p>Ya hemos justificado de manera suficiente la permanencia del método gráfico en los programas de enseñanza de <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/que-es-la-investigacion-de-operaciones/"><strong>Investigación de Operaciones</strong></a>; sin embargo, es necesario reconocer la posibilidad actual de integrar diversas disciplinas a través de los procesos de aprendizaje que enriquezcan la formación en la materia.</p>
<p>El objetivo de este artículo consiste precisamente en abordar el método gráfico como alternativa de solución de modelos de programación lineal, al tiempo que generamos un código en Python (programación), que nos permita automatizar procedimientos gráficos y cálculos.</p>
<p>El propósito de integrar un lenguaje de programación como lo es Python, consiste en acercar a las personas a la posibilidad de integrar métodos tradicionales de la investigación de operaciones con herramientas tecnológicas vigentes. <em>¿Por qué Python? </em>Porque es gratuito; está respaldado por los desarrollos de una gran comunidad (casi que existe una línea de código desarrollado para cada requerimiento); sus aplicaciones no se limitan a un área en concreto, y por lo tanto podemos integrar diversos desarrollos a nuestros métodos.</p>
<p>En síntesis, queremos aportar nuevas propuestas en la enseñanza de la investigación de operaciones a través de la programación.</p>
<hr />
<h3>Requisitos técnicos</h3>

		<div id="requisitos-tecnicos" data-title="Requisitos técnicos" class="index-title"></div>
	
<p>Los requisitos técnicos varían de acuerdo a si queremos ejecutar los códigos en nuestro equipo, o si queremos utilizar un entorno colaborativo (<em>recomendado</em>).</p>
<h4><em>Requisitos en nuestro equipo</em></h4>

		<div class="checklist tie-list-shortcode">
<ul>
<li>Tener una versión de Python instalada (preferiblemente una versión posterior a 3.6): <a href="https://www.python.org/downloads/release/python-380/"><strong>Descargar Python 3.8x 64-bit</strong></a></li>
<li>Tener una versión de <em>pip</em> (paquetes de instalación) de Python superior a 9.01 (Python 3.4 o superiores vienen con <em>pip</em> incorporado). Esto le permitirá instalar librerías con un comando simple y directo: <em>pip</em>.</li>
<li>Tener un editor para código, nosotros recomendamos un editor simple, por ejemplo: Sublime Text: <a href="https://www.sublimetext.com/3"><strong>Descargar Sublime Text</strong></a><strong>. </strong>También puede utilizar un IDE (Entorno de Desarrollo Integrado), como <em><strong>Spyder.</strong></em> Todo dependerá del alcance de su proyecto.</li>
</ul>

		</div>
	
<h4><em>Requisitos en un entorno colaborativo</em></h4>
<p>Podemos utilizar del mismo modo, un entorno virtual. En este caso recomendamos el uso de <em><strong>Colaboratory de Google</strong></em>, un entorno que cuenta con todas las herramientas necesarias para nuestros desarrollos. No tendremos que instalar nada en nuestro equipo, y aprovecharemos la potencia de las máquinas de Google.</p>
<hr />
<h3>Librerías necesarias</h3>

		<div id="librerias-necesarias" data-title="Librerías necesarias" class="index-title"></div>
	
<p>Con la instalación de los programas, o el uso de un entorno colaborativo, ya estamos listos para empezar a programar, sin embargo, cada desarrollo, por pequeño que este sea, tiene sus particularidades; y existen herramientas (librerías) que nos facilitan considerablemente nuestros desarrollos, de acuerdo a nuestras necesidades. Para colocarlo en perspectiva, piense en se teléfono celular, tenemos diferentes <em>apps</em>, cada una de ellas nos facilita algunas tareas, de acuerdo a nuestras necesidades; pues bien, así funcionan las librerías en Python.</p>
<p>El desarrollo que queremos lograr requiere de las siguientes librerías:</p>

		<div class="checklist tie-list-shortcode">
<ul>
<li><strong>Numpy</strong>: Numpy es una librería (biblioteca) que contiene un conjunto amplio de soluciones especializadas en cálculos matemáticos de alto nivel. Numpy nos facilita la vida a la hora de trabajar con matrices, vectores, rangos, etc.</li>
</ul>

		</div>
	
<p>Instalar una librería en Python es muy sencillo, de ahí la importancia de contar con <em>pip</em> (paquetes de instalación). <em>Pip </em>nos permite instalar cualquier librería con un comando escrito en la <span class="tie-highlight tie-highlight-black"><em><strong>Lista de comandos de Windows (CMD)</strong></em></span>. Recuerde que si utiliza un entorno colaborativo, este incluye gran parte de las librerías necesarias.</p>

		<div class="box info  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span> Para abrir la <em><strong>Lista de comandos de Windows </strong></em>pulsa a la vez la tecla de Windows (normalmente tiene el logotipo de Microsoft, está ubicada cerca de la tecla Alt) y la letra R. Se te abrirá una pequeña ventana con el título de «Ejecutar». Dentro del rectángulo para introducir texto que verás en la ventana, escribe cmd y pulsa sobre el botón de «Aceptar».
			</div>
		</div>
	
<p>Para instalar Numpy tan solo debemos escribir el siguiente comando en la lista de comandos: <span>pip install numpy</span></p>
<figure id="attachment_26196" aria-describedby="caption-attachment-26196" style="width: 559px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Numpy.jpg" alt="Numpy" width="559" height="159" class="wp-image-26196 size-full" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Numpy.jpg 559w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Numpy-300x85.jpg 300w" sizes="(max-width: 559px) 100vw, 559px" /><figcaption id="caption-attachment-26196" class="wp-caption-text">Figura 1: Comando para instalar librería Numpy</figcaption></figure>
<p>Damos <em><strong>ENTER </strong></em>y veremos lo siguiente:</p>
<figure id="attachment_26197" aria-describedby="caption-attachment-26197" style="width: 575px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Numpy2.jpg" alt="Numpy2" width="575" height="301" class="wp-image-26197 size-full" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Numpy2.jpg 575w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Numpy2-300x157.jpg 300w" sizes="(max-width: 575px) 100vw, 575px" /><figcaption id="caption-attachment-26197" class="wp-caption-text">Figura 2: Proceso de descarga de librería Numpy finalizado</figcaption></figure>
<p>Así de sencillo es instalar una librería en Python.</p>

		<div class="checklist tie-list-shortcode">
<ul>
<li><strong>Matplotlib</strong>: Matplotlib es una librería (biblioteca) completa para crear visualizaciones estáticas, animadas e interactivas en Python. Y bien, si queremos abordar el método gráfico, necesitamos una librería que nos ayude con las gráficas.</li>
</ul>

		</div>
	
<p>Para instalar Matplotlib tan solo debemos escribir el siguiente comando en la lista de comandos: pip install matplotlib</p>

		<div class="checklist tie-list-shortcode">
<ul>
<li><strong>Shapely</strong>: Shapely es una librería (biblioteca) completa que nos permite la manipulación y análisis de objetos geométricos. Nos resultará de mucha ayuda al momento de manipular nuestras gráficas.</li>
</ul>

		</div>
	
<p>Para instalar Shapely tan solo debemos escribir el siguiente comando en la lista de comandos: pip install Shapely</p>
<p>Así de sencillo es instalar librerías en Python. Con estas librerías estamos listos para crear nuestro desarrollo.</p>
<hr />
<h2>El problema</h2>
<blockquote class=" quote-simple "><p>Un autobús que hace el recorrido Cali-Buga, ofrece asientos para fumadores al precio de 10.000 pesos y a no fumadores al precio de 6.000 pesos. Al no fumador se le deja llevar 50 Kg. de peso y al fumador 20 Kg. Si el autobús tiene 90 asientos y admite un equipaje de hasta 3.000 Kg. ¿Cuál ha de ser la oferta de asientos de la compañía para cada tipo de pasajeros, con la finalidad de optimizar el beneficio? Además, debe considerarse que por políticas de la empresa, deben ofrecerse cómo mínimo 10 asientos para pasajeros no fumadores.</p></blockquote>
<h3>Modelamiento mediante programación lineal</h3>
<p><em><strong>Variables</strong></em></p>
<p><strong>x</strong>: Cantidad de asientos reservados a fumadores.</p>
<p><strong>y</strong>: Cantidad de asientos reservados a no fumadores.</p>
<p><em><strong>Restricciones</strong></em></p>
<p>20<strong>x</strong> + 50<strong>y</strong> &lt;= 3000 <em>(Equipaje permitido)</em></p>
<p><strong>x</strong> + <strong>y</strong> &lt;= 90 <em>(Cantidad de asientos disponibles)</em></p>
<p><strong>y</strong> &gt;= 10 <em>(Política de asientos mínimos para no fumadores)</em></p>
<p><strong>y</strong> &gt;= 0 <em>(No negatividad)</em></p>
<p><strong>x</strong> &gt;= 0 <em>(No negatividad)</em></p>
<p><em><strong>Función objetivo </strong></em></p>
<p><em><strong>z = </strong></em>10000<strong>x</strong> + 6000<strong>y  </strong><em>(Maximizar)</em></p>
<hr />
<h2>Método gráfico mediante Python</h2>
<h3>Paso 1: Importar las librerías</h3>

		<div id="paso-1-importar-las-librerias" data-title="Paso 1: Importar las librerías" class="index-title"></div>
	
<p>El siguiente fragmento de código importa las librerías necesarias para nuestro desarrollo:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Librerías necesarias
import matplotlib.pyplot as plt
import numpy as np
from shapely.geometry import LineString
</code></pre>
</div>
<h3>Paso 2: Ecuaciones e intervalos</h3>

		<div id="paso-2-ecuaciones-e-intervalos" data-title="Paso 2: Ecuaciones e intervalos" class="index-title"></div>
	
<p>Para poder graficar las restricciones (paso esencial del método gráfico), es necesario representar las ecuaciones por medio de líneas en nuestra gráfica. Cada restricción estará representada por una línea recta. El paso que antecede trazar una línea recta consiste en la determinación de un mínimo de dos puntos que al unirse la conformen.</p>
<p>Cada punto en el plano cartesiano se encuentra conformado por una coordenada en <em><strong>x</strong> </em>y una coordenada en <em><strong>y</strong> </em>(en el caso que así definamos llamar a la abscisa y a la ordenada). Recordemos que a partir del modelo algebraico inicial, nuestras restricciones se encuentran representadas por ecuaciones. Así entonces, la tarea consiste en, a partir de una ecuación, obtener un conjunto mínimo de dos coordenadas.</p>
<p>Manualmente este proceso se realiza tabulando, es decir, despejando el valor de una de las variables de la ecuación, a partir de la asignación arbitraria de un valor a la variable restante.</p>
<p>La tarea que tenemos mediante la programación en Python consistirá entonces en automatizar este proceso.</p>
<p>Lo primero que debemos hacer es despejar cada una de las inecuaciones convertidas en ecuaciones del problema, para eso, en nuestro caso, vamos a despejar en función de <em><strong>y</strong></em>:</p>
<p>Por ejemplo, para nuestra <strong>primera restricción</strong>:</p>
<p>20<strong>x</strong> + 50<strong>y</strong> &lt;= 3000 <em>(Inecuación)</em></p>
<p>20<strong>x</strong> + 50<strong>y</strong> = 3000 <em>(Ecuación)</em></p>
<p><strong>y</strong> = (3000 &#8211; 20<strong>x</strong>) / 50 <em>(Despejamos <strong>y</strong>)</em></p>
<p><strong>y1</strong> = (3000 &#8211; 20<strong>x</strong>) / 50 <em>(Asignamos un identificador único a <strong>y</strong>)</em></p>
<p>Repetimos el procedimiento para nuestra <strong>segunda restricción</strong>:</p>
<p><strong>x</strong> + <strong>y</strong> &lt;= 90 <em>(Inecuación)</em></p>
<p><strong>x</strong> + <strong>y</strong> = 90 <em>(Ecuación)</em></p>
<p><strong>y</strong> = 90 &#8211; <strong>x</strong> <em>(Despejamos <strong>y</strong>)</em></p>
<p><strong>y2</strong> = 90 &#8211; <strong>x</strong> <em>(Asignamos un identificador único a <strong>y</strong>)</em></p>
<p>En el caso de la <strong>tercera restricción</strong>:</p>
<p><strong>y</strong> &gt;= 10 <em>(Inecuación)</em></p>
<p><strong>y</strong> = 10 <em>(Ecuación)</em></p>
<p>En este caso, dado que la intención es graficar, es fundamental que cada ecuación contenga las dos variables. Dado que en la ecuación original la variable <em><strong>x </strong></em>no hace parte, podemos incluirla multiplicándola por 0. Es decir, para todos los valores que tome <em><strong>x </strong></em>la ecuación permanecerá inalterable.</p>
<p><strong>y</strong> = 10 + (0 * <strong>x</strong>) <em>(Ecuación, <strong>y</strong> ya se encuentra despejada)</em></p>
<p><strong>y3</strong> = 10 + (0 * <strong>x</strong>) <em>(Asignamos un identificador único a <strong>y</strong>)</em></p>
<p>En el caso de la <strong>cuarta restricción</strong>:</p>
<p><strong>y</strong> &gt;= 0 <em>(Inecuación)</em></p>
<p><strong>y</strong> = 0 <em>(Ecuación)</em></p>
<p>En este caso, dado que la intención es graficar, es fundamental que cada ecuación contenga las dos variables. Dado que en la ecuación original la variable <em><strong>x </strong></em>no hace parte, podemos incluirla multiplicándola por 0. Es decir, para todos los valores que tome <em><strong>x </strong></em>la ecuación permanecerá inalterable.</p>
<p><strong>y</strong> = 0 * <strong>x</strong> <em>(Ecuación, <strong>y</strong> ya se encuentra despejada)</em></p>
<p><strong>y4</strong> = 0 * <strong>x</strong> <em>(Asignamos un identificador único a <strong>y</strong>)</em></p>
<p>Todas las ecuaciones anteriores tienen algo en común: Se encuentran despejadas para obtener el valor de <em><strong>y </strong></em>a partir de <em><strong>x</strong></em><em>, </em>de manera que necesitamos alguna función que nos permita asignar diferentes valores a <em><strong>x </strong></em>en un rango dado. Para eso utilizaremos la función <strong><em>np.arange.</em></strong></p>
<p style="text-align: center;"><strong>x </strong>= <strong>np.arange</strong>(-100, 150, 50)</p>
<p>Esta función permite asignar a <em><strong>x</strong></em> diferentes valores de acuerdo a unos argumentos dados (<em>valor mínimo, valor máximo, intervalo o paso</em>). Es decir que de acuerdo a la anterior línea de código, a la variable <em><strong>x </strong></em>le serán asignados diversos valores desde el valor <em>-100 </em>hasta el valor <em>150 </em>con intervalos de <em>50. </em>Así entonces, tomará los siguientes valores:</p>
<table border="0" cellpadding="0" cellspacing="0" width="80" style="border-collapse: collapse; width: 60pt;" class=" aligncenter">
<tbody>
<tr height="20" style="height: 15.0pt;">
<td height="20" width="80" style="height: 15pt; width: 60pt; text-align: center;"><em><strong>x</strong></em></td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" align="right" style="height: 15pt; text-align: center;">-100</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" align="right" style="height: 15pt; text-align: center;">-50</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" align="right" style="height: 15pt; text-align: center;">0</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" align="right" style="height: 15pt; text-align: center;">50</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" align="right" style="height: 15pt; text-align: center;">100</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" align="right" style="height: 15pt; text-align: center;">150</td>
</tr>
</tbody>
</table>
<p>Dado que las ecuaciones que pretenden hallar <em><strong>y1, y2, y3 </strong></em>y <em><strong>y4 </strong></em>son dependientes de <em><strong>x</strong></em><em>, </em>tomarán sus valores respectivos de acuerdo a los resultados de cada ecuación, para cada valor de <em><strong>x</strong></em>:</p>
<table border="0" cellpadding="0" cellspacing="0" width="400" style="border-collapse: collapse; width: 300pt;" class=" aligncenter">
<tbody>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl66" width="80" style="height: 15pt; width: 60pt;"><em><strong>x</strong></em></td>
<td class="xl66" width="80" style="width: 60pt;"><em><strong>y1</strong></em></td>
<td class="xl66" width="80" style="width: 60pt;"><em><strong>y2</strong></em></td>
<td class="xl66" width="80" style="width: 60pt;"><em><strong>y3</strong></em></td>
<td class="xl66" width="80" style="width: 60pt;"><em><strong>y4</strong></em></td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15.0pt;">-100</td>
<td class="xl65">100</td>
<td class="xl65">190</td>
<td class="xl65">10</td>
<td class="xl65">0</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15.0pt;">-50</td>
<td class="xl65">80</td>
<td class="xl65">140</td>
<td class="xl65">10</td>
<td class="xl65">0</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15.0pt;">0</td>
<td class="xl65">60</td>
<td class="xl65">90</td>
<td class="xl65">10</td>
<td class="xl65">0</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15.0pt;">50</td>
<td class="xl65">40</td>
<td class="xl65">40</td>
<td class="xl65">10</td>
<td class="xl65">0</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15.0pt;">100</td>
<td class="xl65">20</td>
<td class="xl65">-10</td>
<td class="xl65">10</td>
<td class="xl65">0</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15pt;">150</td>
<td class="xl65">0</td>
<td class="xl65">-60</td>
<td class="xl65">10</td>
<td class="xl65">0</td>
</tr>
</tbody>
</table>
<p>La última de nuestras restricciones (<strong>quinta restricción</strong>), está dada en función de hallar <em><strong>x </strong></em>a partir <em><strong>y</strong></em>, de manera que efectuamos la misma tarea en un sentido inverso:</p>
<p><strong>x</strong> &gt;= 0 <em>(Inecuación)</em></p>
<p><strong>x</strong> = 0 <em>(Ecuación)</em></p>
<p>En este caso, dado que la intención es graficar, es fundamental que cada ecuación contenga las dos variables. Dado que en la ecuación original la variable <em><strong>y </strong></em>no hace parte, podemos incluirla multiplicándola por 0. Es decir, para todos los valores que tome <em><strong>y </strong></em>la ecuación permanecerá inalterable.</p>
<p><strong>x</strong> = 0 * <strong>y</strong> <em>(Ecuación, <strong>x</strong> ya se encuentra despejada)</em></p>
<p><strong>x1</strong> = 0 * <strong>y</strong> <em>(Asignamos un identificador único a <strong>x</strong>)</em></p>
<p>En este caso, ya que requerimos que <em><strong>y </strong></em>tome diversos valores, utilizaremos la función <em><strong>np.arange.</strong></em></p>
<p style="text-align: center;"><strong>y </strong>= <strong>np.arange</strong>(-100, 150, 50)</p>
<p>Esta función permite asignar a <em><strong>y</strong></em> diferentes valores de acuerdo a unos argumentos dados (<em>valor mínimo, valor máximo, intervalo o paso</em>). Es decir que de acuerdo a la anterior línea de código, a la variable <em><strong>y </strong></em>le serán asignados diversos valores desde el valor <em>-100 </em>hasta el valor <em>150 </em>con intervalos de <em>50. </em>Así entonces, tomará los siguientes valores:</p>
<table border="0" cellpadding="0" cellspacing="0" width="80" style="border-collapse: collapse; width: 60pt;" class=" aligncenter">
<tbody>
<tr height="20" style="height: 15.0pt;">
<td height="20" width="80" style="height: 15pt; width: 60pt; text-align: center;"><em><strong>y</strong></em></td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" align="right" style="height: 15pt; text-align: center;">-100</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" align="right" style="height: 15pt; text-align: center;">-50</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" align="right" style="height: 15pt; text-align: center;">0</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" align="right" style="height: 15pt; text-align: center;">50</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" align="right" style="height: 15pt; text-align: center;">100</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" align="right" style="height: 15pt; text-align: center;">150</td>
</tr>
</tbody>
</table>
<p>Dada que nuestra quinta restricción pretende hallar <em><strong>x1</strong></em> a partir de los valores de <em><strong>y, </strong></em>tendríamos lo siguiente:</p>
<table border="0" cellpadding="0" cellspacing="0" width="160" style="border-collapse: collapse; width: 120pt;" class=" aligncenter">
<tbody>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl66" width="80" style="height: 15.0pt; width: 60pt;"><em><strong>y</strong></em></td>
<td class="xl66" width="80" style="width: 60pt;"><em><strong>x1</strong></em></td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15.0pt;">-100</td>
<td class="xl65">0</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15.0pt;">-50</td>
<td class="xl65">0</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15.0pt;">0</td>
<td class="xl65">0</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15.0pt;">50</td>
<td class="xl65">0</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15.0pt;">100</td>
<td class="xl65">0</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15.0pt;">150</td>
<td class="xl65">0</td>
</tr>
</tbody>
</table>
<p>Por último, consideramos la inclusión de la <em><strong>función objetivo</strong></em><strong>, </strong>para ello:</p>
<p>10000<strong>x</strong> + 6000<strong>y</strong> = 0 <em>(Ecuación)</em></p>
<p><strong>y</strong> = (- 10000<strong>x</strong>) / 6000 <em>(Despejamos <strong>y</strong>)</em></p>
<p><strong>y5</strong> = (- 10000<strong>x</strong>) / 6000 <em>(Asignamos un identificador único a <strong>y</strong>)</em></p>
<p>En este caso, la función que ya asignamos a <em><strong>x </strong></em>(np.arange), nos prestará los valores necesarios para tabular <em><strong>y5</strong></em>.</p>
<p>Lo que hicimos hasta ahora consiste en explicar con alto grado de detalle la función de cada una las líneas del código que utilizaremos en Python. Todo lo anterior queda reducido al siguiente fragmento:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Ecuaciones e intervalos (Para tabular)
x = np.arange(-100, 150, 50)
y1 = (3000 - (20 * x))/ 50
y2 = 90 - x
y3 = 10 + (0 * x)
y4 = 0 * x
y5 = (-10000 * x) / 6000
y = np.arange(-100, 150, 50)
x1 = 0 * y
</code></pre>
</div>
<h3>Paso 3: Tabular coordenadas e identificar las líneas</h3>

		<div id="paso-3-tabular-coordenadas-e-identificar-las-lineas" data-title="Paso 3: Tabular coordenadas e identificar las líneas" class="index-title"></div>
	
<p>En el paso anterior desarrollamos unas líneas de código que representan los cálculos correspondientes a cada una de las ecuaciones del modelo. Si bien con fines prácticos mostramos la forma en que se tabularían los datos, es hasta este paso en que la información se organiza en tablas (propiamente matrices de dos columnas: <em><strong>x </strong></em>y <em><strong>y</strong></em>). La información se organiza a partir de una instancia básica de la librería <em>Numpy, </em>tal como se explicará a continuación:</p>
<p style="text-align: center;"><strong>np.column_stack</strong>((x, y1))</p>
<p>Esta instancia tomará los valores del <strong><em>paso 1</em></strong> y los tabulará en una matriz 2D (dos columnas). En este ejemplo:</p>
<table border="0" cellpadding="0" cellspacing="0" width="160" style="border-collapse: collapse; width: 120pt;" class=" aligncenter">
<tbody>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl66" width="80" style="height: 15.0pt; width: 60pt;">x</td>
<td class="xl66" width="80" style="width: 60pt;">y1</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15.0pt;">-100</td>
<td class="xl65">100</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15.0pt;">-50</td>
<td class="xl65">80</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15.0pt;">0</td>
<td class="xl65">60</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15.0pt;">50</td>
<td class="xl65">40</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15.0pt;">100</td>
<td class="xl65">20</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" class="xl65" style="height: 15.0pt;">150</td>
<td class="xl65">0</td>
</tr>
</tbody>
</table>
<p>El siguiente paso consiste en, a partir de una instancia básica de la librería <em>Shapely, </em>generar la línea correspondiente a cada ecuación de acuerdo al tabulado generado, tal como se aprecia a continuación:</p>
<p style="text-align: center;"><strong>LineString</strong>(<strong>np.column_stack</strong>((x, y1)))</p>
<p><em>LineString</em> es una instancia de la librería <em>Shapely </em>que permite unir cada punto (coordenada), de manera que genera una línea. Ahora bien, cada línea de código deberá corresponder o asociarse a una variable única que nos permitirá identificar cada una de las líneas, por ejemplo:</p>
<p style="text-align: center;"><strong>primera_línea</strong> = <strong>LineString</strong>(<strong>np.column_stack</strong>((x, y1)))</p>
<p>Realizamos el mismo procedimiento para cada una de las líneas, siendo cuidadosos al momento de asignar las variables asociadas a cada una de las líneas:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Identificadores para las líneas
primera_linea = LineString(np.column_stack((x, y1)))
segunda_linea = LineString(np.column_stack((x, y2)))
tercera_linea = LineString(np.column_stack((x, y3)))
cuarta_linea = LineString(np.column_stack((x1, y)))
quinta_linea = LineString(np.column_stack((x, y4)))
sexta_linea = LineString(np.column_stack((x, y5)))
</code></pre>
</div>
<p>Podemos observar como cada conjunto de variables corresponde estrictamente a cada una de las líneas asociadas a cada ecuación en particular.</p>
<h3>Paso 4: Graficar las líneas</h3>

		<div id="paso-4-graficar-las-lineas" data-title="Paso 4: Graficar las líneas" class="index-title"></div>
	
<p>En este paso vamos a utilizar la librería <em>Matplotlib </em>para graficar nuestras líneas (ecuaciones).</p>

		<div class="clearfix"></div>
		<div class="toggle tie-sc-close">
			<h3 class="toggle-head">Colores de línea <span class="fa fa-angle-down" aria-hidden="true"></span></h3>
			<div class="toggle-content">
<table class="table table-bordered table-striped">
<tbody>
<tr>
<th style="text-align: center;">Alias</th>
<th style="text-align: center;">Color</th>
</tr>
</tbody>
<tbody>
<tr>
<td style="text-align: center;">b</td>
<td style="text-align: center;">Azul</td>
</tr>
<tr>
<td style="text-align: center;">g</td>
<td style="text-align: center;">Verde</td>
</tr>
<tr>
<td style="text-align: center;">r</td>
<td style="text-align: center;">Rojo</td>
</tr>
<tr>
<td style="text-align: center;">c</td>
<td style="text-align: center;">Cyan</td>
</tr>
<tr>
<td style="text-align: center;">m</td>
<td style="text-align: center;">Magenta</td>
</tr>
<tr>
<td style="text-align: center;">y</td>
<td style="text-align: center;">Amarillo</td>
</tr>
<tr>
<td style="text-align: center;">k</td>
<td style="text-align: center;">Negro</td>
</tr>
<tr>
<td style="text-align: center;">w</td>
<td style="text-align: center;">Blanco</td>
</tr>
</tbody>
</table>

			</div>
		</div>
	

		<div class="clearfix"></div>
		<div class="toggle tie-sc-close">
			<h3 class="toggle-head">Tipos de línea <span class="fa fa-angle-down" aria-hidden="true"></span></h3>
			<div class="toggle-content">
<table class="table table-bordered table-striped">
<tbody>
<tr>
<th style="text-align: center;">Estilo de línea</th>
</tr>
</tbody>
<tbody>
<tr>
<td style="text-align: center;">&#8211;</td>
<td><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/linea1-150x10.jpg" alt="" width="150" height="10" class="aligncenter size-thumbnail wp-image-26201" /></td>
</tr>
<tr>
<td style="text-align: center;">&#8211; &#8211;</td>
<td><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/linea2-150x10.jpg" alt="" width="150" height="10" class="aligncenter size-thumbnail wp-image-26202" /></td>
</tr>
<tr>
<td style="text-align: center;">:</td>
<td><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/linea3-150x10.jpg" alt="línea3" width="150" height="10" class="aligncenter size-thumbnail wp-image-26203" /></td>
</tr>
<tr>
<td style="text-align: center;">: &#8211;</td>
<td><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/linea4-150x10.jpg" alt="línea4" width="150" height="10" class="aligncenter size-thumbnail wp-image-26204" /></td>
</tr>
</tbody>
</table>

			</div>
		</div>
	
<p>El argumento <em>linewidth </em>determinará el grosor de la línea. Debemos considerar asignar las mismas variables que en el paso anterior.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Graficando las líneas
plt.plot(x, y1, '-', linewidth=2, color='b')
plt.plot(x, y2, '-', linewidth=2, color='g')
plt.plot(x, y3, '-', linewidth=2, color='r')
plt.plot(x1, y, '-', linewidth=2, color='y')
plt.plot(x, y4, '-', linewidth=2, color='k')
plt.plot(x, z, ':', linewidth=1, color='k')
</code></pre>
</div>
<p>Ya en este paso tenemos lo suficiente para esbozar nuestras líneas, sin embargo es necesario crear algunas configuraciones generales de nuestra gráfica, y aunque estas líneas de código van al cierre, nos adelantaremos para ir conociendo la evolución parcial de nuestro desarrollo.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Configuraciones adicionales del gráfico
plt.grid()
plt.xlabel('Asientos para fumadores')
plt.ylabel('Asientos para no fumadores')
plt.title('Método Gráfico')

plt.show()
</code></pre>
</div>
<p>Estos ajustes permiten asignar los títulos de los ejes, así como el título general del gráfico, así mismo especifica la función que permite que el resultado del código se muestre como imagen.</p>
<p>En este paso queremos ejecutar el código parcial. Nosotros utilizaremos <em>Google Colaboratory</em>, puedes ver la ejecución en nuestro cuaderno: <a href="https://colab.research.google.com/drive/1EFa3Fb2nAB7ws6faGc73Me8KAhjYKqXM?usp=sharing"><em><strong>Método Gráfico</strong></em></a>.</p>
<figure id="attachment_26453" aria-describedby="caption-attachment-26453" style="width: 397px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Figura-4_Ecuaciones-representadas-en-lineas-Metodo-grafico.png" alt="Figura 4: Ecuaciones representadas en líneas (Método gráfico)" width="397" height="278" class="size-full wp-image-26453" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Figura-4_Ecuaciones-representadas-en-lineas-Metodo-grafico.png 397w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Figura-4_Ecuaciones-representadas-en-lineas-Metodo-grafico-300x210.png 300w" sizes="(max-width: 397px) 100vw, 397px" /><figcaption id="caption-attachment-26453" class="wp-caption-text">Figura 4: Ecuaciones representadas en líneas (Método gráfico)</figcaption></figure>
<p>&nbsp;</p>
<p>De manera que, de acuerdo al código ejecutado, nuestro programa es capaz de esbozar gráficamente cada una de nuestras ecuaciones sobre el plano cartesiano. Ya que incluso tenemos una representación de la función objetivo (línea punteada), e infiriendo el polígono factible (de acuerdo a la naturaleza de las restricciones: &lt;= o &gt;=), podemos geométricamente establecer cual es el vértice solución.</p>
<p>Ahora bien, podemos identificar que en la gráfica se pueden apreciar algunos polígonos, pero: <em>¿Cuál es nuestro polígono factible? </em>Bien, para eso debemos considerar la naturaleza de las restricciones; en cuyo caso, cada línea trazada dividirá el cuadrante solución en dos semiplanos: uno a cada lado de la línea trazada. Solo una de estas dos mitades satisface cada desigualdad, de manera que debemos considerar si cada restricción es «menor o igual», «mayor o igual», o en su defecto «igual». Por ejemplo:</p>
<figure id="attachment_26216" aria-describedby="caption-attachment-26216" style="width: 491px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/semiplanos.jpg" alt="semiplanos" width="491" height="322" class="wp-image-26216" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/semiplanos.jpg 563w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/semiplanos-300x197.jpg 300w" sizes="(max-width: 491px) 100vw, 491px" /><figcaption id="caption-attachment-26216" class="wp-caption-text">Figura 5: Semiplanos obtenidos a partir de una línea de ecuación</figcaption></figure>
<p>En la anterior gráfica (Figura 5) podemos observar la línea que representa la segunda restricción. Así mismo, podemos observar el concepto de semiplanos: <em><strong>A</strong> y <strong>B</strong> </em>(Uno a cada lado de la línea trazada). Como se trata de una restricción «menor o igual» (líneas hacia abajo y hacia la izquierda); solo la mitad <em><strong>A </strong></em>satisface la desigualdad.</p>
<figure id="attachment_26209" aria-describedby="caption-attachment-26209" style="width: 614px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/metodo_grafico2.jpg" alt="metodo_grafico2" width="614" height="460" class="wp-image-26209 size-full" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/metodo_grafico2.jpg 614w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/metodo_grafico2-300x225.jpg 300w" sizes="(max-width: 614px) 100vw, 614px" /><figcaption id="caption-attachment-26209" class="wp-caption-text">Figura 6: Polígono factible</figcaption></figure>
<p>En este caso representamos con flechas el lado, es decir la mitad que divide cada línea trazada, en el cual se encuentran los valores que satisfacen cada restricción. Las restricciones «menores o igual» apuntarán sus flechas hacia abajo y/o a la izquierda; los «mayores o igual» apuntarán sus flechas hacia arriba y/o a la derecha. Así entonces encontramos con suma facilidad nuestro polígono factible (zona gris).</p>
<h3>Paso 5: Determinar y graficar las intersecciones</h3>

		<div id="paso-5-determinar-y-graficar-las-intersecciones" data-title="Paso 5: Determinar y graficar las intersecciones" class="index-title"></div>
	
<p>Algunos textos, como por ejemplo <em>Investigación de Operaciones de </em><em>Taha</em>, consideran que los dos pasos fundamentales de la solución gráfica consisten en: determinar el espacio de soluciones factibles y determinar la solución óptima entre todos los puntos localizados en el espacio de soluciones.</p>
<p>Consideremos que el área gris de la Figura 6 corresponde al polígono o espacio de soluciones factibles. Todos los puntos (coordenadas en x, y) que se encuentran en este espacio, satisfacen al mismo tiempo todas las restricciones del modelo. Los puntos que se encuentra fuera, satisfacen algunas o ninguna de las restricciones.</p>
<p>Ahora bien, la cantidad de puntos dentro del espacio de soluciones factibles es sumamente grande, sin embargo, hemos de recordar que este método se rige bajo criterios de optimización. En nuestro ejemplo, este criterio es: <em>maximizar</em>. Recordemos que en programación lineal, la solución óptima siempre está asociada con un punto de esquina o vértice del polígono factible. Y que estos vértices se generan en cada punto de intersección de dos o más líneas, es decir, en el punto en que se igualan dos o más ecuaciones.</p>
<p>Lo anterior es sumamente importante, ya que para efectos de nuestro desarrollo en Python, podemos utilizar alguna función básica que, dadas las líneas, nos represente las intersecciones. En la práctica, determinar el punto de intersección de dos líneas requiere de la solución de un sistema de ecuaciones de 2 x 2, ya sea por el método de <em>sustitución, igualación, eliminación</em>, etc.</p>
<p>En nuestro caso, vamos a utilizar la función <strong>intersection</strong>() de Python. Lo que debemos hacer es determinar que intersecciones queremos determinar y graficar. Por ejemplo:</p>
<p>Si queremos determinar la intersección de la línea amarilla (cuarta línea, así la nombramos en el paso anterior) y la línea azul (primera línea), debemos escribir el siguiente código:</p>
<p style="text-align: center;">primera_interseccion = cuarta_linea.<strong>intersection</strong>(primera_linea)</p>
<p>Esta línea de código creará una variable llamada <em>primera_interseccion</em> que estará definida por la intersección entre la <em>cuarta línea</em> y la <em>primera línea</em>. El siguiente fragmento creará las intersecciones restantes del polígono solución (consideramos que el orden es importante, así que las creamos de acuerdo a las manecillas del reloj).</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Generando las intersecciones (vértices)
primera_interseccion = cuarta_linea.intersection(primera_linea)
segunda_interseccion = primera_linea.intersection(segunda_linea)
tercera_interseccion = segunda_linea.intersection(tercera_linea)
cuarta_interseccion = tercera_linea.intersection(cuarta_linea)
</code></pre>
</div>
<p>El espacio de soluciones factibles tienen cuatro intersecciones, de acuerdo al código anterior quedan definidas de acuerdo a los nombres que le asignamos a las variables. Ahora, el paso siguiente consiste en graficar dichas restricciones.</p>
<p>Acá pueden encontrar el listado con los tipos de marcadores (símbolos) que pueden utilizar: <a href="https://matplotlib.org/stable/api/markers_api.html"><em><strong>marcadores pyplot</strong></em></a>. Nosotros utilizaremos un marcador en círculo (representado así en el código: «o»).</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Graficando los vértices
plt.plot(*primera_interseccion.xy, 'o', color='k')
plt.plot(*segunda_interseccion.xy, 'o', color='k')
plt.plot(*tercera_interseccion.xy, 'o', color='k')
plt.plot(*cuarta_interseccion.xy, 'o', color='k')
</code></pre>
</div>
<p>Así entonces, podemos ejecutar nuestro código (<a href="https://colab.research.google.com/drive/1EFa3Fb2nAB7ws6faGc73Me8KAhjYKqXM?usp=sharing"><em><strong>Método Gráfico</strong></em></a>) nuevamente y veremos:</p>
<figure id="attachment_26454" aria-describedby="caption-attachment-26454" style="width: 397px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Figura-7_-Vertices-del-espacio-de-solucion-factible.png" alt="Figura 7: Vértices del espacio de solución factible" width="397" height="278" class="wp-image-26454 size-full" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Figura-7_-Vertices-del-espacio-de-solucion-factible.png 397w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Figura-7_-Vertices-del-espacio-de-solucion-factible-300x210.png 300w" sizes="(max-width: 397px) 100vw, 397px" /><figcaption id="caption-attachment-26454" class="wp-caption-text">Figura 7: Vértices del espacio de solución factible</figcaption></figure>
<p>Como podemos observar en la Figura 7, hemos logrado graficar los vértices del polígono factible.</p>
<p>Ahora es cuando debemos preguntarnos: <em>¿Qué más necesitamos? </em>Pues bien, si bien gráficamente podemos determinar el vértice solución (basta con trasladar paralelamente la línea punteada hasta cada vértice e identificar en cual de ellos la línea no corta el polígono solución); sería importante determinar el valor de las coordenadas en cada uno de los vértices, ya que con ello podemos evaluar la ecuación de la función objetivo para cada punto de esquina.</p>
<p>Lo que necesitamos es el valor numérico de cada punto, y la verdad, ya lo tenemos dentro de nuestras variables; lo que debemos hacer es imprimirlo en la consola de Windows, para eso podemos utilizar el siguiente fragmento:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Imprimiendo las coordenadas de los vértices en la consola
print('\n COORDENADAS DE LAS INTERSECCIONES')
print('Coordenadas de la primera intersección: {} '.format(primera_interseccion))
print('Coordenadas de la segunda intersección: {} '.format(segunda_interseccion))
print('Coordenadas de la tercera intersección: {} '.format(tercera_interseccion))
print('Coordenadas de la cuarta intersección: {} '.format(cuarta_interseccion))
</code></pre>
</div>
<p>Bien podíamos utilizar tan solo la función <strong>print</strong>() en su versión más simple, por ejemplo:</p>
<p style="text-align: center;"><strong>print</strong>(primera_interseccion)</p>
<p>Esto serviría para obtener el punto de la primera intersección con sus dos coordenadas (<em><strong>x</strong></em>, <em><strong>y</strong></em>). Sin embargo, hemos utilizado algún texto que identifique con precisión la información que estamos generando. En este caso utilizamos un poco de texto, dentro de las llaves {} el programa introducirá el valor de cada variable. Esta es una cuestión accesoria y de estilo, siéntanse libres de explorar con el código. Ejecutamos (<a href="https://colab.research.google.com/drive/1EFa3Fb2nAB7ws6faGc73Me8KAhjYKqXM?usp=sharing"><em><strong>Método Gráfico</strong></em></a>) y, junto a la imagen, tendremos el siguiente resultado:</p>
<figure id="attachment_26455" aria-describedby="caption-attachment-26455" style="width: 533px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Figura-8_Valores-de-las-coordenadas-en-cada-vertice.png" alt="Figura 8: Valores de las coordenadas en cada vértice" width="533" height="124" class="wp-image-26455 size-full" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Figura-8_Valores-de-las-coordenadas-en-cada-vertice.png 533w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Figura-8_Valores-de-las-coordenadas-en-cada-vertice-300x70.png 300w" sizes="(max-width: 533px) 100vw, 533px" /><figcaption id="caption-attachment-26455" class="wp-caption-text">Figura 8: Valores de las coordenadas en cada vértice</figcaption></figure>
<p>&nbsp;</p>
<p>De esta manera hemos obtenido los valores de los puntos de cada vértice.</p>
<h3>Paso 6: Determinar la solución óptima</h3>

		<div id="paso-6-determinar-la-solucion-optima" data-title="Paso 6: Determinar la solución óptima" class="index-title"></div>
	
<p>Básicamente el objetivo de la solución gráfica se logra en este paso, es decir, hallar la solución óptima en términos de la función objetivo y los valores de las variables de decisión. Con un poco de lógica podemos inferir que en el punto en el que estamos, esta es una cuestión sencilla. Lo único que debemos hacer es, de acuerdo a los valores de cada vértice, evaluar la ecuación de la función objetivo en cada uno de ellos, de manera que podamos determinar cual es el mejor resultado (de acuerdo al criterio de optimización, en este caso: <em>maximizar</em>).</p>
<p>Ya que nos encontramos trabajando en <em>Python</em>, es necesario aclarar que el valor de los vértices obtenidos corresponde a un formato de tipo <em>point </em>(punto), y que básicamente, no es posible operar cada una de las variables (<em>x, y) </em>que contiene sin antes extraerlas. Por esa razón, lo siguiente que debemos hacer es extraer el valor de cada variable contenida en cada punto de manera independiente:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Identificando los valores de las coordenadas (x, y) de cada vértice
xi1m, yi1m = primera_interseccion.xy
xi2m, yi2m = segunda_interseccion.xy
xi3m, yi3m = tercera_interseccion.xy
xi4m, yi4m = cuarta_interseccion.xy
</code></pre>
</div>
<p>El anterior código acaba de generar un total de 8 variables, cada una de ellas contendrá la información correspondiente a la proyección de cada eje sobre cada punto, por ejemplo: <em><strong>xi1m</strong></em><em> </em>contendrá la información correspondiente al valor que tienen el punto de la primera intersección sobre el eje <em><strong>x</strong></em>. Es decir, acabamos de extraer las variables <em><strong>x</strong></em> y <em><strong>y </strong></em>de cada uno de los puntos de intersección.</p>
<p>Sin embargo, ese valor extraído se encuentra en un formato de matriz y contiene más información que la que necesitamos, de hecho por eso le colocamos la letra <em><strong>m</strong>, </em>para reconocer que es una matriz. Lo que debemos hacer es cambiar el formato de los valores extraídos. Formas existen muchas, nosotros utilizaremos la siguiente:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Cambiamos el formato de la variable de matriz a real
xi1 = np.float64(np.array(xi1m))
xi2 = np.float64(np.array(xi2m))
xi3 = np.float64(np.array(xi3m))
xi4 = np.float64(np.array(xi4m))
yi1 = np.float64(np.array(yi1m))
yi2 = np.float64(np.array(yi2m))
yi3 = np.float64(np.array(yi3m))
yi4 = np.float64(np.array(yi4m))
</code></pre>
</div>
<p><em>float 64</em> es un formato que corresponde a números reales, es decir: números que pueden ser positivos o negativos con decimales. En este punto tenemos las variables correspondientes a cada uno de los valores de los vértices en los ejes <em><strong>x </strong></em>y <em><strong>y</strong></em>. Lo siguiente será evaluar la ecuación objetivo en cada uno de los vértices, es decir, en las coordenadas de cada intersección. Por ejemplo:</p>
<p style="text-align: center;"><strong>FOi1</strong> = (<strong>xi1</strong> * 10000) + (<strong>yi1</strong> * 6000)</p>
<p>Creamos la variable <em><strong>FOi1</strong></em>, es decir: La función objetivo en la intersección 1 (vértice 1). La cual multiplicará los coeficientes de la ecuación objetivo por el valor de la variable <strong>xi1 </strong>y <strong>yi1</strong>, es decir, las coordenadas <strong>x </strong>y <strong>y </strong>en el vértice 1. En este caso, y ya que conocemos estos valores (los hemos impreso en la consola), generaría el siguiente resultado:</p>
<p style="text-align: center;"><strong>FOi1</strong> = (<strong>0</strong> * 10000) + (<strong>60</strong> * 6000)</p>
<p style="text-align: center;"><strong>FOi1</strong> = 360000</p>
<p>Lo que equivale a decir que el resultado de la función objetivo en el vértice 1 es igual a 360.000. Así entonces, generamos el fragmento de código de estas ecuaciones y variables, así como las funciones que permitan que estos valores se impriman en la consola:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Evaluando la función objetivo en cada vértice
FOi1 = (xi1 * 10000) + (yi1 * 6000)
FOi2 = (xi2 * 10000) + (yi2 * 6000)
FOi3 = (xi3 * 10000) + (yi3 * 6000)
FOi4 = (xi4 * 10000) + (yi4 * 6000)

#Imprimiendo las evaluaciones de la FO en cada vértice (Consola)
print('\n EVALUACIÓN DE LA FO EN LOS VÉRTICES')
print('Función objetivo en la intersección 1: {} pesos'.format(FOi1))
print('Función objetivo en la intersección 2: {} pesos'.format(FOi2))
print('Función objetivo en la intersección 3: {} pesos'.format(FOi3))
print('Función objetivo en la intersección 4: {} pesos'.format(FOi4))
</code></pre>
</div>
<p>Ejecutamos nuestro código (<a href="https://colab.research.google.com/drive/1EFa3Fb2nAB7ws6faGc73Me8KAhjYKqXM?usp=sharing"><em><strong>Método Gráfico</strong></em></a>), y tendremos, además de la gráfica, el siguiente resultado:</p>
<figure id="attachment_26456" aria-describedby="caption-attachment-26456" style="width: 519px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Figura-9_Funcion-objetivo-en-cada-uno-de-los-vertices.png" alt="Figura 9: Función objetivo en cada uno de los vértices" width="519" height="124" class="size-full wp-image-26456" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Figura-9_Funcion-objetivo-en-cada-uno-de-los-vertices.png 519w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Figura-9_Funcion-objetivo-en-cada-uno-de-los-vertices-300x72.png 300w" sizes="(max-width: 519px) 100vw, 519px" /><figcaption id="caption-attachment-26456" class="wp-caption-text">Figura 9: Función objetivo en cada uno de los vértices</figcaption></figure>
<p>&nbsp;</p>
<p>A esta altura debemos suponer que estamos muy cerca de lograr que nuestro desarrollo determine, según el criterio de optimización, la solución óptima. Ya que tenemos los valores de la función objetivo en cada uno de los vértices, será cuestión de determinar su valor máximo o mínimo, según se el caso. En nuestro problema, requerimos determinar el valor máximo; para eso utilizamos una función básica de Python:</p>
<p style="text-align: center;"><strong>ZMAX </strong>= <strong>max</strong>(FOi1, FOi2, FOi3, FOi4)</p>
<p>Creamos la variable <em><strong>ZMAX</strong></em>, es decir: La variable que contendrá el valor máximo entre las variables que contienen los valores de la función objetivo en cada vértice. Así entonces obtendremos de una muy sencilla, nuestra solución óptima. El siguiente código creará la variable y la función que permitirá que se imprima dicho resultado en la consola:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Calculando el mejor resultado (Maximizar)
ZMAX = max(FOi1, FOi2, FOi3, FOi4)

#Imprimiendo la solución óptima en la consola
print('\n SOLUCIÓN ÓPTIMA')
print('Solución óptima: {} pesos'.format(ZMAX))
</code></pre>
</div>
<p>Ejecutamos nuestro código (<a href="https://colab.research.google.com/drive/1EFa3Fb2nAB7ws6faGc73Me8KAhjYKqXM?usp=sharing"><em><strong>Método Gráfico</strong></em></a>) y tendremos, además de la gráfica, el siguiente resultado:</p>
<figure id="attachment_26457" aria-describedby="caption-attachment-26457" style="width: 478px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Figura-10_Solucion-optima.png" alt="Figura 10: Solución óptima" width="478" height="70" class="size-full wp-image-26457" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Figura-10_Solucion-optima.png 478w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Figura-10_Solucion-optima-300x44.png 300w" sizes="(max-width: 478px) 100vw, 478px" /><figcaption id="caption-attachment-26457" class="wp-caption-text">Figura 10: Solución óptima</figcaption></figure>
<p>En este punto nuestro desarrollo permite que obtengamos, además de la gráfica, la solución óptima. <em>¿Qué más podemos necesitar?</em> Pues bien, necesitamos como mínimo imprimir el valor de las variables de decisión, es decir, el valor de las coordenadas <em><strong>x </strong></em>y <em><strong>y </strong></em>en el vértice donde se encuentra la solución óptima (punto óptimo). En <em>Python </em>pueden existir muchas alternativas para obtener esta información, nosotros utilizaremos el concepto de directorio.</p>
<p>Lo primero que vamos a hacer es organizar la información, es decir, crear un vector que almacene los valores de cada variable (sea <em><strong>x</strong> </em>o <strong><em>y</em></strong>) en todos los vértices, por ejemplo:</p>
<p style="text-align: center;"><strong>m</strong> = [<strong>xi1</strong>, <strong>xi2</strong>, <strong>xi3</strong>, <strong>xi4</strong>]
<p>El vector <em><strong>m </strong></em>contendrá los valores (ordenados) de las variables <em><strong>x </strong></em>en cada uno de los vértices, empezando por el vértice 1 y finalizando en el vértice 4. Lo mismo realizamos con las variables <em><strong>y</strong></em>.</p>
<p style="text-align: center;"><strong>n</strong> = [<strong>yi1</strong>, <strong>yi2</strong>, <strong>yi3</strong>, <strong>yi4</strong>]
<p>En este punto, y con la información tal cual como tenemos organizada, podemos realizar un pequeño aporte al gráfico: rellenar nuestro polígono solución. Para eso, utilizamos una función llamada <em>fill</em>, y nuestros vectores recién creados:</p>
<p style="text-align: center;">plt.<strong>fill</strong>(<strong>m</strong>, <strong>n</strong>, color=&#8217;silver&#8217;)</p>
<p>Esta función utiliza los vectores <em><strong>m </strong></em>y <em><strong>n </strong></em>para crear un relleno en el gráfico al desplazarse por los puntos de los vectores (coordenadas), en sentido de las manecillas del reloj. Es decir, iniciará en el vértice 1 y finalizará en el vértice 4. Además, hemos especificado que el color de este relleno sea <em>silver:</em></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Ordenando las coordenadas de los vértices (Las coordenadas x en m y las coordenadas y en n)
m = [xi1, xi2, xi3, xi4]
n = [yi1, yi2, yi3, yi4]

#Graficando el polígono solución a partir de las coordenadas de los vértices 
plt.fill(m, n, color='silver')
</code></pre>
</div>
<p>Ejecutamos nuestro código (<a href="https://colab.research.google.com/drive/1EFa3Fb2nAB7ws6faGc73Me8KAhjYKqXM?usp=sharing"><em><strong>Método Gráfico</strong></em></a>) y tendremos la siguiente gráfica:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/metodo_grafico3.png" alt="método_gráfico3" width="640" height="480" class="aligncenter wp-image-26223 size-full" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/metodo_grafico3.png 640w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/metodo_grafico3-300x225.png 300w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<p>Ahora podemos apreciar el espacio de soluciones factibles desde la gráfica que nos exporta el programa.</p>
<p>Volvamos a nuestro directorio. Lo que vamos a hacer es crear un arreglo con las variables que contienen los resultados de las funciones objetivo (<em><strong>FOi1, FOi2, FOi3 </strong></em>y <em><strong>FOi4</strong></em>), y a cada uno le asignaremos un índice de acuerdo a su orden (ya veremos para qué). Por ejemplo:</p>
<p style="text-align: center;"><strong>dict1</strong> = {0:<strong>FOi1</strong>, 1:<strong>FOi2</strong>, 2:<strong>FOi3</strong>, 3:<strong>FOi4</strong>}</p>
<p>Así entonces, a cada variable le asignamos un número inicia en 0 y finaliza en 3 (ya veremos para qué). La variable <em><strong>dict</strong></em> hace referencia a nuestro directorio, y dentro de él se encuentra el arreglo con nuestros índices.</p>
<p>Lo siguiente que haremos es extraer el índice, no la variable de este arreglo, de acuerdo al mayor valor de la variable, no del índice. Es decir, una función que evalúe las variables de las funciones objetivo, y en lugar de devolvernos dicho valor, nos traiga el índice que tiene al lado. Nosotros de antemano conocemos que el mayor valor es el de <em><strong>FOi3</strong></em>, por esta razón, la función debe arrojarnos como respuesta el índice <em><strong>2</strong></em> (2:<strong>FOi3</strong>). <em>¿Por qué no iniciamos desde 1 y sí desde 0? </em>En Python, las posiciones dentro de un arreglo inician desde 0.</p>
<p>La siguiente función nos traerá el índice de acuerdo al mayor valor de la variable:</p>
<p style="text-align: center;"><strong>posicion</strong> = <strong>max</strong>(<strong>dict1</strong>, key=dict1.get)</p>
<p>Creamos la variable <em><strong>posicion </strong></em>y en ella se almacenará el índice asociado al mayor valor de la variable del arreglo. <em>¿Y esto para qué nos sirve? </em>Pues bien, recuerdan que tenemos un par de vectores donde se almacenan las variables <em><strong>x </strong></em>y <em><strong>y </strong></em>de cada uno de los vértices (y que hicimos énfasis en ordenarlos). Con la variable <em><strong>posicion</strong></em> podemos acceder a la variable específica dentro de estos vectores, es decir, a la posición en la que se encuentra cada una de las variables asociadas al vértice solución. <em>¿Podemos plantearlo de una manera más sencilla? </em>Vamos a intentarlo:</p>
<p>Según de la manera ordenada en la que hemos venido trabajando el código, podemos inferir que si la función objetivo solución se encuentra en la variable <em><strong>FOi3</strong></em> sus coordenadas serán <em><strong>xi3 </strong></em>y <em><strong>y13</strong></em>. Así entonces, si tenemos la posición de la función objetivo dentro de un arreglo (<em><strong>dict1</strong></em>)<strong></strong><em><strong>,</strong></em> esa misma posición corresponderá a la de cada variable dentro del vector que la contenga (el vector <em><strong>m </strong></em>contiene las variables <em><strong>x</strong></em> de los vértices, mientras el vector <em><strong>n </strong></em>contiene las variables <em><strong>y</strong></em> de los vértices).</p>
<p>Así entonces, el valor de las coordenadas del vértice solución la obtenemos de la siguiente forma:</p>
<p style="text-align: center;"><strong>XMAX</strong> = <strong>m</strong>[<strong>posicion</strong>]
<strong>YMAX</strong> = <strong>n</strong>[<strong>posicion</strong>]
<p>La variable <em><strong>XMAX</strong></em> tomará el valor de la variable <em><strong>x</strong></em> que se encuentra en el vector <em><strong>m </strong></em>en la posición de la variable <em><strong>posicion</strong></em>. Es decir, corresponderá al valor de la variable <em><strong>x</strong></em> en el vértice solución. Veamos:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Identificando el índice del vértice de la mejor solución
dict1 = {0:FOi1, 1:FOi2, 2:FOi3, 3:FOi4}
posicion = max(dict1, key=dict1.get)

#Obteniendo las coordenadas del vértice de la mejor solución de acuerdo al índice
XMAX = m[posicion]
YMAX = n[posicion]

#Imprimiendo las coordenadas del vértice de la mejor solución (variables de decisión)
print('\n VARIABLES DE DECISIÓN')
print('Cantidad de asientos a reservar para fumadores: {} '.format(XMAX))
print('Cantidad de asientos a reservar para no fumadores: {} '.format(YMAX))
</code></pre>
</div>
<p>En el anterior fragmento, bien pudimos utilizar la función <strong>print</strong>(<strong>XMAX</strong>) de una manera sencilla. Sin embargo, le dimos un formato que permitiera darle un nombre a las variables de acuerdo al problema (variables de decisión).</p>
<p>Ejecutamos nuestro código y tendremos, además de la gráfica, el siguiente resultado en la consola:</p>
<figure id="attachment_26458" aria-describedby="caption-attachment-26458" style="width: 591px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Variables-de-decision.png" alt="Variables de decisión" width="591" height="89" class="size-full wp-image-26458" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Variables-de-decision.png 591w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/Variables-de-decision-300x45.png 300w" sizes="(max-width: 591px) 100vw, 591px" /><figcaption id="caption-attachment-26458" class="wp-caption-text">Variables de decisión</figcaption></figure>
<p>En este punto podemos decir que nuestro código tiene la capacidad de esbozar una solución gráfica del problema de programación lineal. Al mismo tiempo nos permite obtener información básica relevante.</p>
<p>Podemos hacer algunos ajustes accesorios, todos a elección del desarrollador. En este caso, vamos a agregar un par de líneas de código que permitan adicionar al gráfico un par de anotaciones con las coordenadas del vértice solución y el valor la solución óptima. Veamos:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Generando las anotaciones de las coordenadas y solución óptima en el gráfico
plt.annotate('  X: {0} / Y: {1} (Coordenadas)'.format(XMAX, YMAX), (XMAX, YMAX))
plt.annotate('  Solución óptima: {}'.format(ZMAX), (XMAX, YMAX+3))
</code></pre>
</div>
<p>Ejecutamos nuestro código (<a href="https://colab.research.google.com/drive/1EFa3Fb2nAB7ws6faGc73Me8KAhjYKqXM?usp=sharing"><em><strong>Método Gráfico</strong></em></a>) y tendremos la siguiente gráfica:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/metodo_grafico4.png" alt="método_gráfico4" width="656" height="563" class="aligncenter wp-image-26225 size-full" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/metodo_grafico4.png 656w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/metodo_grafico4-300x257.png 300w" sizes="(max-width: 656px) 100vw, 656px" /></p>
<p>También podemos eliminar las líneas rectas, para ello anteponemos # en la línea que ordena imprimir cada una de las ecuaciones. Ejecutamos (<a href="https://colab.research.google.com/drive/1EFa3Fb2nAB7ws6faGc73Me8KAhjYKqXM?usp=sharing"><em><strong>Método Gráfico</strong></em></a>) y tendremos:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/descarga.png" alt="poligono solucion factible" width="528" height="278" class="aligncenter size-full wp-image-26459" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/descarga.png 528w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/07/descarga-300x158.png 300w" sizes="(max-width: 528px) 100vw, 528px" /></p>
<hr />
<p>Así entonces, hemos finalizado con la construcción de nuestro código para efectuar una solución gráfica de un modelo de programación lineal. Este puede, con ligeras modificaciones, ajustarse a cualquier problema susceptible de ser solucionado mediante método gráfico.</p>
<hr />
<p>El código completo de nuestro desarrollo lo presentamos a continuación. También puedes ver el cuaderno de este módulo en nuestro <em>Colaboratory: <a href="https://colab.research.google.com/drive/1EFa3Fb2nAB7ws6faGc73Me8KAhjYKqXM?usp=sharing"><strong>Método Gráfico</strong></a>.</em></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Autor: Bryan Salazar López, Ing. M.Sc. (2021)
#Librerías necesarias
import matplotlib.pyplot as plt
import numpy as np
from shapely.geometry import LineString

#Ecuaciones e intervalos (Para tabular)
x = np.arange(-100, 150, 50)
y = np.arange(-100, 150, 50)
y1 = (3000 - (20 * x))/ 50
y2 = 90 - x
y3 = 10 + (0 * x)
x1 = 0 * y
y4 = 0 * x
z = (-10000 * x) / 6000

#Identificadores para las líneas
primera_linea = LineString(np.column_stack((x, y1)))
segunda_linea = LineString(np.column_stack((x, y2)))
tercera_linea = LineString(np.column_stack((x, y3)))
cuarta_linea = LineString(np.column_stack((x1, y)))
quinta_linea = LineString(np.column_stack((x, y4)))
sexta_linea = LineString(np.column_stack((x, z)))

#Graficando las líneas
plt.plot(x, y1, '-', linewidth=2, color='b')
plt.plot(x, y2, '-', linewidth=2, color='g')
plt.plot(x, y3, '-', linewidth=2, color='r')
plt.plot(x1, y, '-', linewidth=2, color='y')
plt.plot(x, y4, '-', linewidth=2, color='k')
plt.plot(x, z, ':', linewidth=1, color='k')

#Generando las intersecciones (vértices)
primera_interseccion = cuarta_linea.intersection(primera_linea)
segunda_interseccion = primera_linea.intersection(segunda_linea)
tercera_interseccion = segunda_linea.intersection(tercera_linea)
cuarta_interseccion = tercera_linea.intersection(cuarta_linea)

#Graficando los vértices
plt.plot(*primera_interseccion.xy, 'o')
plt.plot(*segunda_interseccion.xy, 'o')
plt.plot(*tercera_interseccion.xy, 'o')
plt.plot(*cuarta_interseccion.xy, 'o')

#Imprimiendo las coordenadas de los vértices en la consola
print('\n COORDENADAS DE LAS INTERSECCIONES')
print('Coordenadas de la primera intersección: {} '.format(primera_interseccion))
print('Coordenadas de la segunda intersección: {} '.format(segunda_interseccion))
print('Coordenadas de la tercera intersección: {} '.format(tercera_interseccion))
print('Coordenadas de la cuarta intersección: {} '.format(cuarta_interseccion))

#Identificando los valores de las coordenadas x y y de cada vértice
xi1m, yi1m = primera_interseccion.xy
xi2m, yi2m = segunda_interseccion.xy
xi3m, yi3m = tercera_interseccion.xy
xi4m, yi4m = cuarta_interseccion.xy

#Cambiamos el formato de matriz a float
xi1 = np.float64(np.array(xi1m))
xi2 = np.float64(np.array(xi2m))
xi3 = np.float64(np.array(xi3m))
xi4 = np.float64(np.array(xi4m))
yi1 = np.float64(np.array(yi1m))
yi2 = np.float64(np.array(yi2m))
yi3 = np.float64(np.array(yi3m))
yi4 = np.float64(np.array(yi4m))

#Evaluando la función objetivo en cada vértice
FOi1 = (xi1 * 10000) + (yi1 * 6000)
FOi2 = (xi2 * 10000) + (yi2 * 6000)
FOi3 = (xi3 * 10000) + (yi3 * 6000)
FOi4 = (xi4 * 10000) + (yi4 * 6000)

#Imprimiendo las evaluaciones de la FO en cada vértice (Consola)
print('\n EVALUACIÓN DE LA FO EN LOS VÉRTICES')
print('Función objetivo en la intersección 1: {} pesos'.format(FOi1))
print('Función objetivo en la intersección 2: {} pesos'.format(FOi2))
print('Función objetivo en la intersección 3: {} pesos'.format(FOi3))
print('Función objetivo en la intersección 4: {} pesos'.format(FOi4))

#Calculando el mejor resultado (Maximizar)
ZMAX = max(FOi1, FOi2, FOi3, FOi4)

#Imprimiendo la solución óptima en la consola
print('\n SOLUCIÓN ÓPTIMA')
print('Solución óptima: {} pesos'.format(ZMAX))

#Ordenando las coordenadas de los vértices (Las coordenadas x en m y las coordenadas y en n)
m = [xi1, xi2, xi3, xi4]
n = [yi1, yi2, yi3, yi4]

#Graficando el polígono solución a partir de las coordenadas de los vértices 
plt.fill(m, n, color='silver')

#Identificando el índice del vértice de la mejor solución
dict1 = {0:FOi1, 1:FOi2, 2:FOi3, 3:FOi4}
posicion = max(dict1, key=dict1.get)

#Obteniendo las coordenadas del vértice de la mejor solución de acuerdo al índice
XMAX = m[posicion]
YMAX = n[posicion]

#Imprimiendo las coordenadas del vértice de la mejor solución (variables de decisión)
print('\n VARIABLES DE DECISIÓN')
print('Cantidad de asientos a reservar para fumadores: {} '.format(XMAX))
print('Cantidad de asientos a reservar para no fumadores: {} '.format(YMAX))

#Generando las anotaciones de las coordenadas y solución óptima en el gráfico
plt.annotate('  X: {0} / Y: {1} (Coordenadas)'.format(XMAX, YMAX), (XMAX, YMAX))
plt.annotate('  Solución óptima: {}'.format(ZMAX), (XMAX, YMAX+3))


#Configuraciones adicionales del gráfico
plt.grid()
plt.xlabel('Asientos para fumadores')
plt.ylabel('Asientos para no fumadores')
plt.title('Método Gráfico')

plt.show()
</code></pre>
</div>
<p>&nbsp;</p>
<hr />
<p>En artículos posteriores abordaremos <em><strong><a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/analisis-de-sensibilidad-grafica-mediante-el-uso-de-python-caso-1/">Análisis de sensibilidad</a> </strong></em>en la solución gráfica mediante <em>Python, y </em>evaluaremos la pertinencia de la misma.</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/metodo-grafico-de-la-programacion-lineal-mediante-el-uso-de-python/">Método gráfico de la programación lineal mediante el uso de Python</a> se publicó primero en <a href="https://ingenieriaindustrialonline.com">Ingenieria Industrial Online</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ingenieriaindustrialonline.com/investigacion-de-operaciones/metodo-grafico-de-la-programacion-lineal-mediante-el-uso-de-python/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Método gráfico</title>
		<link>https://ingenieriaindustrialonline.com/investigacion-de-operaciones/metodo-grafico/</link>
					<comments>https://ingenieriaindustrialonline.com/investigacion-de-operaciones/metodo-grafico/#comments</comments>
		
		<dc:creator><![CDATA[Bryan Salazar López]]></dc:creator>
		<pubDate>Mon, 10 Jun 2019 22:02:42 +0000</pubDate>
				<category><![CDATA[Investigación de operaciones]]></category>
		<category><![CDATA[Investigación de Operaciones]]></category>
		<category><![CDATA[Método gráfico]]></category>
		<category><![CDATA[Programación lineal]]></category>
		<category><![CDATA[Restricciones]]></category>
		<guid isPermaLink="false">http://contentlab.co/ingenieria/?p=1163</guid>

					<description><![CDATA[<p>El método gráfico es una técnica de solución de problemas de programación lineal que se utiliza principalmente para casos con dos variables. Aunque no es muy práctico para una gran cantidad de variables, es muy útil para interpretar y analizar los resultados y la sensibilidad del problema. Sin embargo, en casos donde se requiera un &#8230;</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/metodo-grafico/">Método gráfico</a> se publicó primero en <a href="https://ingenieriaindustrialonline.com">Ingenieria Industrial Online</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>El <strong>método gráfico es una técnica de solución de problemas</strong> de <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/programacion-lineal/"><strong>programación lineal</strong></a> que se utiliza principalmente para casos con dos variables. Aunque no es muy práctico para una gran cantidad de variables, es muy útil para interpretar y analizar los resultados y la sensibilidad del problema. Sin embargo, en casos donde se requiera un mayor número de variables, es posible emplear otras técnicas como la proyección en un plano.</p>
<p>El método gráfico se basa en la representación gráfica de las restricciones del modelo de programación lineal, lo que permite determinar el polígono solución o región factible. Según el teorema fundamental de la programación lineal, <strong>si existe una solución que cumple con las restricciones del modelo, se encontrará en uno de los vértices de la región factible</strong>.</p>

		<div class="box success  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>
<p>El método gráfico es una técnica que ha sido objeto de debate entre distintos autores a lo largo de la historia. Algunos de ellos han señalado que esta metodología presenta ciertos supuestos o limitaciones.</p>
<p>Uno de los supuestos más conocidos es que no permite realizar un análisis de sensibilidad en el caso de cambios simultáneos en el lado derecho de las restricciones o en los coeficientes de la función objetivo. Otro supuesto es que no se pueden considerar variables binarias en el modelo.</p>
<p>Sin embargo, con el avance de la tecnología, es posible utilizar herramientas como GeoGebra para superar estas limitaciones y realizar análisis de sensibilidad con cambios simultáneos y considerar variables binarias en el modelo. <strong>Por lo tanto, estos supuestos ya no son válidos en la actualidad</strong>.</p>

			</div>
		</div>
	
<h2>
		<div id="consideraciones-previas" data-title="Consideraciones previas" class="index-title"></div>
	Consideraciones previas</h2>
<p>Es necesario recordar que el método gráfico es un método de solución, y por tanto, una etapa previa corresponde al modelamiento matemático.</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/metodo_grafico.png" alt="método_gráfico" width="635" height="105" class="size-full wp-image-32736 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/metodo_grafico.png 635w, https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/metodo_grafico-300x50.png 300w" sizes="(max-width: 635px) 100vw, 635px" /></p>
<h2>
		<div id="problema-de-ejemplo" data-title="Problema de ejemplo" class="index-title"></div>
	El problema</h2>
<p>Vamos a utilizar un problema técnicamente formulado con el objetivo de abordar cada una de las fases del método gráfico.</p>
<blockquote class="aligncenter quote-simple "><p>La fábrica de Hilados y Tejidos «Salazar» requiere fabricar dos tejidos de calidad diferente <strong>Estándar</strong> y <strong>Premium</strong>; se dispone de 500 Kg de hilo a, 300 Kg de hilo b y 108 Kg de hilo c. Para obtener un metro de <strong>Estándar</strong> diariamente se necesitan 125 gr de a, 150 gr de b y 72 gr de c; para producir un metro de <strong>Premium</strong> por día se necesitan 200 gr de a, 100 gr de b y 27 gr de c. El Estándar se vende a $4000 el metro y el Premium se vende a $5000 el metro. Si se debe obtener el máximo beneficio, ¿Cuántos metros de Estándar y Premium se deben fabricar?</p></blockquote>
<p>&nbsp;</p>
<h2>
		<div id="modelamiento-mediante-programacion-lineal" data-title="Modelamiento mediante programación lineal" class="index-title"></div>
	Modelamiento mediante programación lineal</h2>
<p>Como lo se hamencionado anteriormente, la base para utilizar el método gráfico corresponde al modelo matemático de programación lineal:</p>
<h3><em><strong>Variables</strong></em></h3>
<p>x: Cantidad de metros diarios de tejido tipo Estándar a fabricar</p>
<p>y: Cantidad de metros diarios de tejido tipo Premium a fabricar</p>
<h3><strong>Restricciones</strong></h3>
<p>0,12x + 0,2y &lt;= 500              <em>Kg de hilo “a”</em></p>
<p>0,15x + 0,1y &lt;= 300              <em>Kg de hilo “b”</em></p>
<p>0,072x + 0,027y &lt;= 108        <em>Kg de hilo “c”</em></p>
<p>x &gt;= 0      Restricción de no negatividad</p>
<p>y &gt;= 0      Restricción de no negatividad</p>
<h3><strong>Función objetivo</strong></h3>
<p>Zmax = 4000x + 5000y         (Maximizar los ingresos totales dados en $)</p>

		<div class="clearfix"></div>
		<hr style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid">
	
<h2>
		<div id="solucion-mediante-metodo-grafico" data-title="Solución mediante método gráfico" class="index-title"></div>
	Solución mediante método gráfico</h2>
<h3>
		<div id="paso-1-graficar-las-restricciones" data-title="Paso 1: Graficar las restricciones" class="index-title"></div>
	<em>Paso 1: Graficar las restricciones</em></h3>
<p>El proceso para encontrar la solución factible comienza con la representación gráfica de las restricciones; cada una de ellas debe representarse de tal manera que se vayan limitando las posibles soluciones del modelo.</p>
<p>En este punto, debemos considerar dos posibilidades:</p>
<ol>
<li>Que realicemos todo el procedimiento de forma manual</li>
<li>Que utilicemos un software gráfico que simplifique las operaciones matemáticas</li>
</ol>
<p>En este caso, mostraremos toda la metodología para realizar el procedimiento manual, al mismo tiempo que utilizaremos un software gráfico para representar cada fase del método.</p>

		<div class="clearfix"></div>
		<hr style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid">
	
<p>Cada restricción corresponde a una función lineal, lo que significa que gráficamente se representa mediante una línea en el plano cartesiano. Para trazar una línea en el plano cartesiano es necesario conocer al menos dos puntos de la función.</p>
<p>Para comenzar a trazar las restricciones es esencial <em><strong>igualar las restricciones a cero</strong></em>, de esta manera podremos usar el despeje de las ecuaciones para iniciar la tabulación que nos dará las coordenadas para dibujar cada una de las gráficas.</p>
<p><em><strong>Igualamos las restricciones a cero:</strong></em></p>
<p>0.12x + 0.2y = 500             (Restricción 1)</p>
<p>0.15x + 0.1y = 300             (Restricción 2)</p>
<p>0.072x + 0.027y = 108       (Restricción 3)</p>
<p>x = 0                                  (Restricción 4)</p>
<p>y = 0                                  (Restricción 5)</p>
<p>Iniciamos con la <em><strong>Restricción 1: </strong></em>Hallamos las primeras dos coordenadas. Para hallar las coordenadas, regularmente llevamos una de las variables a cero, para de esta manera despejar más fácilmente la segunda.</p>
<p><em>Cuando <strong>x = 0</strong></em></p>
<p>0,12(0) + 0,2y = 500</p>
<p>0,2y =  500</p>
<p>500/0,2 = y</p>
<p>2500 = y</p>
<p><em>y cuando <strong>y = 0</strong></em></p>
<p>0,12x + 0,2(0) = 500</p>
<p>0,12x = 500</p>
<p>x = 500/0,12</p>
<p>x = 4167</p>
<table style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<td style="width: 33.3333%; background-color: #135222;"><span style="color: #ffffff;"><strong>Restricción 1</strong></span></td>
<td style="width: 33.3333%; text-align: center;"><strong>x</strong></td>
<td style="width: 33.3333%; text-align: center;"><strong>y</strong></td>
</tr>
<tr>
<td style="width: 33.3333%;"><strong>Primera coordenada</strong></td>
<td style="width: 33.3333%; text-align: center;">0</td>
<td style="width: 33.3333%; text-align: center;">2500</td>
</tr>
<tr>
<td style="width: 33.3333%;"><strong>Segunda coordenada</strong></td>
<td style="width: 33.3333%; text-align: center;">4167</td>
<td style="width: 33.3333%; text-align: center;">0</td>
</tr>
</tbody>
</table>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r11.png" alt="C1" width="623" height="458" class="size-full wp-image-32739 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r11.png 623w, https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r11-300x221.png 300w" sizes="(max-width: 623px) 100vw, 623px" /></p>

		<div class="clearfix"></div>
		<hr style="margin-top:20px; margin-bottom:20px;" class="divider divider-dashed">
	
<p><em><strong>Seguimos con la Restricción 2</strong></em>:</p>
<p><em>Por ejemplo, cuando <strong>x = 0</strong></em></p>
<p>0.15(0) + 0.1y = 300</p>
<p>0.1y = 300</p>
<p>y = 300/0.1</p>
<p>y = 3000</p>
<p><em>Cuando <strong>y = 0</strong></em></p>
<p>0.15x + 0.1(0) = 300</p>
<p>0.15x = 300</p>
<p>x = 300/0.15</p>
<p>x = 2000</p>
<table style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<td style="width: 33.3333%; background-color: #006cbf;"><span style="color: #ffffff;"><strong>Restricción 2</strong></span></td>
<td style="width: 33.3333%; text-align: center;"><strong>x</strong></td>
<td style="width: 33.3333%; text-align: center;"><strong>y</strong></td>
</tr>
<tr>
<td style="width: 33.3333%;"><strong>Primera coordenada</strong></td>
<td style="width: 33.3333%; text-align: center;">0</td>
<td style="width: 33.3333%; text-align: center;">3000</td>
</tr>
<tr>
<td style="width: 33.3333%;"><strong>Segunda coordenada</strong></td>
<td style="width: 33.3333%; text-align: center;">2000</td>
<td style="width: 33.3333%; text-align: center;">0</td>
</tr>
</tbody>
</table>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r2.png" alt="r2" width="572" height="467" class="size-full wp-image-32740 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r2.png 572w, https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r2-300x245.png 300w" sizes="(max-width: 572px) 100vw, 572px" /></p>

		<div class="clearfix"></div>
		<hr style="margin-top:20px; margin-bottom:20px;" class="divider divider-dashed">
	
<p><em><strong>Seguimos con la Restricción 3</strong></em>:</p>
<p><em>Por ejemplo, cuando <strong>x = 0</strong></em></p>
<p>0.072x + 0.027y = 108</p>
<p>0.072(0) + 0.027y = 108</p>
<p>0.027y = 108</p>
<p>y = 108/0.027</p>
<p>y = 4000</p>
<p><em>Cuando <strong>y = 0</strong></em></p>
<p>0.072x + 0.027(0) = 108</p>
<p>0.072x = 108</p>
<p>x = 108/0.072</p>
<p>x = 1500</p>
<table style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<td style="width: 33.3333%; background-color: #bf0023;"><span style="color: #ffffff;"><strong>Restricción 3</strong></span></td>
<td style="width: 33.3333%; text-align: center;"><strong>x</strong></td>
<td style="width: 33.3333%; text-align: center;"><strong>y</strong></td>
</tr>
<tr>
<td style="width: 33.3333%;"><strong>Primera coordenada</strong></td>
<td style="width: 33.3333%; text-align: center;">0</td>
<td style="width: 33.3333%; text-align: center;">4000</td>
</tr>
<tr>
<td style="width: 33.3333%;"><strong>Segunda coordenada</strong></td>
<td style="width: 33.3333%; text-align: center;">1500</td>
<td style="width: 33.3333%; text-align: center;">0</td>
</tr>
</tbody>
</table>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r3.png" alt="r3" width="600" height="546" class="size-full wp-image-32741 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r3.png 600w, https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r3-300x273.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></p>

		<div class="clearfix"></div>
		<hr style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid">
	
<p><em><strong>Restricciones de no negatividad</strong></em>:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r4.png" alt="r4 y r5" width="574" height="527" class="size-full wp-image-32742 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r4.png 574w, https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r4-300x275.png 300w" sizes="(max-width: 574px) 100vw, 574px" /></p>
<h3>
		<div id="paso-2-encontrar-el-area-solucion-poligono-solucion" data-title="Paso 2: Encontrar el área solución (Polígono solución)" class="index-title"></div>
	<em>Paso 2: Encontrar el área solución (Polígono solución)</em></h3>
<p>Después de que todas las restricciones sean representadas gráficamente, el siguiente paso consiste en encontrar el área factible o polígono solución; que no es otra cosa más que la región en la que todos los puntos satisfacen la totalidad de las restricciones, es decir, son factibles.</p>
<p>Para delimitar el área factible, es necesario determinar el sentido de las restricciones. Aquí me detengo un poco; ya que prefiero explicarlo en detalle. Cada línea que representa una restricción divide el plano cartesiano en dos semiplanos: En un lado y en el otro lado de la restricción. Bien, solo los puntos del uno de los lados pueden considerarse como factibles.</p>
<p>Si queremos encontrar el área factible, debemos empezar por encontrar el lado factible de cada una de las restricciones; esto es lo que yo llamo: evaluar el sentido de las restricciones.</p>
<p>Veamos un ejemplo para la primera restricción.</p>
<p><em><strong>Evaluar el sentido de la Restricción 1</strong></em></p>
<p>Esto es muy sencillo, solo debemos evaluar un punto cualquiera del plano cartesiano, debe corresponder a uno de los lados de la restrición. Si se satisface o no la restricción, sabremos el sentido de la misma.</p>
<p style="text-align: center;">0,12x + 0,2y &lt;= 500</p>
<p>Es normal que queramos simplificar el proceso aritmético, y es común utilizar el punto de coordenadas (0, 0):</p>
<p style="text-align: center;">0,12(0) + 0,2(0) &lt;= 500</p>
<p style="text-align: center;">0 &lt;= 500</p>
<p style="text-align: center;">¡Verdad!</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r1_e.png" alt="" width="590" height="428" class="size-full wp-image-32744 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r1_e.png 590w, https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r1_e-300x218.png 300w" sizes="(max-width: 590px) 100vw, 590px" /></p>
<p>Dado que <strong>0 es menor o igual a 500</strong>, podemos afirmar que de ese lado de la restricción se encuentran los valores que la satisfacen.</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r1_ev.png" alt="" width="598" height="435" class="size-full wp-image-32745 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r1_ev.png 598w, https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/r1_ev-300x218.png 300w" sizes="(max-width: 598px) 100vw, 598px" /></p>
<p>La región en verde representa el área en la que se encuentran todos los puntos que satisfacen la restrición 1.</p>

		<div class="box error  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>Cuando la función de la restricción (línea en el plano) pase por el punto (0, 0) este no servirá para evaluar la restricción. Recuerde que debe elegirse un punto que se encuentre en uno de los lados de la restricción.
			</div>
		</div>
	
<p>Para encontrar la región factible, el procedimiento debe repetirse para cada una de las restricciones del problema. Dado que todas las restricciones deben cumplirse, la región factible será el resultado de la intersección de todas las regiones factibles de cada una de las restricciones del modelo.</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/rf.png" alt="rf" width="650" height="519" class="size-full wp-image-32746 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/rf.png 650w, https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/rf-300x240.png 300w" sizes="(max-width: 650px) 100vw, 650px" /></p>
<p>El área sombreada de la gráfica anterior corresponde a la regín factible.</p>
<h3>
		<div id="paso-3-la-busqueda-de-la-solucion-optima" data-title="Paso 3: La búsqueda de la solución óptima" class="index-title"></div>
	<em>Paso 3: La búsqueda de la solución óptima</em></h3>
<p>Una vez que se ha encontrado la región factible que cumple con todas las restricciones del modelo, el siguiente paso es encontrar la solución óptima. Es importante diferenciar entre factibilidad y optimalidad.</p>
<p>La solución óptima dependerá del criterio de optimización de la función objetivo y, de acuerdo al teorema fundamental de la programación lineal, se encuentra en uno de los vértices del área factible. Tecnicamente, en los vértices se encuentra la solución óptima para cualquier criterio de optimización: El valor mínimo (minimización) y el valor máximo (maximización).</p>
<p>Hay principalmente dos procedimientos para encontrar la solución óptima:</p>
<ol>
<li>Graficamente</li>
<li>Evaluando todos los vértices (Fuerza bruta)</li>
</ol>
<p><em><strong>Graficamente</strong></em></p>
<p>Este método requiere de la representación gráfica de la función objetivo. Por lo menos dos veces.</p>
<p>Es necesario graficar la función objetivo y encontrar el sentido en el cual se acerca al criterio de optimización. ¿Cómo lo hacemos? En cada caso, necesitamos dos puntos para graficar la primera línea que representa a la función objetivo; estos dos puntos deben dar como resultado el mismo Z. Veamos:</p>
<p style="text-align: center;">Zmax = 4000x + 5000y</p>
<table style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<td style="width: 33.3333%; background-color: #000000;"><span style="color: #ffffff;"><strong>Función objetivo (Z1)</strong></span></td>
<td style="width: 33.3333%; text-align: center;"><strong>4000(x)</strong></td>
<td style="width: 16.6667%; text-align: center;"><strong>5000(y)</strong></td>
<td style="width: 16.6667%; text-align: center;"><strong>z</strong></td>
</tr>
<tr>
<td style="width: 33.3333%;"><strong>Primera coordenada</strong></td>
<td style="width: 33.3333%; text-align: center;">4000(500)</td>
<td style="width: 16.6667%; text-align: center;">5000(0)</td>
<td style="width: 16.6667%; text-align: center;">2000000</td>
</tr>
<tr>
<td style="width: 33.3333%;"><strong>Segunda coordenada</strong></td>
<td style="width: 33.3333%; text-align: center;">4000(0)</td>
<td style="width: 16.6667%; text-align: center;">5000(400)</td>
<td style="width: 16.6667%; text-align: center;">2000000</td>
</tr>
</tbody>
</table>
<p>Ahora, podemos intentar con otra representación de la función objetivo que se acerque aún más al criterio de optimización: Maximizar; es decir, un Z2 mayor a Z1. Veamos:</p>
<table style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<td style="width: 33.3333%; background-color: #000000;"><span style="color: #ffffff;"><strong>Función objetivo (Z2)</strong></span></td>
<td style="width: 33.3333%; text-align: center;"><strong>4000(x)</strong></td>
<td style="width: 16.6667%; text-align: center;"><strong>5000(y)</strong></td>
<td style="width: 16.6667%; text-align: center;"><strong>z</strong></td>
</tr>
<tr>
<td style="width: 33.3333%;"><strong>Primera coordenada</strong></td>
<td style="width: 33.3333%; text-align: center;">4000(1000)</td>
<td style="width: 16.6667%; text-align: center;">5000(0)</td>
<td style="width: 16.6667%; text-align: center;">4000000</td>
</tr>
<tr>
<td style="width: 33.3333%;"><strong>Segunda coordenada</strong></td>
<td style="width: 33.3333%; text-align: center;">4000(0)</td>
<td style="width: 16.6667%; text-align: center;">5000(800)</td>
<td style="width: 16.6667%; text-align: center;">4000000</td>
</tr>
</tbody>
</table>
<p>Now, we can try with another representation of the objective function that gets even closer to the optimization criterion: Maximize; that is, a Z2 greater than Z1. Let&#8217;s see:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/z2.png" alt="" width="671" height="559" class="size-full wp-image-32747 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/z2.png 671w, https://ingenieriaindustrialonline.com/wp-content/uploads/2019/06/z2-300x250.png 300w" sizes="(max-width: 671px) 100vw, 671px" /></p>
<p>Se puede ver cómo la función objetivo se aproxima al criterio de optimización (aumenta) mientras se desplaza hacia arriba. El siguiente paso es encontrar el último vértice del área factible (en dirección ascendente en este caso), donde una línea paralela a la función objetivo no corta el polígono factible. En este punto se encontrará la solución óptima.</p>
<p><iframe loading="lazy" width="800" height="600" style="border: 1px solid #e4e4e4; border-radius: 4px;" src="https://www.geogebra.org/graphing/snaezncx?embed" allowfullscreen="allowfullscreen" frameborder="0"></iframe></p>
<p>Utilice la barra de desplazamiento de GeoGebra para desplazar la función objetivo. Verá que el último vértice en el que la función objetivo no corta el área factible es el que se da por la intersección de la Restricción 2 y la Restricción 3 (Vértice C). Este punto corresponde a la solución óptima.</p>
<p>Para encontrar el valor de esta coordenada es necesario resolver una ecuación lineal 2&#215;2, y se pueden considerar varios métodos de solución, como:</p>

		<div class="checklist tie-list-shortcode">
<ul>
<li>Método de sustitución</li>
<li>Método de igualación</li>
<li>Método de reducción o Eliminación</li>
<li>Método de eliminación Gauss</li>
<li>Método de eliminación Gauss-Jordán</li>
<li>Método de determinantes</li>
</ul>

		</div>
	
<p>Hay muchos métodos disponibles, pero uno de los más utilizados es el método de reducción o eliminación, que es muy fácil de aplicar.</p>
<p>El método de reducción o eliminación consiste en igualar los coeficientes de una de las variables multiplicando una o ambas ecuaciones, teniendo en cuenta que estos coeficientes queden iguales pero con signos contrarios.</p>
<div id="cc-m-2963529113" class="j-module n j-imageSubtitle ">
<p style="text-align: justify;">Ecuación 1                        0,12x + 0,2y = 500</p>
<p style="text-align: justify;">Ecuación 2                        0,15x + 0,1y = 300  multiplicamos por (-2)</p>
<p style="text-align: justify;">Ecuación 3 (2*(-2))          -0,30x &#8211;  0,2y = -600</p>
<p style="text-align: justify;">Sumamos 1 y 3               -0,18x = -100</p>
<p style="text-align: justify;">Despejamos «x»               x = -100 / (-0,18)</p>
<p style="text-align: justify;"><em><strong>                                         x = 555,55</strong></em></p>
<p style="text-align: justify;">Luego reemplazamos x = 555,55 en cualquiera de las dos ecuaciones originales con el objetivo de despejar «y».</p>
<p style="text-align: justify;">Ecuación 1                     0,12x + 0,2y = 500</p>
<p style="text-align: justify;">Reemplazamos «x»        0,12(555,55) + 0,2y = 500</p>
<p style="text-align: justify;">Despejamos «y»             66,666 + 0,2y = 500</p>
<p style="text-align: justify;">                                      0,2y = 500 &#8211; 66,666</p>
<p style="text-align: justify;">                                      0,2y = 433,334</p>
<p style="text-align: justify;">                                      y = 433,334 / 0,2</p>
<p style="text-align: justify;"><em><strong>                                      y = 2166,67</strong></em></p>
<p style="text-align: justify;">De esta forma hemos obtenido los valores para <em><strong>«x»</strong></em> y <em><strong>«y»</strong></em>.</p>
<p>x: Cantidad de metros diarios de tejido tipo Estándar a fabricar</p>
<p>y: Cantidad de metros diarios de tejido tipo Premium a fabricar</p>
<p style="text-align: justify;">Cantidad de metros diarios de tejido tipo Estándar a fabricar = 555,55</p>
<p style="text-align: justify;">Cantidad de metros diarios de tejido tipo Premium a fabricar = 2166,67</p>
<p style="text-align: justify;">La contribución obtenida (reemplazando las variables en la función objetivo) es de:</p>
<p style="text-align: justify;">Zmax = 4000x + 5000y</p>
<p style="text-align: justify;">Zmax = 4000(555,55) + 5000(2166,67)</p>
<p style="text-align: justify;"><em><strong>Zmax = $13.055.550 </strong></em></p>
<p>Ahora podemos comparar los resultados con los obtenidos mediante resolución en Excel, pero recuerden que el método de búsqueda de la solución óptima en el método gráfico que utilizamos es geométrico y que existe una forma mucho más compleja pero igualmente efectiva, que es el método de iteración por vértice. Este consiste en hallar todas las coordenadas de los vértices y luego evaluar la función objetivo en cada coordenada. Cada coordenada nos proporciona un valor en «x» y otro en «y», luego reemplazamos estos valores en la función objetivo «4000x + 5000y = ?» y evaluamos los resultados seleccionando el mayor valor.</p>

		<div class="clearfix"></div>
		<hr style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid">
	

		<div class="box info  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>Si deseas conocer más sobre los casos especiales en la programación lineal, ¡este post es para ti: <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/casos-especiales-de-programacion-lineal-metodo-grafico/"><em><strong>Casos especiales en programación lineal mediante Método Gráfico</strong></em></a>! Descubre cómo se dan las situaciones de infactibilidad, infinitas soluciones óptimas y restricciones redundantes en esta técnica de modelado matemático. ¡Te sorprenderás de la relevancia de estos casos en la vida real!
			</div>
		</div>
	

		<div class="clearfix"></div>
		<hr style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid">
	

		<div class="box info  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>Recomendamos que lean: <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/metodo-grafico-de-la-programacion-lineal-mediante-el-uso-de-python/"><strong>Método gráfico mediante Python</strong></a>
			</div>
		</div>
	
</div>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/metodo-grafico/">Método gráfico</a> se publicó primero en <a href="https://ingenieriaindustrialonline.com">Ingenieria Industrial Online</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ingenieriaindustrialonline.com/investigacion-de-operaciones/metodo-grafico/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
