<?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>Logística &#187; Ingenieria Industrial Online</title>
	<atom:link href="https://ingenieriaindustrialonline.com/logistica/feed/" rel="self" type="application/rss+xml" />
	<link>https://ingenieriaindustrialonline.com/logistica/</link>
	<description>ingenieriaindustriaonline.com</description>
	<lastBuildDate>Fri, 20 Jan 2023 18:31:04 +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>Logística &#187; Ingenieria Industrial Online</title>
	<link>https://ingenieriaindustrialonline.com/logistica/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Recomendaciones de expertos en management, ¿cómo filtrarlas?</title>
		<link>https://ingenieriaindustrialonline.com/columnas/recomendaciones-de-expertos-en-management-como-filtrarlas/</link>
					<comments>https://ingenieriaindustrialonline.com/columnas/recomendaciones-de-expertos-en-management-como-filtrarlas/#respond</comments>
		
		<dc:creator><![CDATA[Matías Birrell Rodríguez]]></dc:creator>
		<pubDate>Sat, 27 Aug 2022 20:37:22 +0000</pubDate>
				<category><![CDATA[Columnas]]></category>
		<category><![CDATA[Consultoría]]></category>
		<category><![CDATA[Gestión de inventarios]]></category>
		<category><![CDATA[Logística]]></category>
		<category><![CDATA[Teoría de restricciones (TOC)]]></category>
		<category><![CDATA[Agotados]]></category>
		<category><![CDATA[Disponibilidad]]></category>
		<category><![CDATA[Nivel de servicio]]></category>
		<category><![CDATA[Stock Out]]></category>
		<category><![CDATA[Teoría de Restricciones]]></category>
		<category><![CDATA[TOC]]></category>
		<category><![CDATA[Última milla]]></category>
		<guid isPermaLink="false">https://ingenieriaindustrialonline.com/?p=31685</guid>

					<description><![CDATA[<p>Si está leyendo esto es porque en este portal ya leyó cosas interesantes o porque alguien lo recomendó o porque va a evaluar el contenido por primera vez. Pero, de todos modos, a veces es difícil saber si estamos frente a un experto o, por lo menos, frente a buenas recomendaciones. Mi recomendación: contraste lo &#8230;</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/columnas/recomendaciones-de-expertos-en-management-como-filtrarlas/">Recomendaciones de expertos en management, ¿cómo filtrarlas?</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><span>Si está leyendo esto es porque en este portal ya leyó cosas interesantes o porque alguien lo recomendó o porque va a evaluar el contenido por primera vez. Pero, de todos modos, a veces es difícil saber si estamos frente a un experto o, por lo menos, frente a buenas recomendaciones.</span></p>
<p><span><strong>Mi recomendación</strong>: contraste lo que lee con su experiencia y <em><strong>haga el ejercicio de validar la lógica</strong></em> de lo que le proponen. Una manera es verificar “efecto-causa-efecto”, como decía el Dr. Goldratt. Es decir, si nos proponen que un efecto tiene cierta causa, podemos predecir que, si esa causa existiera, también debería existir otro efecto. Esto también se conoce en <a href="https://ingenieriaindustrialonline.com/teoria-de-restricciones-toc/que-es-teoria-de-restricciones-toc/"><strong>Teoría de Restricciones</strong></a> como “reserva de efecto predicho”. Veamos un ejemplo reciente.</span></p>
<h2>«The Future of Commerce Trend Report 2022» (Por Shopify.com)</h2>

		<div id="the-future-of-commerce-trend-report-2022-por-shopify-com" data-title="«The Future of Commerce Trend Report 2022» (Por Shopify.com)" class="index-title"></div>
	
<p><span>No creo que esté mostrando aquí un portal desconocido, y es fuente de artículos y de reportes muy acabados, como el <strong>“The Future of Commerce Trend Report 2022”</strong> (<a href="https://ingenieriaindustrialonline.com/wp-content/uploads/2022/08/FOC_PDF_FA.pdf" target="_blank" rel="noopener"><em><strong>Descargar reporte</strong></em></a>), que me recomendaron recientemente. Es un reporte de 140 páginas y en la 105 encuentro la segunda recomendación para la cadena suministro: “<em><strong>Redistribuya inventario más cerca de sus clientes</strong></em>”, y en el detalle dice:</span></p>
<p class="Quotations" style="padding-left: 40px;"><em><span lang="ES-MX">«La redistribución de su inventario a lugares más cercanos a sus clientes reduce los costes al mantener la mercancía dentro de zonas de envío, lo que le permite ofrecer envíos en el mismo día o en dos días sin incurrir en costes adicionales, y aumenta la resiliencia frente a los problemas regionales de la cadena de suministro.<o:p></o:p></span></em></p>
<p class="Quotations" style="padding-left: 40px;"><span lang="ES-MX"><em>Si tiene un negocio de venta al por menor, considere la posibilidad de convertir las tiendas en minicentros de distribución. La conversión de una sola tienda minorista en un minicentro de cumplimiento tiene el potencial de reducir los costes de última milla en más de un 60%. Estos espacios híbridos de venta al por menor son también una oportunidad para ofrecer opciones de recogida en la acera y de «click-y-cobrar».»</em><o:p></o:p></span></p>
<p><span>Vamos por partes. </span></p>
<p><span><strong>Primera afirmación</strong>: enviar (incurrir en un costo de flete) a una ubicación cercana a sus clientes, permitiría enviar (otro costo de flete) en un tiempo de uno o dos días, pero dice que sin incurrir en costos adicionales.</span></p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2022/08/shopify_png2.png" alt="shopify_png2" width="710" height="773" class="size-full wp-image-31692 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2022/08/shopify_png2.png 710w, https://ingenieriaindustrialonline.com/wp-content/uploads/2022/08/shopify_png2-276x300.png 276w" sizes="(max-width: 710px) 100vw, 710px" /></p>
<p><span>Aquí hay supuestos que habría que validar para que esta afirmación sea correcta en los dos aspectos: <em>«que reduce costo y que reduce tiempo»</em>. Los supuestos son:</span></p>

		<div class="lightbulb tie-list-shortcode">
<ul>
<li><span>Suponemos que el envío de un artículo desde el proveedor a la tienda (mini CD) demora más de dos días. De ser cierto, también debe ser cierto que no hay otras tiendas en la zona que justifiquen una bodega regional. Pero si esto es cierto, tampoco parece buena idea tener esos pocos puntos de venta. Es decir, la recomendación se basa en que hay pocos clientes en esa zona o que queda alejada del centro de distribución principal (CD). Si el tiempo de viaje a la tienda es menos de dos días, también debe ser igual el envío a cualquier cliente atendido desde esa tienda. Es decir, en cuanto a tiempo, me parece que despachar desde el CD es igual a despachar desde la tienda. Y si es para retirar en tienda… <em><strong>¡para eso están las tiendas en primer lugar: para comprar ahí!</strong></em></span></li>
<li>Y sumado a lo anterior, ¿por qué costaría menos enviar a la tienda que enviar a una ubicación cerca de la tienda? Si el argumento es que se puede consolidar carga hasta la tienda, de todos modos, hay que pagar la entrega a domicilio. A menos de que ambos sumados sean menor que una entrega a domicilio desde el CD, dos fletes parecen sumar más que solo uno, por lo que creo que tampoco es eficiente en costo la idea de tienda como mini-CD.</li>
</ul>

		</div>
	
<p><span><strong>Segunda afirmación</strong>: la tienda como mini-CD (…) aumenta la resiliencia frente a los problemas regionales de la cadena de suministro. Supongo que se refiere a que usar la tienda como punto de acopio para ventas con plazos cortos de entrega (1 – 2 días) contribuye a mitigar los problemas asociados con los frecuentes faltantes y excedentes de stock (¿hay otros “problemas regionales”?). Y es que, si la tienda tiene alta disponibilidad de todos los SKUs, no veo porqué un cliente esperaría uno o dos días. 🤔</span></p>
<p><span>Es decir, como tenemos problemas para mantener disponibilidad a un costo razonable en las tiendas, convenzamos a los clientes de pedir y esperar el envío desde el CD a la tienda, para que sea retirado o enviado desde la tienda. Así no tenemos el problema del agotado en tienda. (¡Pero precisamente esto era para resolver la falta de disponibilidad en tienda y no se resuelve!). Seamos justos, acá brindaríamos al cliente visibilidad sobre la disponibilidad: Si en todo momento sabe qué no hay, su opción es esperar. 🚨 También tiene la opción de comprar a la competencia.</span></p>
<p><span>Yo soy comprador por internet y espero más de dos días, pero si voy a una tienda, espero encontrar de entrega inmediata. Hace poco busqué unas pilas especiales en una tienda por departamentos y las encontré en el sitio web. Acto seguido fui a la tienda física a comprarlas, para encontrarme con la sorpresa de que eso solo se vende por internet (supongo que hay que leerlo todo en la página). Hice la compra por internet, pero a otro proveedor. O sea que no les sirvió de nada usar la tienda como mini-CD en ese caso. Además, que es “mini-HUB”, o sea que es de paso, no de acopio.</span></p>
<figure id="attachment_31694" aria-describedby="caption-attachment-31694" style="width: 623px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2022/08/1-de-3.png" alt="" width="623" height="433" class="size-full wp-image-31694" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2022/08/1-de-3.png 623w, https://ingenieriaindustrialonline.com/wp-content/uploads/2022/08/1-de-3-300x209.png 300w" sizes="(max-width: 623px) 100vw, 623px" /><figcaption id="caption-attachment-31694" class="wp-caption-text">Consumers in the Micro-Moment (Los consumidores en el micromomento), Wave 3, Google/Ipsos, EE.UU., agosto de 2015, n=1,291, usuarios de smartphones en línea mayores de 18 años.</figcaption></figure>
<p>&nbsp;</p>
<p><span>Y <strong>la tercera afirmación</strong> es que podría reducir el costo de última milla en más de un 60% usando las tiendas como mini-CDs. Me parece que quedó establecido que, si es entrega a domicilio, menos viajes reducen el costo, no lo contrario. Pero, además, si se trata de entrega a domicilio desde la tienda, eso ya es posible si la tienda mantiene buena disponibilidad en primer lugar. <b>⚠️ Y buena disponibilidad no implica necesariamente que la tienda se convierta en un mini CD ⚠️</b></span></p>
<p><span>No. <strong>La solución a la mala disponibilidad y a los excedentes no es usar las tiendas como mini-CD</strong> (¿no son eso hoy sin ponerles nombres complicados?). La solución ya la he descrito en otros artículos y es simple: Por ejemplo, los invito a revisar <a href="https://ingenieriaindustrialonline.com/gestion-de-inventarios/cross-docking-no-lo-intente-en-casa/"><em><strong>Cross Docking ¡No lo intente en casa!</strong></em></a>.</span></p>
<h2><span>Conclusión</span></h2>

		<div id="conclusion" data-title="Conclusión" class="index-title"></div>
	
<p><span>Después de analizar estas recomendaciones, el resto del reporte pierde mucha fuerza. Decir cosas que parecen novedosas pero que son lo mismo de siempre con otras palabras, o directamente son erróneas, me llevó a escribir esta alerta, y también a ser más exigente conmigo mismo al hacer recomendaciones.</span></p>
<hr />

		<div class="clearfix"></div>
		<div class="about-author about-author-box container-wrapper">
			<div class="author-avatar">
				<img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/avatars/940/60e72e2d7b452-bpfull.jpg" alt="">
			</div>
			<div class="author-info">
				<h4><strong>Matías Birrell Rodríguez</strong></h4>D<span>e profesión, ingeniero civil de industrias, con mención en mecánica, con un MBA en finanzas. Pero principalmente, experto en Teoría de Restricciones y autor de libros acerca de este tema, habiendo trabajado y aprendido directamente con el Dr. Goldratt en Goldratt Group. Adicionalmente es director de <a href="http://www.goldfish.cl/">www.goldfish.cl</a>, empresa que ofrece aplicaciones en la nube, simples y asequibles, para aplicar estos conceptos a las decisiones diarias.</span></p>
<p style="text-align: center;"><a href="https://goldfish.cl/" target="_blank" class="shortc-button small black">¿Quieres optimizar tus procesos? Contáctame</a>

			</div>
		</div>
	
<p>La entrada <a href="https://ingenieriaindustrialonline.com/columnas/recomendaciones-de-expertos-en-management-como-filtrarlas/">Recomendaciones de expertos en management, ¿cómo filtrarlas?</a> se publicó primero en <a href="https://ingenieriaindustrialonline.com">Ingenieria Industrial Online</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ingenieriaindustrialonline.com/columnas/recomendaciones-de-expertos-en-management-como-filtrarlas/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>¿Qué tipo de tecnología tengo que adoptar para crear una verdadera diferencia comercial? &#124; Retail</title>
		<link>https://ingenieriaindustrialonline.com/actualidad/que-tipo-de-tecnologia-tengo-que-adoptar-para-crear-una-verdadera-diferencia-comercial-retail/</link>
					<comments>https://ingenieriaindustrialonline.com/actualidad/que-tipo-de-tecnologia-tengo-que-adoptar-para-crear-una-verdadera-diferencia-comercial-retail/#respond</comments>
		
		<dc:creator><![CDATA[Goldratt Consulting]]></dc:creator>
		<pubDate>Fri, 04 Mar 2022 23:26:16 +0000</pubDate>
				<category><![CDATA[Actualidad]]></category>
		<category><![CDATA[Columnas]]></category>
		<category><![CDATA[Logística]]></category>
		<category><![CDATA[Transformación digital]]></category>
		<category><![CDATA[Cadena de abastecimiento]]></category>
		<category><![CDATA[Datos]]></category>
		<category><![CDATA[Retail]]></category>
		<category><![CDATA[Tecnologías]]></category>
		<guid isPermaLink="false">https://ingenieriaindustrialonline.com/?p=29881</guid>

					<description><![CDATA[<p>Por: Roei Raz – Vicepresidente de ventas de Onebeat Traducción Libre de Javier Arévalo &#8211; Goldratt Consulting Partner Latin America El comercio del retail moderno, como muchos otros ámbitos y campos, ya no es solo un simple juego de oferta y demanda como antes, si es que alguna vez lo fue. En nuestra realidad actual, &#8230;</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/actualidad/que-tipo-de-tecnologia-tengo-que-adoptar-para-crear-una-verdadera-diferencia-comercial-retail/">¿Qué tipo de tecnología tengo que adoptar para crear una verdadera diferencia comercial? | Retail</a> se publicó primero en <a href="https://ingenieriaindustrialonline.com">Ingenieria Industrial Online</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Por: <em>Roei Raz</em> – Vicepresidente de ventas de Onebeat</p>
<p>Traducción Libre de <em>Javier Arévalo</em> &#8211; Goldratt Consulting Partner Latin America</p>
<p>El comercio del retail moderno, como muchos otros ámbitos y campos, ya no es solo un simple juego de oferta y demanda como antes, si es que alguna vez lo fue. En nuestra realidad actual, los consumidores lo quieren todo, aquí y ahora. Cada vez más servicios pasan por la digitalización y la personalización, y los retailers están conscientes de que el uso de la tecnología ya no es una opción, sino una necesidad. Con interminables posibilidades de mejoras tecnológicas en diferentes ámbitos en esta industria y un limitado presupuesto de IT; la pregunta del millón es: <strong><em>¿Qué tipo de tecnología tengo que adoptar para crear una verdadera diferencia comercial? </em></strong></p>
<p>Según mi experiencia durante los últimos 15 años, todos los retailers están de acuerdo en que la principal limitación en este tipo de comercio, es <strong>el tráfico</strong>. No obstante, éste se encuentra entre las variables más difíciles de predecir en un mundo en constante cambio que se enfrenta a la pandemia de Covid-19 en los últimos años. Sin embargo, los retailers exitosos son aquellos que tienen capacidades integradas para convertir altos porcentajes de su tráfico en compradores, con un ticket promedio más alto y un mejor margen de utilidad.</p>
<h2><strong>La necesidad de un nuevo modelo de gestión de la moda y el comercio retail en la era post-Covid-19 </strong></h2>
<p>Con el brote de Covid-19, el mundo ha cambiado drásticamente y a la par el retail y la industria de la moda. La pandemia aceleró algunas tendencias que comenzaron antes de su aparición y uno de los cambios más impactantes, fue la rápida transición de los clientes a plataformas online. Para las marcas tradicionales de establecimientos físicos y las cadenas de retail, esta transición significa una competencia feroz en términos de precio y servicio con las plataformas de comercio electrónico ya establecidas, y al mismo tiempo hace que el tráfico en sus tiendas físicas sea errático, lo que impacta directamente la rentabilidad de las tiendas.</p>
<p>Además, este cambio puso de manifiesto otros desafíos, desde <strong>la necesidad de los retailers para reaccionar rápidamente</strong>, hasta las preferencias de los consumidores que cambian de una tendencia a otra, e incluso se enfrentan a la escasez de mano de obra, lo que en algunos casos ha dificultado el funcionamiento de las tiendas físicas.</p>
<p>También, toda la gestión del flujo y la cadena de suministro enfrentan desafíos sin precedentes, ya que las operaciones del retail a nivel global tienen retrasos y costos cada vez mayores. Por ello, cualquier predicción a largo plazo es cada vez más desafiante y la precisión de los pronósticos se deteriora constantemente. Por ejemplo, <strong><em>¿cómo pueden los retailers de moda planificar su inventario, cuando ni siquiera están seguros de que llegarán a sus tiendas a tiempo para el inicio de la temporada? </em></strong>En esta realidad caótica, se vuelven esenciales las predicciones a corto plazo y la capacidad de controlar el inventario, las ventas y la rotación del producto durante la temporada de compras.</p>
<p>Asimismo, en un mundo que se vuelve cada vez más ecológico, crece la conciencia de los costos ambientales causados por el exceso de producción. Con las malas predicciones de hoy, la sostenibilidad no se podrá asegurar.</p>
<h2><strong>La trampa de la venta a precio completo </strong></h2>
<p>En general, las temporadas en la moda se planifican con mucha anticipación. A lo largo de mi extensa carrera con profesionales de este campo en todo el mundo, he notado algunos factores clave que influyen en este flujo de trabajo. Los retailers determinan los estilos, las cantidades y otros parámetros claves, como la moda predominante y la forma en que se distribuirá la ropa entre las tiendas, lo cual generalmente toma de 6 a 12 meses previos al inicio de una temporada. Sin embargo, los retailers saben que es imposible vender el 100 por ciento de la mercancía a precio completo por diversas razones. Los expertos retailers de moda pueden terminar la temporada con un 85 por ciento o incluso un 90 por ciento de ventas de productos a precio completo; sin embargo, sólo entre el 50 y el 75 por ciento de las ventas están en el precio completo y el resto se vende con grandes descuentos durante las rebajas de fin de temporada.</p>
<p>No hace falta ser un experto para entender por qué las ventas a precio completo en la moda son tan bajas. Cuando un amplio surtido se actualiza constantemente en la tienda en función de las predicciones, que se hicieron mucho antes de que comenzara la temporada, es inevitable terminar con una alta cantidad de productos que se mueven lentamente en los estantes. De hecho, es común ver que a medida que comienzan las ventas de fin de temporada, hasta el 50 por ciento del surtido de una tienda contribuye a menos del 5 por ciento de las ventas.</p>
<p>Los productos de baja rotación se acumulan con el tiempo, reducen el atractivo de las estanterías y bloquean el espacio disponible para nuevas colecciones. Dichos artículos también son el principal motor de los grandes descuentos a los que estamos acostumbrados a ver en los anuncios de «fin de temporada».</p>
<p>Pero la moda también genera «best-sellers», que son productos de rápido movimiento, es decir, se venden más rápido de lo previsto originalmente y por lo tanto se quedan sin existencias con mayor prontitud. Esos son los productos que nos gustan en exhibición, pero aprendimos que ya se han agotado. En tanto, el inventario de los productos de bajo movimiento se acumula en la temporada de “best-sellers”,lo  que reduce la capacidad de la tienda para convertir el tráfico en compradores.</p>
<p>Las ventas de fin de temporada son la oportunidad de los retailers para liquidar los productos de bajo movimiento y comenzar la próxima temporada de nuevo. No podemos salir de la espiral de liquidación, si nos limitamos a pensar que esos productos son los villanos; esto sólo nos llevará a criticar nuestra planificación y tratar de optimizar nuestras acciones dentro del enorme ruido. Hay que mirar la realidad con mayor resolución para entender la causa y efecto.</p>
<h2><strong>La basura de una tienda es el tesoro de otra </strong></h2>
<p>Los productos de lento y rápido movimiento, son en su mayoría, definiciones específicas de su ubicación. De hecho, hay malos productos con diseños y precios incorrectos que no se pueden vender sin un gran descuento; sin embargo, la mayoría de los que se mueven lentamente en una tienda, en realidad son los “best- sellers” en otras. Es decir, mientras veíamos que estos productos bloqueaban las estanterías de algunas tiendas, en realidad eran necesarios para las ventas en otras, donde los productos se agotaron demasiado pronto en la temporada.</p>
<p><strong>Si tuviéramos el algoritmo adecuado para identificar estos productos de movimientos lentos y rápidos en tiempo real</strong> tan pronto como comenzara la temporada, podríamos tomar medidas inmediatas para garantizar que el producto correcto llega al lugar y momento indicados para maximizar su venta a precio completo.</p>
<h2><strong>Predicción a corto plazo, automatización y optimización </strong></h2>
<p>Las cifras y las tendencias actuales demuestran la importancia de que los retailers presten atención y se centren en la predicción a corto plazo y la toma de decisiones de manera inmediata. Según mi experiencia, una de las mejores maneras de lograrlo es cambiar nuestro enfoque de tener un mejor plan hacia la adopción de tecnologías que se adapten a la temporada.</p>
<p><strong>Dichas tecnologías se basan en herramientas de predicción que ayudan a los retailers a predecir a corto plazo y automatizar los procesos de mercadeo en las tiendas</strong>. La precisión de las estimaciones a corto plazo impacta en las ventas y las ganancias de la temporada, y optimiza los traslados de reabastecimiento entre tiendas así como la gestión de los productos de rápido movimiento, la liquidación de los de lento movimiento y el surtido general de la tienda durante la temporada.</p>
<p>Después de más de una década de trabajar en el comercio retail, y tras cientos de conversaciones con líderes internacionales del retail, sé con certeza que el uso y la implementación de esas herramientas logran un aumento de entre 5 y 10 por ciento en las ventas por tienda durante todo el año, y una mejoría del 20 por ciento en las ventas de temporada a precio completo. Además, como las acciones se traducen en resultados inmediatos, el rendimiento se puede medir con precisión y en tiempo real.</p>
<p>Más allá de las mejoras financieras, con esta tecnología los retailers pueden transitar más rápido hacia una política de cero residuos, ya que estos algoritmos les ayudarán a no dejar productos en los estantes y estar un paso adelante de la industria del retail convencional.</p>
<p><iframe loading="lazy" width="560" height="315" src="https://www.youtube.com/embed/iRvaWHk3A8k" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="allowfullscreen"></iframe></p>
<hr />

		<div class="clearfix"></div>
		<div class="about-author about-author-box container-wrapper">
			<div class="author-avatar">
				<img decoding="async" src="" alt="">
			</div>
			<div class="author-info">
				<h4>Roei Raz </h4>Vicepresidente de ventas de Onebeat y exconsultor de los principales grupos del retail alrededor del mundo. Raz tiene una Licenciatura en Ingeniería Industrial y un MBA, ambos de la Universidad de Tel Aviv.</p>
<p style="text-align: center;"><a href="https://blog.goldrattconsulting.net/" target="_blank" class="shortc-button small black">Goldratt Consulting América Latina</a>

			</div>
		</div>
	
<p>La entrada <a href="https://ingenieriaindustrialonline.com/actualidad/que-tipo-de-tecnologia-tengo-que-adoptar-para-crear-una-verdadera-diferencia-comercial-retail/">¿Qué tipo de tecnología tengo que adoptar para crear una verdadera diferencia comercial? | Retail</a> se publicó primero en <a href="https://ingenieriaindustrialonline.com">Ingenieria Industrial Online</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ingenieriaindustrialonline.com/actualidad/que-tipo-de-tecnologia-tengo-que-adoptar-para-crear-una-verdadera-diferencia-comercial-retail/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Nivel de servicio: ¿es solo un KPI?</title>
		<link>https://ingenieriaindustrialonline.com/columnas/nivel-de-servicio-es-solo-un-kpi/</link>
					<comments>https://ingenieriaindustrialonline.com/columnas/nivel-de-servicio-es-solo-un-kpi/#respond</comments>
		
		<dc:creator><![CDATA[Matías Birrell Rodríguez]]></dc:creator>
		<pubDate>Fri, 14 Jan 2022 21:55:15 +0000</pubDate>
				<category><![CDATA[Columnas]]></category>
		<category><![CDATA[Consultoría]]></category>
		<category><![CDATA[Gestión de inventarios]]></category>
		<category><![CDATA[Logística]]></category>
		<category><![CDATA[Teoría de restricciones (TOC)]]></category>
		<category><![CDATA[Agotados]]></category>
		<category><![CDATA[Fill Rate]]></category>
		<category><![CDATA[Nivel de servicio]]></category>
		<category><![CDATA[OTIF]]></category>
		<category><![CDATA[Stock Out]]></category>
		<category><![CDATA[Teoría de Restricciones]]></category>
		<category><![CDATA[TOC]]></category>
		<guid isPermaLink="false">https://ingenieriaindustrialonline.com/?p=29382</guid>

					<description><![CDATA[<p>¿Para qué está su empresa en el negocio? ¿Para ganar dinero? Yo sé que esa fue la respuesta en el libro La Meta, sin embargo he visto muchas declaraciones de misión y ninguna dice eso. El dinero es un resultado de cumplir la misión de la empresa. En la continuación del libro La Meta, el &#8230;</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/columnas/nivel-de-servicio-es-solo-un-kpi/">Nivel de servicio: ¿es solo un KPI?</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><span>¿Para qué está su empresa en el negocio? ¿Para ganar dinero? Yo sé que esa fue la respuesta en el libro <em><strong><a href="https://ingenieriaindustrialonline.com/teoria-de-restricciones-toc/la-meta-y-las-3-lecciones-inmortales-de-eli-goldratt/">La Meta</a></strong></em>, sin embargo he visto muchas declaraciones de misión y ninguna dice eso. El dinero es un resultado de cumplir la misión de la empresa. En la continuación del libro La Meta, el Dr. Goldratt nos dice que una buena estrategia tiene tres condiciones necesarias. En los últimos capítulos de <em><strong><a href="https://www.amazon.com/dp/B00GOWYWMA">No Fue La Suerte</a></strong></em>, la discusión de Alex con los directores lleva a concluir que los tres pilares de <em><strong><a href="https://blog.goldrattconsulting.net/de-una-buena-estrategia-a-un-desempeno-exitoso-la-magia-del-numero-3/">una buena estrategia</a></strong></em> son: generar un buen entorno a empleados ahora y en el futuro; dar excelente servicio a clientes ahora y en el futuro; y generar buena rentabilidad para accionistas ahora y en el futuro.</span></p>
<p><span>Cualquier misión debería ser consistente con esas condiciones necesarias.</span></p>
<h2><span>¿Dónde inicia todo?</span></h2>

		<div id="donde-inicia-todo" data-title="¿Dónde inicia todo?" class="index-title"></div>
	
<p><span>Es fácil darse cuenta de que sin ventas no hay empresa. Y que, habiendo competencia, debemos construir una <strong>ventaja competitiva</strong> que nos destaque y haga fluir las ventas basadas en intercambio de valor.</span></p>
<p><span>Todas las empresas que están vendiendo algo han logrado construir una oferta compuesta de un producto que tiene una relación precio/calidad atractiva. De otro modo no venderían.</span></p>
<p><span>Diseñar o encontrar esos productos, luego producirlos o comprarlos, hacer un buen empaque, producir materiales de marketing atractivos, la inversión en publicidad, el despliegue de la fuerza de ventas; todo esto es un gran esfuerzo en tiempo y dinero.</span></p>
<p><span>Y la promesa que se le hace al mercado consiste en el producto, el precio y una condición de entrega. La entrega puede ser prometiendo un plazo, o puede ser prometiendo disponibilidad en el punto de venta.</span></p>
<p><span><strong>Todo inicia haciendo una promesa atractiva</strong> y los clientes la aceptan, generándose las ventas.</span></p>
<h2><span>¿Qué pasa cuando se incumple la promesa?</span></h2>

		<div id="que-pasa-cuando-se-incumple-la-promesa" data-title="¿Qué pasa cuando se incumple la promesa?" class="index-title"></div>
	
<p><span>Las ventas no se detienen inmediatamente. Hay una frustración de los clientes que se traduce en buscar alternativas. Pero veamos cuál es la parte de la promesa que se incumple con más frecuencia.</span></p>
<p><span>Ni el producto se degrada con frecuencia ni el precio se altera con frecuencia. Estos dos aspectos son muy cuidados por las empresas.</span></p>
<p><span>Lo habitual es que se incumpla la entrega, ya sea incumpliendo el plazo prometido o simplemente generando un agotado (quiebre o <em>stock out</em>) en el punto de venta.</span></p>
<p><span>Los competidores no son mucho mejores en la entrega, pero esto solo genera más frustración.</span></p>
<p><span>Tal vez el efecto más nocivo sea al interior de las empresas. El incumplimiento de entrega genera inmediatamente quejas desde el mercado, lo que se traduce en <strong>emergencias, reprogramaciones, sobre costos, y mucho <em>stress</em></strong>.</span></p>
<p><span><em>¿Cómo se siente usted cuando incumple un plazo de entrega?</em> <em>¿O cuando más del 10% de sus productos están agotados en las tiendas?</em> Estos hechos generan una onda de presión a lo largo y ancho de la organización. Por lo menos estoy seguro de que no son fuente de satisfacción para nadie.</span></p>
<p><span><em>¿Y si un competidor tuviera un nivel de servicio muy superior?</em> Es muy probable que las ventas bajen y los márgenes se erosionen. Ahora ya nadie está contento.</span></p>
<h2><span>La causa del incumplimiento</span></h2>

		<div id="la-causa-del-incumplimiento" data-title="La causa del incumplimiento" class="index-title"></div>
	
<p><span>Las consecuencias de incumplir la promesa son muchas y negativas, eso ya lo intuíamos.</span></p>
<p><span>Y basta con tener un poco de experiencia para saber que los incumplimientos son muy frecuentes.</span></p>
<p><em>¿Por qué será que, sabiendo lo mal que todos lo pasan al incumplir, las empresas siguen haciendo promesas que incumplen?</em></p>
<p><span>Una explicación podría ser que a algunos gerentes no les importa mentir y prometen cosas para conseguir más ventas. Pero ya sabemos que incumplir tiene demasiadas consecuencias negativas, por lo que esta explicación no puede ser la mayoritaria. Son muchas las empresas que incumplen sus promesas de entrega y deben ser muy pocas o ninguna las que basen su estrategia de ventas en mentir.</span></p>
<p><span>Entonces, ya que los hechos nos muestran un incumplimiento masivo, la explicación debe ser que se prometen plazos o <em>stock</em> sin tener seguridad de cumplirlo, aunque la intención sea de no fallar, lo que se manifiesta en todas las acciones para resolver las emergencias y la frustración que sienten los responsables.</span></p>
<p><span>Es decir, <strong>la causa del incumplimiento es simplemente que se está aplicando un conocimiento para hacer la promesa con alta probabilidad de ser incumplida</strong>.</span></p>
<h2><span>¿Y existe alguna solución?</span></h2>

		<div id="y-existe-alguna-solucion" data-title="¿Y existe alguna solución?" class="index-title"></div>
	
<p><span>Si la mayoría de las empresas incumple, pareciera que no existe una buena solución, porque si existiera ¡todo el mundo la estaría usando!</span></p>
<p><span>No sé cómo se le llama a esa falacia argumental, pero es claramente una falacia. Si algo existe y es muy bueno, todo el mundo debería estar usándolo. (Creo que es falacia <em>ad populum</em>).</span></p>
<p><span>Me acordé de un libro que escribió Jeff Cox (coautor de La Meta), <strong><a href="https://www.amazon.com/dp/8401377870">El hombre que quiso vender la rueda</a></strong>. Empieza con el invento de la rueda y se la va a ofrecer a constructores de pirámides para elevar la productividad, y le responden algo así: “<em>¿quién está usando esto?, si fuera tan bueno, ya muchos lo usarían, ¿no?</em>”</span></p>
<p><span>El conocimiento para calcular una fecha de entrega razonable y que sea altamente probable su cumplimiento existe, es el <strong>Control de Carga de Teoría de Restricciones</strong>.</span></p>
<p><span>El conocimiento para calcular y mantener inventarios adecuados en toda la cadena de suministro existe, es la <strong>Administración Dinámica de Amortiguadores de Teoría de Restricciones</strong>.</span></p>
<p><span>Estos dos métodos son efectivos, nunca he visto un caso de fracaso y son simples de implementar. Pero tienen una “<em>trampa</em>”. <strong>Para implementarlos hay que abandonar varias de las creencias que damos por válidas sin cuestionar</strong> y que son la base de las metodologías que hoy se usan para prometer fechas o para calcular inventarios. Y los esfuerzos de mejora actuales no cuestionan las creencias básicas, por lo que los resultados prevalecientes siguen siendo los que ya conocemos.</span></p>
<h2><span>Conclusión</span></h2>

		<div id="conclusion" data-title="Conclusión" class="index-title"></div>
	
<p><span>El nivel de servicio, en especial la entrega a tiempo (OTIF) o la disponibilidad (FILL RATE), no son solo unos KPIs para medir la gestión. En empresas con productos físicos, es una condición necesaria para una buena estrategia. Sin ese nivel de desempeño excelente, la vida de los clientes no es tan buena, y mucho peor es la experiencia interna en las empresas, muchas veces causa del “síndrome del trabajador quemado” (ver <a href="https://blog.goldfish.cl/consultoria/mundo-vuca-empresa-vuca/">https://blog.goldfish.cl/consultoria/mundo-vuca-empresa-vuca/</a>). Y, como resultado, la rentabilidad está limitada.</span></p>
<p><span>Es posible, y debería ser indispensable, lograr excelente servicio para cimentar una empresa en que valga la pena trabajar, y a la que uno desee comprarle.</span></p>
<hr />

		<div class="clearfix"></div>
		<div class="about-author about-author-box container-wrapper">
			<div class="author-avatar">
				<img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/avatars/940/60e72e2d7b452-bpfull.jpg" alt="">
			</div>
			<div class="author-info">
				<h4><strong>Matías Birrell Rodríguez</strong></h4>D<span>e profesión, ingeniero civil de industrias, con mención en mecánica, con un MBA en finanzas. Pero principalmente, experto en Teoría de Restricciones y autor de libros acerca de este tema, habiendo trabajado y aprendido directamente con el Dr. Goldratt en Goldratt Group. Adicionalmente es director de <a href="http://www.goldfish.cl/">www.goldfish.cl</a>, empresa que ofrece aplicaciones en la nube, simples y asequibles, para aplicar estos conceptos a las decisiones diarias.</span></p>
<p style="text-align: center;"><a href="https://goldfish.cl/" target="_blank" class="shortc-button small black">¿Quieres optimizar tus procesos? Contáctame</a>

			</div>
		</div>
	
<p>La entrada <a href="https://ingenieriaindustrialonline.com/columnas/nivel-de-servicio-es-solo-un-kpi/">Nivel de servicio: ¿es solo un KPI?</a> se publicó primero en <a href="https://ingenieriaindustrialonline.com">Ingenieria Industrial Online</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ingenieriaindustrialonline.com/columnas/nivel-de-servicio-es-solo-un-kpi/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Programación de empleados mediante programación entera</title>
		<link>https://ingenieriaindustrialonline.com/investigacion-de-operaciones/programacion-de-empleados-mediante-programacion-entera/</link>
					<comments>https://ingenieriaindustrialonline.com/investigacion-de-operaciones/programacion-de-empleados-mediante-programacion-entera/#respond</comments>
		
		<dc:creator><![CDATA[Bryan Salazar López]]></dc:creator>
		<pubDate>Sat, 27 Nov 2021 18:27:47 +0000</pubDate>
				<category><![CDATA[Investigación de operaciones]]></category>
		<category><![CDATA[Logística]]></category>
		<category><![CDATA[Asignación]]></category>
		<category><![CDATA[Google OR-Tools]]></category>
		<category><![CDATA[Optimización]]></category>
		<category><![CDATA[Programación de empleados]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scheduling]]></category>
		<category><![CDATA[Turnos]]></category>
		<guid isPermaLink="false">https://ingenieriaindustrialonline.com/?p=29010</guid>

					<description><![CDATA[<p>Las organizaciones que gestionan operaciones cada vez más robustas, requieren en cierto modo de la asignación de personas y recursos a tareas específicas. Desde hace algún tiempo se ha popularizado un planteamiento en torno al objetivo de la logística, generalmente aceptado como: «El objetivo de la logística consiste en llevar el producto correcto, en la &#8230;</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/programacion-de-empleados-mediante-programacion-entera/">Programación de empleados mediante programación entera</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>Las organizaciones que gestionan operaciones cada vez más robustas, requieren en cierto modo de la asignación de personas y recursos a tareas específicas. Desde hace algún tiempo se ha popularizado un planteamiento en torno al objetivo de la logística, generalmente aceptado como: «<em>El objetivo de la logística consiste en llevar el producto correcto, en la cantidad correcta, en el lugar correcto, en el momento correcto</em>» (acepta variaciones).</p>
<p>Ahora bien, tendencias de optimización abordan nuevos objetivos y plantean nuevos desafíos alrededor de la intralogística: <em>optimización extrema</em>. Es decir, optimización en la asignación de recursos internos, como por ejemplo: <em>el recurso correcto, asignado a la tarea correcta, en el momento correcto</em>.</p>
<p>Cuando aterrizamos el anterior planteamiento en términos prácticos, entendemos que se hace necesario resolver problemas de programación complejos de forma regular, que permitan la gestión de las operaciones de la organización. Un caso puntual consiste en la <strong>programación del recurso humano</strong>, sujeta a un conjunto complejo de restricciones y requisitos: <em>número de empleados, días laborales, turnos, tiempos inactivos, permisos, políticas internas, etc.</em></p>
<p>El planteamiento de nuevos desafíos de optimización, guarda una estrecha relación con la posibilidad que nos brinda la tecnología de abordar estos retos. Si bien, la complejidad de las organizaciones es cada vez mayor, los algoritmos cada vez son más refinados, y los solucionadores cada vez más robustos e integrados.</p>
<p>El objetivo de este artículo consiste en utilizar las técnicas robustas del solucionador basado en restricciones <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/que-es-y-para-que-sirve-google-or-tools/"><strong>OR-Tools de Google</strong></a>, para resolver un problema de programación de empleados sujeto a un conjunto complejo de restricciones.</p>

		<div class="box info  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>Cuando cursaban el tercer año, el Director del Lakeside School, les planteó a Bill Gates y Kent Evans, un problema muy complejo que aun nadie lograba resolver.</p>
<p>Lakeside se había fusionado con una escuela femenil local, por lo tanto, el alumnado había crecido considerablemente, y nadie lograba descifrar cómo ajustar los horarios de clase en las nuevas condiciones. Las restricciones de la programación no eran pocas, por ejemplo:</p>
<ul>
<li>Ningún maestro podía impartir cuatro clases seguidas</li>
<li>Debían considerarse pausas para alimentación</li>
<li>La cantidad de alumnos por sesión de clase no podía pasar de 16</li>
<li>Algunas clases como, por ejemplo, las clases de música no podían asignarse en salones conjuntos.</li>
</ul>
<p>La complejidad del problema hizo que Gates buscara la ayuda de Paul Allen, con quien lograría resolver el modelo. Este fue quizá, el algoritmo que les abrió un camino comercial, puesto que otras organizaciones que tenían problemas de programación, comenzarían a acudir a esta pareja de estudiantes.</p>
<p>Bill Gates y Paul Allen fundaron en 1975 la compañía Microsoft, el resto es historia. 
			</div>
		</div>
	
<hr />
<h2>Caso de aplicación</h2>

		<div id="caso-de-aplicacion" data-title="Caso de aplicación" class="index-title"></div>
	
<blockquote class=" quote-simple "><p>La compañía Stark Lab ha adquirido un nuevo torno para su área de mecanizado. El volumen de trabajo que tiene el área, demanda que esta nueva máquina sea operada en los 3 turnos del día (mañana, tarde y noche).</p>
<p>La compañía ha contratado a 3 trabajadores para operar la nueva máquina, y planea emplear a un aprendiz (estudiante) como cuarto operario.</p>
<p>El supervisor debe diseñar una programación para los cuatro operarios para un periodo de 7 días (una semana), sujeto a las siguientes condiciones:</p>
<ul>
<li>Cada día se divide en tres turnos de 8 horas.</li>
<li>Todos los días, cada turno se asigna a un solo operario, y ningún operario trabajará más de un turno por día.</li>
<li>El último día de la programación se realizan actividades de mantenimiento y limpieza profunda en planta. Por tal razón, solo se trabaja el turno de la mañana.</li>
<li>El operario aprendiz (estudiante), cuenta con la colaboración de la compañía para realizar sus estudios. Por tal razón, no puede trabajar el tercer día de la semana en el turno de la noche.</li>
<li>Como mínimo deben trabajarse 19 turnos en total en la programación. Esta cantidad de turnos ya considera los turnos destinados a mantenimiento y limpieza del último día de la programación.</li>
<li>En el caso en el que no se pueda realizar una distribución de turnos igualitaria, la distribución de los turnos debe realizarse de manera uniforme. Esto quiere decir que no puede existir una diferencia mayor a un turno entre las asignaciones para cada operario.</li>
</ul>
</blockquote>
<p>Se desea desarrollar una programación de empleados (asignación de empleados, turnos y días), que cumpla con las restricciones del planteamiento.</p>
<h3>¿Qué necesitaremos?</h3>

		<div id="que-necesitaremos" data-title="¿Qué necesitaremos?" class="index-title"></div>
	
<p>En el desarrollo de este ejercicio emplearemos:</p>

		<div class="plus tie-list-shortcode">
<div class="plus tie-list-shortcode">
<ul>
<li><em><strong>Colaboratory</strong>:<span> </span></em>Este es un entorno de programación y ejecución virtual de Python desarrollado por Google. Nos permitirá no tener la necesidad de realizar ninguna instalación en nuestros equipos. Todo lo que desarrollemos lo ejecutaremos en un cuaderno virtual.</li>
<li><strong><em>Python</em></strong>: Este será el lenguaje de programación que vamos a utilizar, y advertimos: No es necesario tener conocimientos previos, y el objetivo del artículo no es convertirnos en programadores expertos. Utilizaremos fragmentos de códigos, librerías disponibles, y explicaremos lo necesario para configurar nuestro desarrollo de acuerdo a los objetivos específicos de nuestros modelos.</li>
<li><strong><em>ORTools</em></strong>: OR-Tools es un paquete de software portable de código abierto desarrollado por Google, para resolución de problemas de optimización.</li>
</ul>

		</div>
	
</div>
<h3>Paso 1: Crear el entorno de trabajo en Colaboratory</h3>

		<div id="paso-1-crear-el-entorno-de-trabajo-en-colaboratory" data-title="Paso 1: Crear el entorno de trabajo en Colaboratory" class="index-title"></div>
	
<div id="paso-1-crear-el-entorno-de-trabajo-en-colaboratory" data-title="Paso 1: Crear el entorno de trabajo en Colaboratory" class="index-title visible full-visible"></div>
<p><span>Lo primero que vamos a hacer consiste en crear un entorno de trabajo en <em>Google</em> </span><em>Colaboratory</em><span>, así que vayamos allá: </span><a href="https://colab.research.google.com/#create=true" target="_blank" rel="noopener"><em><strong>Abrir cuaderno nuevo</strong></em></a><span>.</span></p>
<p>Verán que tienen un lienzo para programar el modelo, así que en este cuaderno podemos ir generando las líneas de código que explicaremos en los pasos siguientes.</p>
<h3>Paso 2: Instalar Google Or Tools</h3>

		<div id="paso-2-instalar-google-or-tools" data-title="Paso 2: Instalar Google Or Tools" class="index-title"></div>
	
<p>Es necesario instalar la librería de Google Or Tools en nuestro entorno de <em>Colaboratory</em> para poder utilizar nuestro modelo de programación entera.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>!pip install ortools</code></pre>
</div>
<p>Al ejecutar esta instrucción instalaremos el software del solucionador de Google.</p>
<h3>Paso 3: Importar las librerías necesarias</h3>

		<div id="paso-3-importar-las-librerias-necesarias" data-title="Paso 3: Importar las librerías necesarias" class="index-title"></div>
	
<p>Este modelo empleará programación entera, y por lo tanto instalaremos las librerías dispuestas por Google OR Tools para ello. En este caso utilizaremos un solucionador de programación entera llamado CP-SAT.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Importar la librería para utilizar CP-SAT
from ortools.sat.python import cp_model</code></pre>
</div>
<p><span>De esta manera, tenemos todo lo necesario para empezar a desarrollar nuestro código.</span></p>
<h3>Paso 4: Crear los datos de entrada del modelo</h3>

		<div id="paso-4-crear-los-datos-de-entrada-del-modelo" data-title="Paso 4: Crear los datos de entrada del modelo" class="index-title"></div>
	
<p>Los datos de entrada de un problema de programación de empleados suelen ser simples, la complejidad recae en el modelamiento de las restricciones. En este caso, los datos de entrada básicos son: <em>número de empleados, número de turnos por día, número de días del plan de programación</em>.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Datos de entrada del modelo
operarios = 4
turnos = 3
dias = 7
total_operarios = range(operarios)
total_turnos = range(turnos)
total_dias = range(dias)

turnos_no_laborales = 2
turnos_laborales = (turnos * dias) - turnos_no_laborales</code></pre>
</div>
<p>Así mismo, definimos el número de turnos no laborales, recordemos que el planteamiento del problema nos indicó que el último día se trabajaría tan solo un turno (por labores de mantenimiento y limpieza), por lo tanto, dos turnos pueden considerarse como no laborales.</p>
<p>¿Por qué utilizamos una variable llamada <em>operarios </em>y otra llamada <em>total_operarios</em>? Además, ¿Para qué se emplea la función <em>range</em>? Bueno, la variable <em>operarios </em>contendrá el valor entero de la cantidad de operarios del modelo; mientras tanto, la variable <em>total_operarios</em> dado que emplea la función <em>range</em>, contendrá la secuencia de números que nos ayudará a definir a cada operario, lo hace de esta manera: range(4) = 0, 1, 2, 3. Como podemos ver, inicia la secuencia en 0, y finaliza en el entero anterior al parámetro dado, en este caso el parámetro dado fue 4, por lo tanto, el entero anterior será 3.</p>
<h3>Paso 5: Crear el modelo de programación</h3>

		<div id="paso-5-crear-el-modelo-de-programacion" data-title="Paso 5: Crear el modelo de programación" class="index-title"></div>
	
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Crear el modelo
model = cp_model.CpModel()</code></pre>
</div>
<h3>Paso 6: Crear las variables de asignación</h3>

		<div id="paso-6-crear-las-variables-de-asignacion" data-title="Paso 6: Crear las variables de asignación" class="index-title"></div>
	
<p>El problema de programación de empleados es un caso de asignación, y por lo tanto, empleamos variables de decisión de asignación. Veamos:</p>
<p>Necesitamos definir <em>qué operario</em> será asignado a <em>qué turno</em> en <em>qué día </em>en específico. Por lo tanto podemos utilizar variables de asignación binarias, que tomen un valor de 1, si esa asignación específica tiene lugar, y tomen valor de 0, en el caso en el que no.</p>
<p>Algebraicamente sería algo así:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/algebra.png" alt="algebra" width="503" height="93" class="size-full wp-image-29015 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/algebra.png 503w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/algebra-300x55.png 300w" sizes="(max-width: 503px) 100vw, 503px" /></p>
<p>En el caso en el que tuviésemos que definir manualmente cada una de las variables de asignación, requeriríamos un total de 84 variables (7 días * 3 turnos * 4 operarios).</p>
<p>Veamos cómo podemos utilizar los ciclos en <em>Python </em>para simplificar la definición de las variables &#8211; Eso sí, en lugar de <em>X </em>llamaremos a la variable <em>asignacion</em>, y en lugar de <em>a, b </em>y<em> c, </em>utilizaremos la primera letra de cada parámetro.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code># Creamos las variables de asignación
# asignacion[(o, d, t)]: operario 'o' trabaja en el turno 't' el día 'd'.
asignacion = {}
for o in total_operarios:
    for d in total_dias:
        for t in total_turnos:
            asignacion[(o, d, t)] = model.NewBoolVar('turno_n%id%is%i' % (o, d, t))</code></pre>
</div>
<p>De esta manera, haciendo uso de ciclos, creamos todas las variables de asignación del modelo; así mismo, definimos su naturaleza (<em>NewBoolVar = Variable booleana</em>). De manera que en el caso de que una asignación se efectúe su resultado será <em>«verdadero / True»</em>.</p>
<h3>Paso 7: Crear las restricciones del modelo</h3>

		<div id="paso-7-crear-las-restricciones-del-modelo" data-title="Paso 7: Crear las restricciones del modelo" class="index-title"></div>
	
<p>La complejidad de un problema de programación de recursos se define por la naturaleza de sus restricciones. Si bien las restricciones acotan el conjunto solución, y por ende los tiempos de procesamiento, la dificultad subyace del modelamiento. Veamos cómo abordar cada una de las restricciones que nos plantea el caso de aplicación.</p>
<p><strong>Cada turno se asigna a un solo operario</strong></p>
<p>La sumatoria de todas las asignaciones efectuadas en un día <em>d, </em>en el turno <em>t</em>, deben ser menores o iguales a 1. Eso restringe la posibilidad de que un mismo turno, en un mismo día, sea asignado a dos operarios diferentes.</p>
<p>Por ejemplo:</p>
<p style="text-align: center;">X<sub>000</sub> + X<sub>100</sub> + X<sub>200</sub> + X<sub>300</sub> &lt;= 1</p>
<p>Esta restricción nos diría que la sumatoria de todas las asignaciones del día <em>0</em>, para el turno <em>0</em>, de los operarios <em>0, 1, 2 y 3</em>; debe ser menor o igual a <em>1</em>. Es decir que el turno <em>0</em>, del día <em>0</em> no puede ser asignado a más de un operario.</p>
<p>Veamos cómo <em>Python </em>nos puede simplificar esta formulación de restricciones:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code># Cada turno es asignado a un operario en el periodo de programación, o no es asignado
for d in total_dias:
    for t in total_turnos:
        model.Add(sum(asignacion[(o, d, t)] for o in total_operarios) &lt;= 1)</code></pre>
</div>
<p>Esta restricción bien podría formularse como que la sumatoria deba ser igual a 1. Sin embargo, recordemos que existen un par de turnos no laborales, y por lo tanto estos no deben ser asignados.</p>
<p>En el caso en el que tuviésemos que definir manualmente cada una de estas restricciones, requeriríamos un total de 21 restricciones (7 días * 3 turnos).</p>
<p><strong>Cada operario trabaja como máximo un turno por día</strong></p>
<p>La sumatoria de todas las asignaciones efectuadas en un día <em>d, </em>para el operario <em>o</em>, deben ser menores o iguales a 1. Eso restringe la posibilidad de que un operario, en un mismo día, sea asignado a dos turnos diferentes.</p>
<p>Por ejemplo:</p>
<p style="text-align: center;">X<sub>000</sub> + X<sub>001</sub> + X<sub>002</sub> &lt;= 1</p>
<p>Esta restricción nos diría que la sumatoria de todas las asignaciones del día <em>0</em>, para el operario <em>0</em>, de los turnos <em>0, 1, y 2</em>; debe ser menor o igual a <em>1</em>. Es decir que el operario <em>0</em>, del día <em>0</em> no puede ser asignado a más de un turno.</p>
<p>Veamos cómo <em>Python </em>nos puede simplificar esta formulación de restricciones:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code># Cada operario trabaja como máximo un turno por día
for o in total_operarios:
    for d in total_dias:
        model.Add(sum(asignacion[(o, d, t)] for t in total_turnos) &lt;= 1)</code></pre>
</div>
<p>En el caso en el que tuviésemos que definir manualmente cada una de estas restricciones, requeriríamos un total de 28 restricciones (7 días * 4 operarios).</p>
<p><strong>Restricción del operario aprendiz</strong></p>
<p>De acuerdo al caso de aplicación, <em>el operario aprendiz no pude trabajar el tercer día de la semana, en el turno de la noche</em>. Esto nos permite abordar restricciones de requerimientos puntuales sobre el modelo.</p>
<p>Recordemos que el índice, tanto de operarios, turnos y días, comienza en 0. Por lo tanto, para efectos de la formulación de la restricción, el tercer día de la semana será el día 2 (los siete días de la semana son 0, 1, 2, 3, 4, 5 y 6); y el turno de la noche, será el turno 2 (turnos 0, 1 y 2 / mañana, tarde y noche).</p>
<p>Por otro lado, los operarios también son nombrados de acuerdo a sus índices: 0, 1, 2 y 3. Podemos arbitrariamente elegir el índice del operario aprendiz; en nuestro caso diremos que se trata del operario 0.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Restricción del operario (o) 1 para trabajar el día (d) 2, en el turno (t) 2
model.Add(asignacion[(0, 2, 2)] != 1)</code></pre>
</div>
<p>El operador != se utiliza para denotar <em>diferente de</em>, por lo tanto, la restricción indica que la asignación del operario 0, el día 2, en el turno 2, deberá ser diferente de 1; es decir que, al tratarse de una variable booleana, deberá ser <em>Falso = 0.</em></p>
<p><strong>Restricciones de turnos no programados (mantenimiento y limpieza)</strong></p>
<p>De acuerdo al caso de aplicación, el último día de la semana se programan actividades de mantenimiento y limpieza, y que por lo tanto, solo se trabaja en el turno de la mañana. Por esta razón, debemos excluir a los turnos de la tarde y la noche de la programación (turnos <em>1</em> y <em>2</em>) del último día (día 6).</p>
<p>Siguiendo con nuestras denominaciones algebraicas de ejemplo, tendríamos algo así:</p>
<p style="text-align: center;">X<sub>061</sub> + X<sub>161</sub> + X<sub>261</sub> + X<sub>361</sub> == 0</p>
<p style="text-align: center;">X<sub>062</sub> + X<sub>162</sub> + X<sub>262</sub> + X<sub>362</sub> == 0</p>
<p>Veamos cómo <em>Python </em>nos puede simplificar esta formulación de restricciones:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code># Restricción de turnos no programados
model.Add(sum(asignacion[(o, 6, 1)] for o in total_operarios) == 0)
model.Add(sum(asignacion[(o, 6, 2)] for o in total_operarios) == 0)</code></pre>
</div>
<p><strong>Restricción de turnos mínimos programados</strong></p>
<p>De acuerdo al caso de aplicación, debe programarse una cantidad de 19 turnos laborales. Es decir, la cantidad de turnos diarios (3) * la cantidad de días del programa (7); menos la cantidad de turnos no programados por mantenimiento y limpieza (2).</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Como mínimo deben trabajarse "turnos_laborales"
min_turnos_totales = []
for o in total_operarios:
    for d in total_dias:
        for t in total_turnos:
            min_turnos_totales.append(asignacion[(o, d, t)])
model.Add(sum(min_turnos_totales) &gt;= turnos_laborales)</code></pre>
</div>
<p>Esta restricción involucra a todas las variables de asignación del modelo, y por lo tanto el uso de ciclos es importante para simplificar el desarrollo de la formulación. Básicamente indica que la sumatoria de todas las variables de decisión (asignación) del modelo (que son booleanas, y para este efecto podemos decir que binarias), debe ser mayor o igual al mínimo de turnos laborales exigidos para programación.</p>
<p>La restricción es 1 sola, pero involucra las 84 variables de asignación.</p>
<p><strong>Restricción de uniformidad en la distribución de turnos</strong></p>
<p>El objetivo de estas restricciones es la de distribuir de la manera más uniforme posible los turnos asignados. En términos prácticos, el caso de aplicación indica que, no puede existir una diferencia mayor a un turno entre las asignaciones de los operarios. Es decir, ningún operario podrá tener asignados dos turnos más que otro operario, por ejemplo.</p>
<p>Para lograr esto es necesario realizar una serie de cálculos intermedios sencillos, con el objetivo de identificar: <em>número de turnos asignables, cantidad mínima de turnos por operario, cantidad máxima de turnos por operario, entre otros</em>.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>min_turnos_por_operario = ((turnos * dias) - turnos_no_laborales) // operarios
if ((turnos * dias) - turnos_no_laborales) % operarios == 0:
    max_turnos_por_operario = min_turnos_por_operario
else:
    max_turnos_por_operario = min_turnos_por_operario + 1
for o in total_operarios:
    num_turnos_trabajados = []
    for d in total_dias:
        for t in total_turnos:
            num_turnos_trabajados.append(asignacion[(o, d, t)])
    model.Add(min_turnos_por_operario &lt;= sum(num_turnos_trabajados))
    model.Add(sum(num_turnos_trabajados) &lt;= max_turnos_por_operario)</code></pre>
</div>
<p>Lo primero que hicimos fue calcular la parte entera de la fracción entre el <em>número de turnos asignables</em> y los operarios; lo que nos indica la <em>cantidad mínima de turnos por operario</em>. Veamos con un ejemplo:</p>
<p style="text-align: center;">(turnos * días) &#8211; turnos no laborales // operarios</p>
<p style="text-align: center;">(3 turnos por día * 7 días) &#8211; 2 turnos // 4 operarios</p>
<p style="text-align: center;">(3 * 7) &#8211; 2 // 4</p>
<p style="text-align: center;">19 // 4 = 4 turnos por operario</p>
<p>Esto indica que existe la posibilidad de asignar al menos 4 turnos por cada operario. Lo siguiente que se debe considerar es la cantidad máxima de turnos por operario.</p>
<p>En el caso en el cual la cantidad que resulte de dividir el número de turnos asignables entre el número de operarios sea entera sin decimales, esto indicaría que la distribución de los turnos puede realizarse en partes iguales, y por lo tanto <em>la cantidad máxima de turnos por operario </em>será equivalente a <em>la cantidad mínima de turnos por operario</em>.</p>
<p>En los casos en los que esto no ocurra, <em>la cantidad máxima de turnos por operario</em> será equivalente a <em>la cantidad mínima de turnos por operario </em>más 1. Recordemos que la restricción nos indica que la diferencia entre asignaciones de turnos a operarios no puede ser mayor de un turno.</p>
<p>Por todo lo demás, las restricciones de este paso consisten en establecer que la cantidad de turnos asignados por operario deberá ser mayor que <em>la cantidad mínima de turnos por operario </em>y deberá ser menor que <em>a cantidad máxima de turnos por operario</em><em>.</em></p>
<h3>Paso 8: Crear el solucionador y enumerar las soluciones</h3>

		<div id="paso-8-crear-el-solucionador-y-enumerar-las-soluciones" data-title="Paso 8: Crear el solucionador y enumerar las soluciones" class="index-title"></div>
	
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code># Creal (invocar) el solucionador y resolver
solver = cp_model.CpSolver()
solver.parameters.linearization_level = 0
# Enumerar las posibles soluciones
solver.parameters.enumerate_all_solutions = True</code></pre>
</div>
<h3>Paso 9: Configurar las salidas del modelo</h3>

		<div id="paso-9-configurar-las-salidas-del-modelo" data-title="Paso 9: Configurar las salidas del modelo" class="index-title"></div>
	
<p>Este paso consiste en configurar el formato de salida de las soluciones posibles. De forma arbitraria hemos determinado que se impriman las primeras 2 soluciones (<em>solution_limit</em>), de tal manera que el formato de salida tendrá la siguiente estructura:</p>
<ul>
<li>Solución <em>i</em>
<ul>
<li>Día <em>d</em>
<ul>
<li>Operario <em>o, </em>trabaja / no trabaja, en el turno <em>t.</em></li>
</ul>
</li>
</ul>
</li>
</ul>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>class OperariosParcialesSolucion(cp_model.CpSolverSolutionCallback):
    """Print intermediate solutions."""

    def __init__(self, asignacion, operarios, dias, turnos, limit):
        cp_model.CpSolverSolutionCallback.__init__(self)
        self._asignacion = asignacion
        self._operarios = operarios
        self._dias = dias
        self._turnos = turnos
        self._solution_count = 0
        self._solution_limit = limit

    def on_solution_callback(self):
        self._solution_count += 1
        print('Solución %i' % self._solution_count)
        for d in range(self._dias):
            print('Día %i' % d)
            for o in range(self._operarios):
                is_working = False
                for t in range(self._turnos):
                    if self.Value(self._asignacion[(o, d, t)]):
                        is_working = True
                        print('  Operario %i trabaja en el turno %i' % (o, t))
                if not is_working:
                    print('  Operario {} no trabaja'.format(o))
        if self._solution_count &gt;= self._solution_limit:
            print('Detenga la búsqueda después de  %i soluciones' % self._solution_limit)
            self.StopSearch()

    def solution_count(self):
        return self._solution_count

# Muestra las primeras 2 soluciones.
solution_limit = 2
solution_printer = OperariosParcialesSolucion(asignacion, operarios, dias, turnos,
                                                    solution_limit)</code></pre>
</div>
<h3>Paso 10: Invocar al solucionador y configurar algunas estadísticas</h3>

		<div id="paso-10-invocar-al-solucionador-y-configurar-algunas-estadisticas" data-title="Paso 10: Invocar al solucionador y configurar algunas estadísticas" class="index-title"></div>
	
<p>Por último, nos queda invocar al solucionador, y configurar algunos datos estadísticos para enriquecer las salidas del modelo.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>solver.Solve(model, solution_printer)

# Estadísticas.
print('\nEstadísticas')
print('  - conflictos      : %i' % solver.NumConflicts())
print('  - ramas de búsqueda       : %i' % solver.NumBranches())
print('  - tiempo de solución      : %f s' % solver.WallTime())
print('  - soluciones encontradas: %i' % solution_printer.solution_count())</code></pre>
</div>
<hr />
<p>Al ejecutar el programa completo, tendremos la siguiente salida:</p>
<ul>
<li><strong><em>Solución 1</em></strong>
<ul>
<li><em>Día 0</em>
<ul>
<li><em>Operario 0 no trabaja</em></li>
<li><em>Operario 1 trabaja en el turno 1</em></li>
<li><em>Operario 2 trabaja en el turno 2</em></li>
<li><em>Operario 3 trabaja en el turno 0</em></li>
</ul>
</li>
<li><em>Día 1</em>
<ul>
<li><em>Operario 0 no trabaja</em></li>
<li><em>Operario 1 trabaja en el turno 0</em></li>
<li><em>Operario 2 trabaja en el turno 2</em></li>
<li><em>Operario 3 trabaja en el turno 1</em></li>
</ul>
</li>
<li><em>Día 2</em>
<ul>
<li><em>Operario 0 trabaja en el turno 0</em></li>
<li><em>Operario 1 no trabaja</em></li>
<li><em>Operario 2 trabaja en el turno 2</em></li>
<li><em>Operario 3 trabaja en el turno 1</em></li>
</ul>
</li>
<li><em>Día 3</em>
<ul>
<li><em>Operario 0 trabaja en el turno 1</em></li>
<li><em>Operario 1 trabaja en el turno 0</em></li>
<li><em>Operario 2 trabaja en el turno 2</em></li>
<li><em>Operario 3 no trabaja</em></li>
</ul>
</li>
<li><em>Día 4</em>
<ul>
<li><em>Operario 0 trabaja en el turno 1</em></li>
<li><em>Operario 1 trabaja en el turno 0</em></li>
<li><em>Operario 2 no trabaja</em></li>
<li><em>Operario 3 trabaja en el turno 2</em></li>
</ul>
</li>
<li><em>Día 5</em>
<ul>
<li><em>Operario 0 trabaja en el turno 2</em></li>
<li><em>Operario 1 trabaja en el turno 0</em></li>
<li><em>Operario 2 no trabaja</em></li>
<li><em>Operario 3 trabaja en el turno 1</em></li>
</ul>
</li>
<li><em>Día 6</em>
<ul>
<li><em>Operario 0 trabaja en el turno 0</em></li>
<li><em>Operario 1 no trabaja</em></li>
<li><em>Operario 2 no trabaja</em></li>
<li><em>Operario 3 no trabaja</em></li>
</ul>
</li>
</ul>
</li>
<li><strong><em>Solución 2</em></strong>
<ul>
<li><em>Día 0</em>
<ul>
<li><em>Operario 0 no trabaja</em></li>
<li><em>Operario 1 trabaja en el turno 1</em></li>
<li><em>Operario 2 trabaja en el turno 2</em></li>
<li><em>Operario 3 trabaja en el turno 0</em></li>
</ul>
</li>
<li><em>Día 1</em>
<ul>
<li><em>Operario 0 no trabaja</em></li>
<li><em>Operario 1 trabaja en el turno 0</em></li>
<li><em>Operario 2 trabaja en el turno 2</em></li>
<li><em>Operario 3 trabaja en el turno 1</em></li>
</ul>
</li>
<li><em>Día 2</em>
<ul>
<li><em>Operario 0 trabaja en el turno 0</em></li>
<li><em>Operario 1 no trabaja</em></li>
<li><em>Operario 2 trabaja en el turno 2</em></li>
<li><em>Operario 3 trabaja en el turno 1</em></li>
</ul>
</li>
<li><em>Día 3</em>
<ul>
<li><em>Operario 0 trabaja en el turno 1</em></li>
<li><em>Operario 1 trabaja en el turno 0</em></li>
<li><em>Operario 2 trabaja en el turno 2</em></li>
<li><em>Operario 3 no trabaja</em></li>
</ul>
</li>
<li><em>Día 4</em>
<ul>
<li><em>Operario 0 trabaja en el turno 1</em></li>
<li><em>Operario 1 trabaja en el turno 0</em></li>
<li><em>Operario 2 no trabaja</em></li>
<li><em>Operario 3 trabaja en el turno 2</em></li>
</ul>
</li>
<li><em>Día 5</em>
<ul>
<li><em>Operario 0 trabaja en el turno 1</em></li>
<li><em>Operario 1 trabaja en el turno 0</em></li>
<li><em>Operario 2 no trabaja</em></li>
<li><em>Operario 3 trabaja en el turno 2</em></li>
</ul>
</li>
<li><em>Día 6</em>
<ul>
<li><em>Operario 0 trabaja en el turno 0</em></li>
<li><em>Operario 1 no trabaja</em></li>
<li><em>Operario 2 no trabaja</em></li>
<li><em>Operario 3 no trabaja</em></li>
</ul>
</li>
</ul>
</li>
</ul>
<p><em>Detenga la búsqueda después de 2 soluciones</em></p>
<p><em>Estadísticas</em><br />
<em>&#8211; conflictos : 973</em><br />
<em>&#8211; ramas de búsqueda : 1730</em><br />
<em>&#8211; tiempo de búsqueda : 0.044052 s</em><br />
<em>&#8211; soluciones encontradas: 2</em></p>
<hr />
<p>Hemos formulado un modelo con <strong>84 variables de decisión, 55 restricciones y algunos cálculos intermedios</strong>. Podemos observar cómo el modelo ha logrado encontrar soluciones que satisfacen las restricciones planteadas (formuladas). Del mismo modo, podemos observar el tiempo en el cual ha logrado el solucionador hallar la cantidad de soluciones solicitadas (fracciones de segundo).</p>
<p>Es interesante percibir las bondades de este tipo desarrollos, y considerar las posibilidades de aplicación en otros campos diferentes a la programación de empleados; teniendo en cuenta la flexibilidad de la programación basada en restricciones, la potencia de los solucionadores y la capacidad de procesamiento de los equipos en la actualidad.</p>
<p>El código completo de este desarrollo lo puedes encontrar en nuestro cuaderno: <a href="https://colab.research.google.com/drive/18dIH38IZyioGn7eIRaT8bhMatCyEqasJ?usp=sharing" target="_blank" rel="noopener"><em><strong>Programación de empleados</strong></em></a>.</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/programacion-de-empleados-mediante-programacion-entera/">Programación de empleados mediante programación entera</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/programacion-de-empleados-mediante-programacion-entera/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>¿Cómo calcular una matriz de distancias para modelar un VRP?</title>
		<link>https://ingenieriaindustrialonline.com/investigacion-de-operaciones/como-calcular-una-matriz-de-distancias-para-modelar-un-vrp/</link>
					<comments>https://ingenieriaindustrialonline.com/investigacion-de-operaciones/como-calcular-una-matriz-de-distancias-para-modelar-un-vrp/#comments</comments>
		
		<dc:creator><![CDATA[Bryan Salazar López]]></dc:creator>
		<pubDate>Tue, 16 Nov 2021 21:44:14 +0000</pubDate>
				<category><![CDATA[Investigación de operaciones]]></category>
		<category><![CDATA[Logística]]></category>
		<category><![CDATA[Google OR-Tools]]></category>
		<category><![CDATA[Haversine]]></category>
		<category><![CDATA[Matriz de distancias]]></category>
		<category><![CDATA[Optimización]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Routing]]></category>
		<category><![CDATA[Ruteo]]></category>
		<category><![CDATA[VRP]]></category>
		<guid isPermaLink="false">https://ingenieriaindustrialonline.com/?p=28858</guid>

					<description><![CDATA[<p>Tal como lo hemos abordado ampliamente, una de las aplicaciones más importantes del modelamiento de Cadenas de Suministro, es el diseño de red de abastecimiento, y dentro de esta categoría, el diseño de rutas de transporte (enrutamiento de vehículos). Los problemas de enrutamiento de vehículos (routing), se encuentran clasificados como problemas de optimización combinatoria, y &#8230;</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/como-calcular-una-matriz-de-distancias-para-modelar-un-vrp/">¿Cómo calcular una matriz de distancias para modelar un VRP?</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 hemos abordado ampliamente, u<span>na de las aplicaciones más importantes del modelamiento de Cadenas de Suministro, es el diseño de red de abastecimiento, y dentro de esta categoría, el diseño de rutas de transporte (enrutamiento de vehículos).</span></p>
<p>Los problemas de enrutamiento de vehículos (<em>routing</em>), se encuentran clasificados como problemas de optimización combinatoria, y esto producto de que la cantidad de rutas posibles en un modelo básico, se encuentra determinado por la <span>ecuación (</span><em>n</em><span> – 1)!, donde </span><em>n</em><span>, es igual al número de ubicaciones que componen el problema de enrutamiento.</span></p>
<p>Ahora bien, no solo la resolución de los problemas de enrutamiento es considerada como compleja, también lo es la fase preliminar en la que debemos levantar la información de entrada del modelo (<em>inputs</em>), específicamente, la <strong><em>matriz de distancias</em></strong>.</p>
<p>La forma más básica de un modelo <em>VRP</em>, requiere para su resolución la siguiente información mínima de entrada:</p>

		<div class="plus tie-list-shortcode">
<ul>
<li>Número de vehículos</li>
<li>Un depósito</li>
<li>Matriz de distancias</li>
</ul>

		</div>
	
<p>La matriz de distancias es un tabulado que registra la longitud entre cada uno de los nodos del modelo, incluido el nodo depósito. Su tamaño será <em>n x n </em>(siendo <em>n</em> el número de nodos del modelo). Asumiendo, por ejemplo, que tenemos un problema que se compone de 1 depósito y 19 ubicaciones, el modelo requerirá de una <em>matriz de distancias</em> con 400 datos.</p>

		<div class="box note  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>
<p>Recuerdo que cuando abordamos por primera vez este tema en la <em>Universidad</em>, en mi etapa de estudiante, se nos mencionó enfáticamente la complejidad que subyace en este tipo de modelos: El procesamiento, el levantamiento de datos, la consideración de ubicaciones reales, etc.</p>
<p>Pues bien, han pasado algunos años desde entonces, y todo cambió. El modelamiento de este tipo de problemas, la integración con sistemas de información geográfica, la posibilidad de automatizar procesos de captura de información. <em>¡Todo!</em></p>

			</div>
		</div>
	
<p>En artículos anteriores hemos abordado modelos robustos para la <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/problema-de-enrutamiento-de-vehiculos-vrp-con-google-or-tools/"><strong>resolución de problemas VRP</strong></a> y algunas de sus extensiones (<a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/problema-de-enrutamiento-de-vehiculos-capacitados-cvrp-con-google-or-tools/"><strong>CVRP</strong></a>, por ejemplo). El objetivo de este artículo será la de utilizar funciones espaciales de <em>Python</em>, para obtener una matriz de distancias de acuerdo a ubicaciones reales, con el propósito de resolver un modelo VRP básico.</p>
<hr />
<h2>Caso de aplicación</h2>

		<div id="caso-de-aplicacion" data-title="Caso de aplicación" class="index-title"></div>
	
<blockquote class=" quote-simple "><p>La Secretaría de Educación de Santiago de Cali, tiene dentro de sus funciones, distribuir el material pedagógico a las diferentes instituciones de formación de la ciudad. La distribución del material se realiza todos los lunes, y para ello, la Secretaría cuenta con dos vehículos con capacidad suficiente para transportar todo el material. El depósito del material (lugar desde donde salen y deben regresar los vehículos), se encuentra en la Alcaldía de Cali; y las instituciones que deben visitarse son 60. Tal como podemos apreciar en la siguiente tabla:</p></blockquote>
<table width="576">
<tbody>
<tr>
<td width="80" style="text-align: center;"><strong>Nodo</strong></td>
<td width="224" style="text-align: center;"><strong>Lugar</strong></td>
<td width="127" style="text-align: center;"><strong>Latitud</strong></td>
<td width="145" style="text-align: center;"><strong>Longitud</strong></td>
</tr>
<tr>
<td style="text-align: center;">0</td>
<td style="text-align: center;">Secretaría de Educación &#8211; Alcaldía</td>
<td style="text-align: center;">3,454431875</td>
<td style="text-align: center;">-76,53421433</td>
</tr>
<tr>
<td style="text-align: center;">1</td>
<td style="text-align: center;"> Comfandi San Nicolás</td>
<td style="text-align: center;">3,453591118</td>
<td style="text-align: center;">-76,52254886</td>
</tr>
<tr>
<td style="text-align: center;">2</td>
<td style="text-align: center;"> Mayor de Santiago de Cali</td>
<td style="text-align: center;">3,451577758</td>
<td style="text-align: center;">-76,51023216</td>
</tr>
<tr>
<td style="text-align: center;">3</td>
<td style="text-align: center;"> Municipal Comfandi</td>
<td style="text-align: center;">3,448107915</td>
<td style="text-align: center;">-76,51074714</td>
</tr>
<tr>
<td style="text-align: center;">4</td>
<td style="text-align: center;"> Internado San Carlos</td>
<td style="text-align: center;">3,446994135</td>
<td style="text-align: center;">-76,51525325</td>
</tr>
<tr>
<td style="text-align: center;">5</td>
<td style="text-align: center;"> León de Greiff</td>
<td style="text-align: center;">3,447979402</td>
<td style="text-align: center;">-76,49993247</td>
</tr>
<tr>
<td style="text-align: center;">6</td>
<td style="text-align: center;"> Nuestra Señora de la Anunciación</td>
<td style="text-align: center;">3,445152112</td>
<td style="text-align: center;">-76,49641342</td>
</tr>
<tr>
<td style="text-align: center;">7</td>
<td style="text-align: center;"> Fernando de Aragón</td>
<td style="text-align: center;">3,437355603</td>
<td style="text-align: center;">-76,51383704</td>
</tr>
<tr>
<td style="text-align: center;">8</td>
<td style="text-align: center;"> Casa Evangélica</td>
<td style="text-align: center;">3,437955337</td>
<td style="text-align: center;">-76,52299947</td>
</tr>
<tr>
<td style="text-align: center;">9</td>
<td style="text-align: center;"> San Alberto Magno</td>
<td style="text-align: center;">3,433028941</td>
<td style="text-align: center;">-76,52707643</td>
</tr>
<tr>
<td style="text-align: center;">10</td>
<td style="text-align: center;"> Santa María Goretty</td>
<td style="text-align: center;">3,433414486</td>
<td style="text-align: center;">-76,50720662</td>
</tr>
<tr>
<td style="text-align: center;">11</td>
<td style="text-align: center;"> San Alberto Magno</td>
<td style="text-align: center;">3,433157456</td>
<td style="text-align: center;">-76,5267331</td>
</tr>
<tr>
<td style="text-align: center;">12</td>
<td style="text-align: center;"> San Ignacio de Loyola</td>
<td style="text-align: center;">3,431786629</td>
<td style="text-align: center;">-76,51733464</td>
</tr>
<tr>
<td style="text-align: center;">13</td>
<td style="text-align: center;"> Nuestro Futuro</td>
<td style="text-align: center;">3,430629992</td>
<td style="text-align: center;">-76,50360174</td>
</tr>
<tr>
<td style="text-align: center;">14</td>
<td style="text-align: center;"> Sabio Caldas</td>
<td style="text-align: center;">3,429087807</td>
<td style="text-align: center;">-76,51660508</td>
</tr>
<tr>
<td style="text-align: center;">15</td>
<td style="text-align: center;"> CREAD</td>
<td style="text-align: center;">3,425060978</td>
<td style="text-align: center;">-76,51488847</td>
</tr>
<tr>
<td style="text-align: center;">16</td>
<td style="text-align: center;"> Licomtec</td>
<td style="text-align: center;">3,416664559</td>
<td style="text-align: center;">-76,51673383</td>
</tr>
<tr>
<td style="text-align: center;">17</td>
<td style="text-align: center;">  Nuestra Señora De La Providencia</td>
<td style="text-align: center;">3,419534772</td>
<td style="text-align: center;">-76,49591989</td>
</tr>
<tr>
<td style="text-align: center;">18</td>
<td style="text-align: center;"> Real Suizo</td>
<td style="text-align: center;">3,415208029</td>
<td style="text-align: center;">-76,49323768</td>
</tr>
<tr>
<td style="text-align: center;">19</td>
<td style="text-align: center;"> Nuevo Edén</td>
<td style="text-align: center;">3,415722099</td>
<td style="text-align: center;">-76,53383559</td>
</tr>
<tr>
<td style="text-align: center;">20</td>
<td style="text-align: center;"> Católico</td>
<td style="text-align: center;">3,413066071</td>
<td style="text-align: center;">-76,53984374</td>
</tr>
<tr>
<td style="text-align: center;">21</td>
<td style="text-align: center;"> Santa María Stella</td>
<td style="text-align: center;">3,427031556</td>
<td style="text-align: center;">-76,55134505</td>
</tr>
<tr>
<td style="text-align: center;">22</td>
<td style="text-align: center;"> Santa Isabel</td>
<td style="text-align: center;">3,40805355</td>
<td style="text-align: center;">-76,50817223</td>
</tr>
<tr>
<td style="text-align: center;">23</td>
<td style="text-align: center;"> Compartir</td>
<td style="text-align: center;">3,431957663</td>
<td style="text-align: center;">-76,47495575</td>
</tr>
<tr>
<td style="text-align: center;">24</td>
<td style="text-align: center;"> Lancaster</td>
<td style="text-align: center;">3,400770816</td>
<td style="text-align: center;">-76,55177421</td>
</tr>
<tr>
<td style="text-align: center;">25</td>
<td style="text-align: center;"> Parroquial Divino Salvador</td>
<td style="text-align: center;">3,397086588</td>
<td style="text-align: center;">-76,54259033</td>
</tr>
<tr>
<td style="text-align: center;">26</td>
<td style="text-align: center;"> Reyes Católicos</td>
<td style="text-align: center;">3,393316667</td>
<td style="text-align: center;">-76,53735466</td>
</tr>
<tr>
<td style="text-align: center;">27</td>
<td style="text-align: center;"> Liceo Anglo del Valle</td>
<td style="text-align: center;">3,387318719</td>
<td style="text-align: center;">-76,51975937</td>
</tr>
<tr>
<td style="text-align: center;">28</td>
<td style="text-align: center;"> Laurence</td>
<td style="text-align: center;">3,383420238</td>
<td style="text-align: center;">-76,52078934</td>
</tr>
<tr>
<td style="text-align: center;">29</td>
<td style="text-align: center;"> Los Almendros</td>
<td style="text-align: center;">3,381278208</td>
<td style="text-align: center;">-76,52023144</td>
</tr>
<tr>
<td style="text-align: center;">30</td>
<td style="text-align: center;"> Bautista</td>
<td style="text-align: center;">3,37720834</td>
<td style="text-align: center;">-76,52327843</td>
</tr>
<tr>
<td style="text-align: center;">31</td>
<td style="text-align: center;"> Lacordaire</td>
<td style="text-align: center;">3,378150837</td>
<td style="text-align: center;">-76,54460736</td>
</tr>
<tr>
<td style="text-align: center;">32</td>
<td style="text-align: center;"> General José María Córdoba</td>
<td style="text-align: center;">3,393573314</td>
<td style="text-align: center;">-76,54932805</td>
</tr>
<tr>
<td style="text-align: center;">33</td>
<td style="text-align: center;"> El Hogar</td>
<td style="text-align: center;">3,390745864</td>
<td style="text-align: center;">-76,5503151</td>
</tr>
<tr>
<td style="text-align: center;">34</td>
<td style="text-align: center;"> Americano</td>
<td style="text-align: center;">3,379093255</td>
<td style="text-align: center;">-76,54688187</td>
</tr>
<tr>
<td style="text-align: center;">35</td>
<td style="text-align: center;"> Santa Filomena</td>
<td style="text-align: center;">3,401969935</td>
<td style="text-align: center;">-76,51345082</td>
</tr>
<tr>
<td style="text-align: center;">36</td>
<td style="text-align: center;"> Tomás Vasconi</td>
<td style="text-align: center;">3,403040928</td>
<td style="text-align: center;">-76,5173132</td>
</tr>
<tr>
<td style="text-align: center;">37</td>
<td style="text-align: center;"> República del Salvador</td>
<td style="text-align: center;">3,404454636</td>
<td style="text-align: center;">-76,52143308</td>
</tr>
<tr>
<td style="text-align: center;">38</td>
<td style="text-align: center;"> Los Andes</td>
<td style="text-align: center;">3,429601077</td>
<td style="text-align: center;">-76,53761216</td>
</tr>
<tr>
<td style="text-align: center;">39</td>
<td style="text-align: center;">Villacolombia</td>
<td style="text-align: center;">3,445493943</td>
<td style="text-align: center;">-76,50169202</td>
</tr>
<tr>
<td style="text-align: center;">40</td>
<td style="text-align: center;">Las Américas</td>
<td style="text-align: center;">3,449220822</td>
<td style="text-align: center;">-76,50594064</td>
</tr>
<tr>
<td style="text-align: center;">41</td>
<td style="text-align: center;">Santa Fe</td>
<td style="text-align: center;">3,442238267</td>
<td style="text-align: center;">-76,50988885</td>
</tr>
<tr>
<td style="text-align: center;">42</td>
<td style="text-align: center;">Evaristo García</td>
<td style="text-align: center;">3,440781776</td>
<td style="text-align: center;">-76,51752778</td>
</tr>
<tr>
<td style="text-align: center;">43</td>
<td style="text-align: center;">Alfredo Vásquez Cobo</td>
<td style="text-align: center;">3,435598366</td>
<td style="text-align: center;">-76,5164549</td>
</tr>
<tr>
<td style="text-align: center;">44</td>
<td style="text-align: center;">Ciudad de Cali</td>
<td style="text-align: center;">3,431143181</td>
<td style="text-align: center;">-76,51272126</td>
</tr>
<tr>
<td style="text-align: center;">45</td>
<td style="text-align: center;">INEM</td>
<td style="text-align: center;">3,482761991</td>
<td style="text-align: center;">-76,49976083</td>
</tr>
<tr>
<td style="text-align: center;">46</td>
<td style="text-align: center;">Olaya Herrera</td>
<td style="text-align: center;">3,478178519</td>
<td style="text-align: center;">-76,51280709</td>
</tr>
<tr>
<td style="text-align: center;">47</td>
<td style="text-align: center;">Guillermo Valencia</td>
<td style="text-align: center;">3,47449459</td>
<td style="text-align: center;">-76,5136654</td>
</tr>
<tr>
<td style="text-align: center;">48</td>
<td style="text-align: center;">José Ignacio Rengifo</td>
<td style="text-align: center;">3,471624543</td>
<td style="text-align: center;">-76,5136654</td>
</tr>
<tr>
<td style="text-align: center;">49</td>
<td style="text-align: center;">Santo Tomás</td>
<td style="text-align: center;">3,45830227</td>
<td style="text-align: center;">-76,5164549</td>
</tr>
<tr>
<td style="text-align: center;">50</td>
<td style="text-align: center;">La Merced</td>
<td style="text-align: center;">3,46271449</td>
<td style="text-align: center;">-76,5024645</td>
</tr>
<tr>
<td style="text-align: center;">51</td>
<td style="text-align: center;">Pedro Antonio Molina</td>
<td style="text-align: center;">3,482804827</td>
<td style="text-align: center;">-76,48761579</td>
</tr>
<tr>
<td style="text-align: center;">52</td>
<td style="text-align: center;">Santa Librada</td>
<td style="text-align: center;">3,46228612</td>
<td style="text-align: center;">-76,52302095</td>
</tr>
<tr>
<td style="text-align: center;">53</td>
<td style="text-align: center;">República de Israel</td>
<td style="text-align: center;">3,463656904</td>
<td style="text-align: center;">-76,51053258</td>
</tr>
<tr>
<td style="text-align: center;">54</td>
<td style="text-align: center;">San Vicente Paul</td>
<td style="text-align: center;">3,466227117</td>
<td style="text-align: center;">-76,50950261</td>
</tr>
<tr>
<td style="text-align: center;">55</td>
<td style="text-align: center;">Manuel María Mallarino</td>
<td style="text-align: center;">3,456760129</td>
<td style="text-align: center;">-76,48851701</td>
</tr>
<tr>
<td style="text-align: center;">56</td>
<td style="text-align: center;">Sebastián de Belalcazar</td>
<td style="text-align: center;">3,460229941</td>
<td style="text-align: center;">-76,48521253</td>
</tr>
<tr>
<td style="text-align: center;">57</td>
<td style="text-align: center;">Liceo Departamental</td>
<td style="text-align: center;">3,423860462</td>
<td style="text-align: center;">-76,5385563</td>
</tr>
<tr>
<td style="text-align: center;">58</td>
<td style="text-align: center;">Libardo Madrid</td>
<td style="text-align: center;">3,422061154</td>
<td style="text-align: center;">-76,54383489</td>
</tr>
<tr>
<td style="text-align: center;">59</td>
<td style="text-align: center;">Metropolitano Santa Anita</td>
<td style="text-align: center;">3,401691038</td>
<td style="text-align: center;">-76,54218265</td>
</tr>
<tr>
<td style="text-align: center;">60</td>
<td style="text-align: center;">San José</td>
<td style="text-align: center;">3,396935816</td>
<td style="text-align: center;">-76,55031511</td>
</tr>
</tbody>
</table>
<p>Se desea desarrollar un plan de rutas para cada uno de los vehículos que logre minimizar la distancia total recorrida, al tiempo que asegure la visita de todos los colegios.</p>
<h3>¿Qué necesitaremos?</h3>

		<div id="que-necesitaremos" data-title="¿Qué necesitaremos?" class="index-title"></div>
	
<p>En el desarrollo de este ejercicio emplearemos:</p>

		<div class="plus tie-list-shortcode">
<div class="plus tie-list-shortcode">
<ul>
<li><em><strong>Colaboratory</strong>:<span> </span></em>Este es un entorno de programación y ejecución virtual de Python desarrollado por Google. Nos permitirá no tener la necesidad de realizar ninguna instalación en nuestros equipos. Todo lo que desarrollemos lo ejecutaremos en un cuaderno virtual.</li>
<li><strong><em>Python</em></strong>: Este será el lenguaje de programación que vamos a utilizar, y advertimos: No es necesario tener conocimientos previos, y el objetivo del artículo no es convertirnos en programadores expertos. Utilizaremos fragmentos de códigos, librerías disponibles, y explicaremos lo necesario para configurar nuestro desarrollo de acuerdo a los objetivos específicos de nuestros modelos.</li>
<li><strong><em>SkLearn</em></strong>: Las librerías son a <em>Python</em>, lo que las <em>apps<span> </span></em>son a un teléfono celular. Esta es quizá una de las características más a tractivas de este lenguaje: Casi que existe una librería para cada necesidad. En este caso, <em>SKLearn</em>, es una librería que integra un conjunto de métodos de aprendizaje automático y minería de datos. En este caso utilizaremos sus funciones para cálculo de distancias entre pares.</li>
<li><strong><em>Pandas</em></strong>:<span> </span><span>Es un paquete de Python que proporciona estructuras de datos rápidas, y flexibles, diseñadas para que el trabajo con datos estructurados (tabulares, multidimensionales, potencialmente heterogéneos) y de series de tiempo sea fácil e intuitivo.</span></li>
<li><em><strong>Numpy</strong>: </em>Es una librería que nos permitirá efectuar operaciones matriciales en Python.</li>
<li><strong><em>Math: </em></strong>Es una librería que contiene un conjunto de funciones matemáticas básicas.</li>
</ul>

		</div>
	
</div>
<h3>Paso 1: Crear el entorno de trabajo en Colaboratory</h3>

		<div id="paso-1-crear-el-entorno-de-trabajo-en-colaboratory" data-title="Paso 1: Crear el entorno de trabajo en Colaboratory" class="index-title"></div>
	
<div id="paso-1-crear-el-entorno-de-trabajo-en-colaboratory" data-title="Paso 1: Crear el entorno de trabajo en Colaboratory" class="index-title visible full-visible"></div>
<p><span>Lo primero que vamos a hacer consiste en crear un entorno de trabajo en <em>Google</em> </span><em>Colaboratory</em><span>, así que vayamos allá: </span><a href="https://colab.research.google.com/#create=true" target="_blank" rel="noopener"><em><strong>Abrir cuaderno nuevo</strong></em></a><span>.</span></p>
<p>Verán que tienen un lienzo para programar el modelo, así que en este cuaderno podemos ir generando las líneas de código que explicaremos en los pasos siguientes.</p>
<h3>Paso 2: Importar las librerías necesarias</h3>

		<div id="paso-2-importar-las-librerias-necesarias" data-title="Paso 2: Importar las librerías necesarias" class="index-title"></div>
	
<div id="paso-2-importar-las-librerias-necesarias" data-title="Paso 2: Importar las librerías necesarias" class="index-title visible full-visible"></div>
<p>Respecto a las librerías, en la introducción del artículo hicimos una descripción de la funcionalidad de cada una, veamos como importarlas en nuestro entorno:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>from sklearn.neighbors import DistanceMetric
from math import radians
import pandas as pd
import numpy as np</code></pre>
</div>
<p><span>De esta manera, tenemos todo lo necesario para empezar a desarrollar nuestro código.</span></p>
<h3>Paso 3: Importar los datos desde Excel</h3>

		<div id="paso-3-importar-los-datos-desde-excel" data-title="Paso 3: Importar los datos desde Excel" class="index-title"></div>
	
<div id="paso-3-importar-los-datos-desde-excel" data-title="Paso 3: Importar los datos desde Excel" class="index-title visible full-visible"></div>
<p>De acuerdo a las necesidades del modelo, podemos desarrollar un código que permita la entrada manual de la información, la captura de los datos desde entornos digitales (Internet, por ejemplo), o podemos, desde luego, alimentar nuestro modelo con información contenida en documentos externos, como es el caso de un archivo de Microsoft Excel.</p>
<p>Esta puede considerarse como una de las ventajas de utilizar <em>Python, </em>su capacidad de integrarse con cualquier fuente de datos. En nuestro caso, toda la información se encuentra contenida en un documento de Excel, el cual presenta el siguiente formato:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/datos_colegio.png" alt="datos_colegio" width="577" height="241" class="size-full wp-image-28867 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/datos_colegio.png 577w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/datos_colegio-300x125.png 300w" sizes="(max-width: 577px) 100vw, 577px" /></p>
<p>Utilizaremos ubicaciones reales, y para eso emplearemos las coordenadas de <em>latitud </em>y <em>longitud</em>.</p>

		<div class="box download  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span><span>Puedes descargar el documento de Excel que utilizamos en este ejemplo: </span><a href="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/colegios.xlsx" target="_blank" rel="noopener"><strong>Base de datos</strong></a>
			</div>
		</div>
	
<p><span>En </span><em>Colaboratory</em><span>, el siguiente fragmento permitirá cargar un archivo al entorno de ejecución:</span></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>from google.colab import files

uploaded = files.upload()

for fn in uploaded.keys():
  print('User uploaded file "{name}" with length {length} bytes'.format(
      name=fn, length=len(uploaded[fn])))</code></pre>
</div>
<p>Al ejecutar este fragmento de código, se abrirá una ventana emergente del explorador que permitirá cargar nuestra base de datos, en nuestro caso el archivo tienen el nombre de <em>colegios.xlsx.</em></p>
<p>La siguiente línea de código permitirá almacenar los datos contenidos en el documento en un <em>Dataframe</em><span> </span>de nuestro entorno, dentro de la variable <em>data</em>.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Leer el documento de Excel y almacenar los datos en la variable data
data = pd.read_excel('colegios.xlsx')</code></pre>
</div>
<p><span>Podemos en cualquier momento confirmar si la carga de los datos se ha realizado correctamente, para eso imprimiremos las primeras cinco filas del  </span><em>DataFrame:</em></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>data.head()</code></pre>
</div>
<p><span>Al ejecutar esta instrucción tenemos la siguiente salida (Una vista de las 5 primeras filas del marco de datos):</span></p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/data_head.png" alt="data_head" width="534" height="257" class="size-full wp-image-28869 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/data_head.png 534w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/data_head-300x144.png 300w" sizes="(max-width: 534px) 100vw, 534px" /></p>
<p>Podemos observar que los datos han sido perfectamente cargados, y que ahora se encuentran almacenados en la variable (<em>DataFrame</em>): <em><strong>data</strong></em>.</p>
<h3>Paso 4: Convertir las coordenadas de latitud y longitud en radianes</h3>

		<div id="paso-4-convertir-las-coordenadas-de-latitud-y-longitud-en-radianes" data-title="Paso 4: Convertir las coordenadas de latitud y longitud en radianes" class="index-title"></div>
	
<p>La mayor parte de las funciones de cálculo de distancias de <em>Sklearn</em> (<em>Scipy</em>) toman las entradas como radianes. Por esta razón, debemos convertir las coordenadas en radianes.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>data['Latitud'] = np.radians(data['Latitud'])
data['Longitud'] = np.radians(data['Longitud'])

#Creamos una matriz bidimensional con la latitud y la longitud en radianes
data[['Latitud','Longitud']].to_numpy()</code></pre>
</div>
<p>Al ejecutar estas líneas, las coordenadas quedarán convertidas en radianes.</p>
<h3>Paso 5: Declarar el tipo de métrica de distancias que se utilizará</h3>

		<div id="paso-5-declarar-el-tipo-de-metrica-de-distancias-que-se-utilizara" data-title="Paso 5: Declarar el tipo de métrica de distancias que se utilizará" class="index-title"></div>
	
<p>En este punto quiero detenerme para mencionar que existen decenas de funciones métricas de distancia rápida. Algunas de las más utilizadas son destinadas a espacios vectoriales de valor real, como: <em>distancias euclidianas, distancias de Manhattan, </em>etc. Prácticas cuando se emplean con coordenadas cartesianas.</p>
<p>En nuestro caso, ya que utilizamos ubicaciones reales y contamos con coordenadas de latitud y de longitud, podemos emplear una función de distancia de vectores bidimensionales que considere la curvatura de la tierra; tal es el caso de las <em>Distancias Haversine (Semiverseno)</em>.</p>

		<div class="box note  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>La distancia de Haversine (o gran círculo) es la distancia angular entre dos puntos en la superficie de una esfera. Se supone que la primera coordenada de cada punto es la latitud, la segunda es la longitud, expresada en radianes.</p>
<p>Como la Tierra es casi esférica, la fórmula Haversine proporciona una buena aproximación de la distancia entre dos puntos de la superficie terrestre, con un error de menos del 1% en promedio.
			</div>
		</div>
	
<p>Si quieren conocer la fórmula empleada para el cálculo de cada distancia <em>haversine</em>:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/haversine.png" alt="haversine" width="596" height="54" class="size-full wp-image-28870 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/haversine.png 596w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/haversine-300x27.png 300w" sizes="(max-width: 596px) 100vw, 596px" /></p>
<p>Para efectos de nuestro desarrollo, utilizaremos la librería <em>SKLearn</em> para calcular nuestras distancias. Veamos:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>dist = DistanceMetric.get_metric('haversine')

dist.pairwise(data[['Latitud','Longitud']].to_numpy())*6373</code></pre>
</div>
<p>El fragmento anterior crea un objeto con métricas <em>haversine</em>, y luego utiliza la función <em>pairwise()</em>, para calcular la distancia entre cada uno de los elementos de la matriz (nodos). Cada distancia calculada multiplica el escalar 6373 (radio esférico de la tierra), para calcular las distancias en kilómetros (Para millas multiplicar por 3798).</p>
<h3>Paso 6: Crear un marco de datos (tabulado) de matriz de distancias</h3>

		<div id="paso-6-crear-un-marco-de-datos-tabulado-de-matriz-de-distancias" data-title="Paso 6: Crear un marco de datos (tabulado) de matriz de distancias" class="index-title"></div>
	
<p>Una vez que ejecutemos el paso anterior, tendremos nuestras distancias entre nodos calculadas; lo que haremos en este paso será organizar dichos valores en forma de marco de datos o tabulado, obteniendo nuestra matriz de distancias.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>distance_matrix = pd.DataFrame(dist.pairwise(data[['Latitud','Longitud']].to_numpy())*6373)

distance_matrix.head()</code></pre>
</div>
<p><span>Al ejecutar esta instrucción tenemos la siguiente salida (Una vista de las 5 primeras filas del marco de datos):</span></p>
<figure id="attachment_28871" aria-describedby="caption-attachment-28871" style="width: 601px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/matriz_distancias.png" alt="matriz_distancias" width="601" height="274" class="size-full wp-image-28871" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/matriz_distancias.png 601w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/matriz_distancias-300x137.png 300w" sizes="(max-width: 601px) 100vw, 601px" /><figcaption id="caption-attachment-28871" class="wp-caption-text">Vista recortada</figcaption></figure>
<p>&nbsp;</p>
<p>Podemos imprimir la matriz completa:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>print(distance_matrix)</code></pre>
</div>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/matriz_distancias_2.png" alt="matriz_distancias_2" width="624" height="304" class="size-full wp-image-28872 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/matriz_distancias_2.png 624w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/matriz_distancias_2-300x146.png 300w" sizes="(max-width: 624px) 100vw, 624px" /></p>

		<div class="box note  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>Puedes utilizar Google Maps para validar la diferencia entre las distancias obtenidas mediante Haversine y las obtenidas mediante Google.
			</div>
		</div>
	
<hr />
<p>Hasta este punto hemos logrado nuestro objetivo principal, que era <strong>obtener una matriz de distancias</strong> de forma automática tomando como base las coordenadas de longitud y latitud de un conjunto de nodos. Específicamente hemos obtenido 3721 valores de distancia en cuestión de segundos (empleando la métrica <em>haversine</em>).</p>
<p>Lógicamente, estos valores de referencia en la práctica presentan algunas desventajas, como, por ejemplo, la dificultad subyacente de atravesar las ciudades por lugares diferentes que las vías dispuestas para ello. Sin embargo, estos valores pueden ser muy útiles como datos de entrada de un modelo VRP para obtener la secuencia del plan de rutas.</p>

		<div class="box info  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>Un método más preciso para obtener una matriz de distancias y tiempos consiste en utilizar la API Distance Matrix de Google Maps. Sin embargo, este es un servicio de pago que abordaremos en artículos posteriores
			</div>
		</div>
	
<hr />
<p>Lo siguiente que haremos, para finalizar nuestro caso de aplicación, será utilizar la matriz de distancias obtenida, en un <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/problema-de-enrutamiento-de-vehiculos-vrp-con-google-or-tools/"><strong>modelo VRP básico</strong></a> (Si desea profundizar en el modelo, visite el artículo).</p>
<h3>Paso 7: Instalar Google Or Tools</h3>

		<div id="paso-7-instalar-google-or-tools" data-title="Paso 7: Instalar Google Or Tools" class="index-title"></div>
	
<p>Es necesario instalar la librería de Google Or Tools en nuestro entorno de <em>Colaboratory</em> para poder utilizar nuestro modelo VRP.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>!pip install ortools</code></pre>
</div>
<p>Al ejecutar esta instrucción instalaremos nuestro solucionador del modelo de enrutamiento.</p>
<h3>Paso 8: Incorporar el modelo VRP (Previamente formulado)</h3>

		<div id="paso-8-incorporar-el-modelo-vrp-previamente-formulado" data-title="Paso 8: Incorporar el modelo VRP (Previamente formulado)" class="index-title"></div>
	
<p>Como ya lo mencionamos, contamos con un modelo debidamente formulado para resolver problemas VRP básicos. Lo único que modificaremos serán los datos de entrada: <em>Matriz de distancias (distance_matrix), Número de vehículos (2), Depósito (Nodo 0).</em></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>"""Problema de enrutamiento de vehículos simple (VRP)

Autor: MSc. Ing. Bryan Salazar López 2021

"""

from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp


def create_data_model():
    """Datos de entrada del modelo"""
    #Llamaremos la matriz de distancia previamente obtenida
    #Emplearemos dos vehículos como lo indica el problema
    #Definiremos el nodo 0 como el depósito (Secretaría)
    data = {}
    data['matriz_distancias'] = distance_matrix
    data['num_vehiculos'] = 2
    data['deposito'] = 0
    return data


def print_solution(data, manager, routing, solution):
    """Imprime la solución sobre la consola"""
    max_route_distance = 0
    for vehicle_id in range(data['num_vehiculos']):
        index = routing.Start(vehicle_id)
        plan_output = 'Ruta para el vehículo {}:\n'.format(vehicle_id)
        route_distance = 0
        while not routing.IsEnd(index):
            plan_output += ' {} -&gt; '.format(manager.IndexToNode(index))
            previous_index = index
            index = solution.Value(routing.NextVar(index))
            route_distance += routing.GetArcCostForVehicle(
                previous_index, index, vehicle_id)
        plan_output += '{}\n'.format(manager.IndexToNode(index))
        plan_output += 'Distancia de la ruta: {}km\n'.format(route_distance)
        print(plan_output)
        max_route_distance += route_distance
        max_route_distance = max(route_distance, max_route_distance)
    print('Distancia total de todas las rutas: {}km'.format(max_route_distance))



def main():
    """Punto de entrada del programa"""
    # Invocar la data de entrada.
    data = create_data_model()

    # Crea el administrador del índice de rutas.
    manager = pywrapcp.RoutingIndexManager(len(data['matriz_distancias']),
                                           data['num_vehiculos'], data['deposito'])

    # Crea el modelo de enrutamiento.
    routing = pywrapcp.RoutingModel(manager)


    # Crea y registra una devolución de llamada de distancia.
    def distance_callback(from_index, to_index):
        """Retorna la distancia entre dos nodos."""
        # Convierte desde la variable de ruta Index hasta la matriz de distancia NodeIndex.
        from_node = manager.IndexToNode(from_index)
        to_node = manager.IndexToNode(to_index)
        return data['matriz_distancias'][from_node][to_node]

    transit_callback_index = routing.RegisterTransitCallback(distance_callback)

    # Define el costo de cada arco.
    routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)

    # Adhiere la dimensión de distancia.
    dimension_name = 'Distancia'
    routing.AddDimension(
        transit_callback_index,
        0,  # Sin holgura
        3000,  # Distancia máxima de viaje del vehículo
        True,  # Iniciar el acumulador en cero
        dimension_name)
    distance_dimension = routing.GetDimensionOrDie(dimension_name)
    distance_dimension.SetGlobalSpanCostCoefficient(100)

    # Configurar los parámetros de búsqueda.
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)

    # Solucionador del problema.
    solution = routing.SolveWithParameters(search_parameters)

    # Imprimir la solución en la consola.
    if solution:
        print_solution(data, manager, routing, solution)
    else:
        print('No se encuentra solución !')


if __name__ == '__main__':
    main()</code></pre>
</div>
<p>Al ejecutar el modelo tendremos:</p>
<figure id="attachment_28873" aria-describedby="caption-attachment-28873" style="width: 1736px" class="wp-caption aligncenter"><a href="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/vrp_rutas.png" target="_blank" rel="noopener"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/vrp_rutas.png" alt="vrp_rutas" width="1736" height="176" class="wp-image-28873 size-full" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/vrp_rutas.png 1736w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/vrp_rutas-300x30.png 300w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/vrp_rutas-1024x104.png 1024w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/vrp_rutas-768x78.png 768w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/11/vrp_rutas-1536x156.png 1536w" sizes="(max-width: 1736px) 100vw, 1736px" /></a><figcaption id="caption-attachment-28873" class="wp-caption-text">Clic para ver en una pestaña nueva</figcaption></figure>
<p>&nbsp;</p>
<p>Un plan de rutas para los dos vehículos que parten desde los depósitos (ahí mismo finalizan sus recorridos), y visitan la totalidad de los nodos. La distancia total optimizada es equivalente a 33 km.</p>
<p>Por último, también es posible exportar la <strong>matriz de distancias</strong> que hemos obtenido, para eso utilizaremos el siguiente fragmento:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>distance_matrix.to_csv('distance_matrix.csv')
files.download('distance_matrix.csv')</code></pre>
</div>

		<div class="box info  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>
<p><span>Los contribuciones de la comunidad han revelado que el modelo VRP de Or Tools maneja valores enteros para las distancias en la matriz. Esto significa que, por ejemplo, una distancia de 0.58 km se trataría como un entero, lo que puede causar pérdida de precisión en los resultados. Por esta razón, recomendamos trabajar con la unidad más pequeña de longitud posible, como metros, y convertir las distancias antes de ejecutar el modelo de ruteo. Por ejemplo, 0.58 km se convertiría en 580 metros, evitando pérdida de precisión. Además, es importante tener en cuenta que esto afectaría la distancia máxima del viaje del vehículo, la cual debemos modificar, en consecuencia.</span></p>

			</div>
		</div>
	
<hr />
<p>El código completo de este desarrollo lo puedes encontrar en nuestro cuaderno: <a href="https://colab.research.google.com/drive/1YZIpYWOrTGBeGwRl9iOhWAwNH5WAVpWw?usp=sharing" target="_blank" rel="noopener"><em><strong>Matriz de distancias para modelar un VRP</strong></em></a>.</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/como-calcular-una-matriz-de-distancias-para-modelar-un-vrp/">¿Cómo calcular una matriz de distancias para modelar un VRP?</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/como-calcular-una-matriz-de-distancias-para-modelar-un-vrp/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>¿Inteligencia Artificial para mejorar pronósticos de la demanda?</title>
		<link>https://ingenieriaindustrialonline.com/pronostico-de-la-demanda/inteligencia-artificial-para-mejorar-pronosticos-de-la-demanda/</link>
					<comments>https://ingenieriaindustrialonline.com/pronostico-de-la-demanda/inteligencia-artificial-para-mejorar-pronosticos-de-la-demanda/#comments</comments>
		
		<dc:creator><![CDATA[Matías Birrell Rodríguez]]></dc:creator>
		<pubDate>Fri, 15 Oct 2021 15:56:31 +0000</pubDate>
				<category><![CDATA[Columnas]]></category>
		<category><![CDATA[Consultoría]]></category>
		<category><![CDATA[Gestión de inventarios]]></category>
		<category><![CDATA[Inteligencia artificial]]></category>
		<category><![CDATA[Logística]]></category>
		<category><![CDATA[Pronóstico de la demanda]]></category>
		<category><![CDATA[Teoría de restricciones (TOC)]]></category>
		<category><![CDATA[Agotados]]></category>
		<category><![CDATA[Agregación estadística]]></category>
		<category><![CDATA[Inventarios]]></category>
		<category><![CDATA[Pronósticos]]></category>
		<category><![CDATA[Stock Out]]></category>
		<category><![CDATA[Teoría de Restricciones]]></category>
		<category><![CDATA[Tiempo de reposición]]></category>
		<category><![CDATA[TOC]]></category>
		<guid isPermaLink="false">https://ingenieriaindustrialonline.com/?p=28478</guid>

					<description><![CDATA[<p>“¿Quiere mejorar su capacidad de previsión de la demanda? He desarrollado una nueva forma de utilizar el aprendizaje automático para apoyar las cadenas de suministro. Así es como funciona: He desarrollado un metamodelo capaz de tratar prácticamente cualquier conjunto de datos de demanda de la cadena de suministro. El metamodelo trabajará con sus datos para &#8230;</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/pronostico-de-la-demanda/inteligencia-artificial-para-mejorar-pronosticos-de-la-demanda/">¿Inteligencia Artificial para mejorar pronósticos de la demanda?</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><span>“<em>¿Quiere mejorar su capacidad de previsión de la demanda?</em></span></p>
<p><em>He desarrollado una nueva forma de utilizar el aprendizaje automático para apoyar las cadenas de suministro. Así es como funciona:</em></p>
<p><em>He desarrollado un metamodelo capaz de tratar prácticamente cualquier conjunto de datos de demanda de la cadena de suministro. El metamodelo trabajará con sus datos para crear el mejor modelo <a data-toggle="tooltip" data-placement="top" class="post-tooltip tooltip-top" title="Machine Learning">ML</a> posible.”</em></p>
<p><span>Este es el inicio de un post en Linkedin publicado el 12 de octubre de 2021. La promesa es básicamente <em>“mejoraré tu pronóstico con inteligencia artificial (AI)”</em>.</span></p>
<p><span>Y yo pregunto, <strong>¿qué ganamos realmente si esto fuera posible?</strong> No estoy ni siquiera cuestionando que un algoritmo de “aprendizaje automatizado” sea capaz de mejorar la precisión del pronóstico. Mi pregunta es más fundamental todavía. Supongamos que, si mejora el pronóstico, <strong>¿qué hemos ganado?</strong></span></p>
<h2><span>Determinantes del tamaño del inventario</span></h2>

		<div id="determinantes-del-tamano-del-inventario" data-title="Determinantes del tamaño del inventario" class="index-title"></div>
	
<p><span>El inventario es necesario solo si los clientes no tienen paciencia para esperar el producto desde que expresan su necesidad, por lo que el objetivo de tener inventario es satisfacer ventas inmediatas. Y sabemos también que la demanda por un producto particular en un punto de venta tiene una alta variabilidad.</span></p>
<p><span>Si el objetivo es satisfacer ventas y la demanda tiene amplias fluctuaciones, entonces el inventario que requerimos debe ser suficiente para satisfacer la máxima demanda antes de la próxima reposición, lo que significa que la mayor parte del tiempo debemos mantener inventarios en exceso respecto de la demanda real del momento.</span></p>
<p><span>La próxima reposición va a depender del tiempo que nosotros decidamos dejar pasar entre una y otra reposición, y también de cuánto demore en llegar el producto desde que lo pedimos. Ambos tiempos juntos componen el tiempo de reposición.</span></p>
<p><span>Mientras mayor el tiempo de reposición, mayor el inventario necesario.</span></p>
<h2><span>Consecuencias de un inventario grande</span></h2>

		<div id="consecuencias-de-un-inventario-grande" data-title="Consecuencias de un inventario grande" class="index-title"></div>
	
<p><span>Mientras mayor el inventario, más espacio se requiere para almacenarlo, y más capital inmovilizado tendremos. Como espacio y capital son ambos recursos limitados, mientras mayor el inventario, menos variedad podremos ofrecer a los clientes, lo que reduce las ventas.</span></p>
<p><span>Y, además, si el tiempo de reposición es largo, entonces tendremos también mayores riesgos asociados al inventario: riesgo de merma y riesgo de obsolescencia. Además, un menor ROI general de la operación.</span></p>
<h2><span>Incidencia del pronóstico en las consecuencias del inventario</span></h2>

		<div id="incidencia-del-pronostico-en-las-consecuencias-del-inventario" data-title="Incidencia del pronóstico en las consecuencias del inventario" class="index-title"></div>
	
<p><span>Si nuestro <a href="https://ingenieriaindustrialonline.com/pronostico-de-la-demanda/que-es-el-pronostico-de-la-demanda/"><strong>pronóstico</strong></a> está muy equivocado, tendremos ventas perdidas por <a data-toggle="tooltip" data-placement="top" class="post-tooltip tooltip-top" title="Agotados"><em>stock out</em></a>, y tendremos acumulación de exceso de inventario.</span></p>
<p><span>Si mejoramos el pronóstico, vamos a reducir el <em>stock out</em>, y también la acumulación de exceso. Sin embargo, el principal factor que determina el tamaño del inventario es el tiempo de reposición, y un menor error en el pronóstico no reduce en absoluto este factor, por lo que el inventario necesario sigue siendo alto.</span></p>
<p><span>Me detengo aquí un minuto, porque ya puedo escuchar el contra argumento <em>“si el pronóstico es exacto, necesito lo justo y necesario”</em>. Estoy de acuerdo. Pero recuerde que la demanda es muy variable: algunos SKUs tendrán una alta venta en el periodo y otros menos, y se alternan. Para un periodo particular, el inventario requerido es la combinación de alta y baja demanda multiplicada por un tiempo largo.</span></p>
<p><span><em>¿Por qué he deducido que el tiempo es largo?</em> Muy fácil, <em>¿cuántos días de venta necesita uno para pronosticar y cada cuánto tiempo se hace el pronóstico de una línea de productos?</em> <em>¿Una vez a la semana, al mes, cada dos meses?</em> No es todos los días para todos los SKUs, eso creo que es bastante seguro de suponer.</span></p>
<p><span>Por lo tanto, si estoy usando pronóstico, es muy seguro que el tiempo de reposición es largo. Y peor todavía, si además de pronósticos, uso <a href="https://ingenieriaindustrialonline.com/consultoria/la-falacia-del-min-max-y-eoq/">MIN/MAX</a>, el tiempo de reposición también es variable, por lo que debería pronosticar también cuánto será el tiempo hasta la próxima reposición. Y todavía estoy aceptando que podemos mejorar el pronóstico.</span></p>
<p><span>De este razonamiento, yo deduzco que un pronóstico más exacto, sin cambiar nada más, no ha reducido mucho ni espacio ni capital inmovilizado. Supongamos que la mejora del pronóstico elimina el <em>stock out</em>, y se incrementan las ventas. El capital inmovilizado no se reducirá muy significativamente. Recuerde que antes había <em>stock outs</em>, lo que significa menos inventario. Ahora hay más inventario de esos productos y menos de los otros, pero el efecto total es que el inventario sigue siendo proporcional al tiempo de reposición, por lo que no puede reducirse mucho.</span></p>
<h2><span>¿Qué determina la rentabilidad de una empresa?</span></h2>

		<div id="que-determina-la-rentabilidad-de-una-empresa" data-title="¿Qué determina la rentabilidad de una empresa?" class="index-title"></div>
	
<p><span>Tal vez debí empezar por aquí. <a href="https://ingenieriaindustrialonline.com/teoria-de-restricciones-toc/las-empresas-como-un-sistema-un-todo-indivisible/"><strong>Una empresa es un sistema</strong></a> y su rentabilidad depende de cuánto margen podemos generar con sus recursos más escasos. Otra manera de verlo es cuánto dinero se puede generar por cada centavo gastado en operar.</span></p>
<p><span>En <a href="https://ingenieriaindustrialonline.com/teoria-de-restricciones-toc/que-es-teoria-de-restricciones-toc/"><strong>TOC – Teoría de Restricciones</strong></a>, el Dr. Goldratt definió solo tres maneras de medir el dinero en una empresa: </span></p>

		<div class="checklist tie-list-shortcode">
<ul>
<li><span><a data-toggle="tooltip" data-placement="top" class="post-tooltip tooltip-top" title="Throughput"><strong>trúput</strong></a>, </span></li>
<li><span><strong>inventario</strong>, </span></li>
<li><span><strong>gasto de operación</strong>.</span></li>
</ul>

		</div>
	
<p><span>El trúput es la velocidad de generar dinero a través de las ventas. El inventario es la cantidad de dinero atrapado en el sistema y puede convertirse en trúput. El gasto de operación es el dinero gastado para convertir el inventario en trúput.</span></p>
<p><span>Sé que inventario definido así puede confundir. Mejor usemos inversión, y dejemos el término inventario para las unidades de productos almacenadas.</span></p>
<p><span>En optimización matemática (<a href="https://ingenieriaindustrialonline.com/investigacion-de-operaciones/programacion-lineal/">programación lineal</a> y no lineal), se define una función objetivo del sistema. En el caso de una empresa, es la utilidad. Y esa función daría infinito si no fuera porque los recursos de la empresa son limitados, por lo que decimos que el óptimo lo determinan las restricciones activas.</span></p>
<p><span>En los sistemas ya sabemos que la mayoría de los recursos deben tener holguras (ver <a href="https://ingenieriaindustrialonline.com/consultoria/refutacion-al-balanceo-de-lineas/">refutación al balanceo de líneas</a>) por lo que son unas pocas las restricciones activas.</span></p>
<p><span>Entonces, la rentabilidad de una empresa está determinada por cuáles son sus restricciones activas y cómo se usan.</span></p>
<p><span>Espacio y capital son dos restricciones que se usan más o menos dependiendo del tamaño del inventario requerido. Si el inventario necesario es mayor, estas dos restricciones se están usando más, incluso al punto de agotarlas. En ese caso nos vemos obligados a aceptar un nivel de <em>stock out</em> porque no podemos incrementar el inventario.</span></p>
<h2><span>Relación del pronóstico y rentabilidad</span></h2>

		<div id="relacion-del-pronostico-y-rentabilidad" data-title="Relación del pronóstico y rentabilidad" class="index-title"></div>
	
<p><span>Como ya vimos, usar pronósticos está asociado a un tiempo largo de reposición, por lo que las restricciones mencionadas: <em>espacio y capital</em>, estarán utilizadas casi al máximo. Ahora es el momento de responder, <strong><em>¿cómo mejora la rentabilidad un mejor pronóstico?</em></strong></span></p>
<p><span>Un mejor pronóstico hará que usemos mejor esas restricciones de espacio y capital, pero no logrará que las usemos menos. Es decir, si son restricciones activas, lograremos “<em>mover un poco la aguja</em>” con más ventas al reducir los <em>stock outs</em>, pero no mucho más, porque no ha cambiado el tiempo de reposición y seguiremos usando mucho de esas restricciones.</span></p>
<h2><span>¿Y si reducimos el tiempo de reposición?</span></h2>

		<div id="y-si-reducimos-el-tiempo-de-reposicion" data-title="¿Y si reducimos el tiempo de reposición?" class="index-title"></div>
	
<p><span>Al reducir el tiempo de reposición aliviamos inmediatamente la necesidad de inventario para satisfacer la máxima demanda. Es decir, podemos tener menos unidades de inventario y al mismo tiempo ese es un inventario proporcionalmente mayor al anterior. Esto logra reducir <em>stock out</em> y reducir el uso de las restricciones espacio y capital simultáneamente.</span></p>
<p><span>Al reducir el uso de las restricciones, ahora podemos explotar esas restricciones de un modo mejor ampliando variedad, por ejemplo, logrando incrementar las ventas mucho más.</span></p>
<p><span>En un <em>retail</em> típico, los puntos de venta pueden reabastecerse todos los días desde su centro de distribución. Y creo no equivocarme si digo que los puntos de venta reciben mercadería todos los días. Lo que pasa es que el cambio fundamental está en que hacemos la reposición de todos los SKUs todos los días. </span></p>
<p><span><em>¿Cómo influye ahora un mejor pronóstico si ya no estamos copando las restricciones de espacio o capital?</em> Yo creo que no hace ninguna diferencia. Y para un tiempo tan corto, el mejor pronóstico es repetir el pasado inmediato: <strong>reponer hoy lo que se consumió ayer</strong>.</span></p>
<p><span>Pero puede haber cambios en la demanda por cada SKU, y los niveles de inventario no ser adecuados en el tiempo. Para eso necesitamos detectar en qué dirección se mueve la demanda, pero no requerimos un número exacto de unidades a reponer. En TOC tenemos un mecanismo simple que llamamos <strong>Administración Dinámica de Amortiguadores</strong>, que se puede automatizar y ajusta la inversión de acuerdo con la demanda real. Este es el origen de lo que se ha llamado “<em>Demand Driven</em>”.</span></p>
<p><span>Una característica de este sistema es que requiere esfuerzo solo para recolectar los datos diarios, que de todos modos ya se recolectan. Y no se gasta tiempo en procesarlos, porque lo hace un computador (aunque es bueno que haya supervisión humana siempre).</span></p>
<h2><span>¿Cuándo conviene pronosticar la demanda?</span></h2>

		<div id="cuando-conviene-pronosticar-la-demanda" data-title="¿Cuándo conviene pronosticar la demanda?" class="index-title"></div>
	
<p><span>La decisión de capacidad es una decisión estratégica. Normalmente la capacidad no puede variarse fácilmente en cantidades significativas. Incrementar al doble o reducir a la mitad son movimientos que no pueden hacerse con frecuencia y requieren una <strong>planificación de las necesidades</strong>. Para este tipo de decisiones es que se requiere <strong>S&amp;OP</strong> (<em>Sales and Operations Planning</em>).</span></p>
<p><span>A nivel de capacidad hay mucha agregación estadística. Es fácil deducir eso. Si una empresa fabrica 3000 SKUs distintos, difícilmente tendrá cientos de líneas de producción. Una fábrica muy grande tiene menos de diez líneas, por lo que la demanda por cada línea tiene una gran agregación estadística. Eso permite también deducir que el pronóstico de la demanda agregada para cada línea tiene un error mucho menor que el pronóstico de venta de cada SKU. (Un poco de agregación estadística pueden observar en: <a href="https://ingenieriaindustrialonline.com/gestion-de-inventarios/cross-docking-no-lo-intente-en-casa/"><em><strong>Cross Docking: ¡No lo intente en casa!</strong></em></a>).</span></p>
<p><span>En esas circunstancias es aconsejable hacer <a href="https://ingenieriaindustrialonline.com/pronostico-de-la-demanda/que-es-el-pronostico-de-la-demanda/"><strong>pronósticos de demanda</strong></a> para planear ampliaciones de capacidad. La dificultad en este tema es cómo las personas no entienden la función exponencial, pero ese es tema para otro artículo.</span></p>
<p><span>Por otro lado, la complejidad de las cadenas de suministro actuales también se prestan para aplicaciones de AI para estudiar la utilización de capacidad en distintos nodos, como fábricas, medios de transporte, puertos, contenedores, etc. En ese campo es muy impresionante lo que <a href="https://throughput.ai/" target="_blank" rel="noopener">Throughput Inc.</a> ha logrado con su aplicación ELI (me parece que en honor a Eli Goldratt).</span></p>
<h2><span>Conclusión</span></h2>

		<div id="conclusion" data-title="Conclusión" class="index-title"></div>
	
<p><span>Si me ofrecen un sistema para mejorar el pronóstico de la demanda para reponer en los puntos de venta, ya sé que es un sistema que opera con tiempos largos de reposición para cada SKU, por lo que no puedo esperar una gran mejora en rentabilidad. Sí habrá mejora, pero no muy grande.</span></p>
<p><span>En cambio, sin ningún sistema de pronóstico de demanda, pero <strong>con un sistema dinámico de ajuste de amortiguadores</strong>, con tiempos cortos de reposición, la mejora en rentabilidad será la misma o mejor que la del otro sistema, pero con menos esfuerzo y menos capital, y además se suma la liberación de restricciones para generar más margen todavía.</span></p>
<hr />

		<div class="clearfix"></div>
		<div class="about-author about-author-box container-wrapper">
			<div class="author-avatar">
				<img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/avatars/940/60e72e2d7b452-bpfull.jpg" alt="">
			</div>
			<div class="author-info">
				<h4><strong>Matías Birrell Rodríguez</strong></h4>De profesión, ingeniero civil de industrias, con mención en mecánica, con un MBA en finanzas. Pero principalmente, experto en Teoría de Restricciones y autor de libros acerca de este tema, habiendo trabajado y aprendido directamente con el Dr. Goldratt en Goldratt Group. Adicionalmente es director de <strong><a href="http://www.goldfish.cl">www.goldfish.cl</a></strong>, empresa que ofrece aplicaciones en la nube, simples y asequibles, para aplicar estos conceptos a las decisiones diarias. <a href="https://otif100.com"><strong>OTIF100</strong></a> (manufactura), <a href="https://fillrate100.com"><strong>Fill Rate 100</strong></a> (cadena de suministro).</p>
<p style="text-align: center;"><a href="https://goldfish.cl/" target="_blank" class="shortc-button small black">¿Quieres optimizar tus procesos? Contáctame</a>

			</div>
		</div>
	
<p>La entrada <a href="https://ingenieriaindustrialonline.com/pronostico-de-la-demanda/inteligencia-artificial-para-mejorar-pronosticos-de-la-demanda/">¿Inteligencia Artificial para mejorar pronósticos de la demanda?</a> se publicó primero en <a href="https://ingenieriaindustrialonline.com">Ingenieria Industrial Online</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ingenieriaindustrialonline.com/pronostico-de-la-demanda/inteligencia-artificial-para-mejorar-pronosticos-de-la-demanda/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Localización de varios almacenes mediante agrupación geoespacial</title>
		<link>https://ingenieriaindustrialonline.com/localizacion-de-instalaciones/localizacion-de-varios-almacenes-mediante-agrupacion-geoespacial/</link>
					<comments>https://ingenieriaindustrialonline.com/localizacion-de-instalaciones/localizacion-de-varios-almacenes-mediante-agrupacion-geoespacial/#respond</comments>
		
		<dc:creator><![CDATA[Bryan Salazar López]]></dc:creator>
		<pubDate>Thu, 14 Oct 2021 19:54:29 +0000</pubDate>
				<category><![CDATA[Actualidad]]></category>
		<category><![CDATA[Análisis de datos]]></category>
		<category><![CDATA[Diseño y distribución en planta]]></category>
		<category><![CDATA[Gestión de almacenes]]></category>
		<category><![CDATA[Inteligencia artificial]]></category>
		<category><![CDATA[Localización de instalaciones]]></category>
		<category><![CDATA[Logística]]></category>
		<category><![CDATA[Agrupación geoespacial]]></category>
		<category><![CDATA[Centro de masa]]></category>
		<category><![CDATA[Clustering]]></category>
		<category><![CDATA[Localización]]></category>
		<category><![CDATA[Machine learning]]></category>
		<category><![CDATA[Mapa de calor]]></category>
		<category><![CDATA[Mapas de calor]]></category>
		<category><![CDATA[Método del Centro de gravedad]]></category>
		<category><![CDATA[Métodos de localización]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">https://ingenieriaindustrialonline.com/?p=28444</guid>

					<description><![CDATA[<p>En un artículo anterior, desarrollamos un modelo capaz de determinar la localización de una instalación (almacén), de acuerdo a un conjunto de ubicaciones existentes (clientes); estas ubicaciones tenían una ponderación determinada (peso, por ejemplo demanda), y basamos nuestro desarrollo en el algoritmo de Centro de Gravedad. El valor agregado del modelo consistía en la integración &#8230;</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/localizacion-de-instalaciones/localizacion-de-varios-almacenes-mediante-agrupacion-geoespacial/">Localización de varios almacenes mediante agrupación geoespacial</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>En un artículo anterior, desarrollamos un modelo capaz de determinar la localización de una instalación (almacén), de acuerdo a un conjunto de ubicaciones existentes (clientes); estas ubicaciones tenían una ponderación determinada (peso, por ejemplo demanda), y basamos nuestro desarrollo en el algoritmo de Centro de Gravedad.</p>
<p>El valor agregado del modelo consistía en la integración de una capa de mapa de calor (para graficar la densidad), un proceso de geocodificación y el uso de un entorno geográfico real. El alcance de este modelo se encuentra determinado por la localización de una sola instalación (depósito, almacén, etc.), y en los casos en los que se requiera determinar múltiples localizaciones, el modelo no aplica.</p>

		<div class="box info  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>Para ver el artículo: <a href="https://ingenieriaindustrialonline.com/localizacion-de-instalaciones/mapas-de-calor-y-algoritmo-de-centro-de-gravedad-utilizando-python/" target="_blank" rel="noopener"><strong>Mapas de calor y Algoritmo de Centro de Gravedad utilizando Python</strong></a>
			</div>
		</div>
	
<p>La pregunta siguiente que nos hacemos es <em>¿Cómo determinar la localización de múltiples instalaciones?</em> En realidad, hay muchas respuestas para este interrogante, y gran parte de ellas conducen a la <strong>agrupación geoespacial</strong> (Clustering).</p>
<h2>¿Qué es la agrupación geoespacial (Clustering)?</h2>

		<div id="que-es-la-agrupacion-geoespacial-clustering" data-title="¿Qué es la agrupación geoespacial (Clustering)?" class="index-title"></div>
	
<p>La agrupación geoespacial es un método que se utiliza para asociar un conjunto de objetos espaciales en grupos denominados «<em>clusters</em>«. Los objetos que conforman cada grupo presentan un grado de similitud asociado a un atributo o varios atributos en particular.</p>
<p>El objetivo de la agrupación geoespacial, consiste en determinar una relación entre atributos espaciales (coordenadas, ubicación) y no espaciales (demanda, por ejemplo).</p>
<p>En la literatura encontraremos varios tipos de agrupación geoespacial, cada uno con un enfoque particular, y un campo de aplicación específico; entre los cuales podemos encontrar:</p>

		<div class="lightbulb tie-list-shortcode">
<ul>
<li>Agrupación de particiones</li>
<li>Agrupación jerárquica</li>
<li>Agrupación <em>Fuzzy</em></li>
<li>Agrupación basada en densidad</li>
</ul>

		</div>
	
<p>En nuestro caso, que pretendemos determinar la localización de varias instalaciones, considerando la ponderación y ubicación de los puntos existentes, requerimos de un modelo capaz de relacionar atributos espaciales (coordenadas) y no espaciales (peso de cada nodo). Que nos permita, primero agrupar los puntos dados (ubicaciones), y eventualmente, aplicar un algoritmo de <a href="https://ingenieriaindustrialonline.com/diseno-y-distribucion-en-planta/metodo-del-centro-de-gravedad/" target="_blank" rel="noopener"><strong>Centro de Gravedad</strong></a>, para determinar localizaciones potenciales.</p>
<p>Para tales efectos, vamos a utilizar la <strong>agrupación de particiones</strong>, que se caracteriza, entre otras, por:</p>

		<div class="checklist tie-list-shortcode">
<ul>
<li>Agrupar los puntos espaciales en subconjuntos</li>
<li>Cada punto agrupado pertenece solo a un subconjunto (clúster)</li>
<li>Cada subconjunto tiene al menos un punto</li>
</ul>

		</div>
	
<p>Vale la pena destacar que en cuanto a la agrupación de participaciones, en esta categoría encontraremos varios métodos de partición, y nosotros utilizaremos el método <em><strong>K-Means</strong></em>, un algoritmo de aprendizaje automático (Machine Learning) no supervisado. Para ello utilizaremos <em>Python</em>.</p>
<figure id="attachment_28445" aria-describedby="caption-attachment-28445" style="width: 299px" class="wp-caption aligncenter"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/clustering.png" alt="clustering" width="299" height="290" class=" wp-image-28445" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/clustering.png 471w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/clustering-300x291.png 300w" sizes="(max-width: 299px) 100vw, 299px" /><figcaption id="caption-attachment-28445" class="wp-caption-text">Agrupación por particiones</figcaption></figure>
<p>Para sintetizar, el objetivo de este artículo será el de emplear un algoritmo de aprendizaje automático capaz de agrupar nuestros nodos en <em>clusters</em>, de acuerdo a atributos espaciales (coordenadas) y no espaciales (ponderación); para luego, utilizar un algoritmo de Centro de Gravedad en cada <em>clúster</em> para determinar la localización de múltiples instalaciones (almacenes, depósitos, etc.).</p>
<p>En el desarrollo de este ejercicio emplearemos:</p>

		<div class="plus tie-list-shortcode">
<ul>
<li><em><strong>Colaboratory</strong>: </em>Este es un entorno de programación y ejecución virtual de Python desarrollado por Google. Nos permitirá no tener la necesidad de realizar ninguna instalación en nuestros equipos. Todo lo que desarrollemos lo ejecutaremos en un cuaderno virtual.</li>
<li><strong><em>Python</em></strong>: Este será el lenguaje de programación que vamos a utilizar, y advertimos: No es necesario tener conocimientos previos, y el objetivo del artículo no es convertirnos en programadores expertos. Utilizaremos fragmentos de códigos, librerías disponibles, y explicaremos lo necesario para configurar nuestro desarrollo de acuerdo a los objetivos específicos de nuestros modelos.</li>
<li><strong><em>SkLearn</em></strong>: Las librerías son a <em>Python</em>, lo que las <em>apps </em>son a un teléfono celular. Esta es quizá una de las características más a tractivas de este lenguaje: Casi que existe una librería para cada necesidad. En este caso, <em>SKLearn</em>, es una librería que integra un conjunto de métodos de aprendizaje automático y minería de datos.</li>
<li><em><strong>K-Means</strong>: </em>Este es un módulo de <em>SKLearn</em> que contiene el algoritmo de agrupación <em>KMeans,</em> el cual separa muestras en <em>n</em> grupos de varianza igual, minimizando un criterio conocido como inercia o suma de cuadrados dentro del grupo.</li>
<li><em><strong>Matplotlib</strong>: </em>Es una biblioteca completa para crear visualizaciones estáticas, animadas e interactivas en Python. Nos permitirá visualizar nuestros nodos y nuestras localizaciones solución.</li>
<li><strong><em>Pandas</em></strong>: <span>Es un paquete de Python que proporciona estructuras de datos rápidas, y flexibles, diseñadas para que el trabajo con datos estructurados (tabulares, multidimensionales, potencialmente heterogéneos) y de series de tiempo sea fácil e intuitivo.</span></li>
<li><em><strong>Numpy</strong>: </em>Es una librería que nos permitirá efectuar operaciones matriciales en Python.</li>
</ul>

		</div>
	
<hr />
<p>Para desarrollar estas herramientas, vamos a plantear un caso típico de localización de múltiples instalaciones a partir de la consideración de otros nodos (nodos de demanda, por ejemplo).</p>
<h2>Caso de aplicación</h2>

		<div id="caso-de-aplicacion" data-title="Caso de aplicación" class="index-title"></div>
	
<blockquote class=" quote-simple "><p>El Departamento de Desarrollo Sostenible de la ciudad de Cali se encuentra implementando una estrategia piloto de recolección de aceite de cocina usado. Ha articulado este proyecto con una Universidad, la cual desarrolló 4 contenedores inteligentes (BIN’s) para la disposición del bioresiduo.</p></blockquote>
<blockquote class=" quote-simple "><p>En investigaciones asociadas, la Universidad ha determinado que el reciclaje del aceite es un problema de densidad; esto quiere decir que es vital la ubicación de los contenedores (cobertura), para así mismo optimizar el proceso de disposición y recolección. El proyecto piloto piensa articular a las instituciones de educación como puntos potenciales de recolección. Por medio de las instituciones piensan socializar el programa con la comunidad. El primer reto del proyecto consiste en determinar la ubicación de los contenedores inteligentes (4 unidades). La información relacionada con las instituciones de educación que hacen parte del programa (ubicación geográfica / población estudiantil), se detalla a continuación:</p></blockquote>
<table width="611">
<tbody>
<tr>
<td width="80">Nodo</td>
<td width="224">Lugar (Colegios)</td>
<td width="127">Latitud</td>
<td width="100">Longitud</td>
<td width="80">Peso</td>
</tr>
<tr>
<td>0</td>
<td> Comfandi San Nicolás</td>
<td>3,453591118</td>
<td>-76,52254886</td>
<td>1494</td>
</tr>
<tr>
<td>1</td>
<td> Mayor de Santiago de Cali</td>
<td>3,451577758</td>
<td>-76,51023216</td>
<td>908</td>
</tr>
<tr>
<td>2</td>
<td> Municipal Comfandi</td>
<td>3,448107915</td>
<td>-76,51074714</td>
<td>697</td>
</tr>
<tr>
<td>3</td>
<td> Internado San Carlos</td>
<td>3,446994135</td>
<td>-76,51525325</td>
<td>1714</td>
</tr>
<tr>
<td>4</td>
<td> León de Greiff</td>
<td>3,447979402</td>
<td>-76,49993247</td>
<td>1731</td>
</tr>
<tr>
<td>5</td>
<td> Nuestra Señora de la Anunciación</td>
<td>3,445152112</td>
<td>-76,49641342</td>
<td>2297</td>
</tr>
<tr>
<td>6</td>
<td> Fernando de Aragón</td>
<td>3,437355603</td>
<td>-76,51383704</td>
<td>1265</td>
</tr>
<tr>
<td>7</td>
<td> Casa Evangélica</td>
<td>3,437955337</td>
<td>-76,52299947</td>
<td>1658</td>
</tr>
<tr>
<td>8</td>
<td> San Alberto Magno</td>
<td>3,433028941</td>
<td>-76,52707643</td>
<td>604</td>
</tr>
<tr>
<td>9</td>
<td> Santa María Goretty</td>
<td>3,433414486</td>
<td>-76,50720662</td>
<td>416</td>
</tr>
<tr>
<td>10</td>
<td> San Alberto Magno</td>
<td>3,433157456</td>
<td>-76,5267331</td>
<td>1584</td>
</tr>
<tr>
<td>11</td>
<td> San Ignacio de Loyola</td>
<td>3,431786629</td>
<td>-76,51733464</td>
<td>2350</td>
</tr>
<tr>
<td>12</td>
<td> Nuestro Futuro</td>
<td>3,430629992</td>
<td>-76,50360174</td>
<td>964</td>
</tr>
<tr>
<td>13</td>
<td> Sabio Caldas</td>
<td>3,429087807</td>
<td>-76,51660508</td>
<td>329</td>
</tr>
<tr>
<td>14</td>
<td> CREAD</td>
<td>3,425060978</td>
<td>-76,51488847</td>
<td>774</td>
</tr>
<tr>
<td>15</td>
<td> Licomtec</td>
<td>3,416664559</td>
<td>-76,51673383</td>
<td>1818</td>
</tr>
<tr>
<td>16</td>
<td>  Nuestra Señora De La Providencia</td>
<td>3,419534772</td>
<td>-76,49591989</td>
<td>1530</td>
</tr>
<tr>
<td>17</td>
<td> Real Suizo</td>
<td>3,415208029</td>
<td>-76,49323768</td>
<td>2106</td>
</tr>
<tr>
<td>18</td>
<td> Nuevo Edén</td>
<td>3,415722099</td>
<td>-76,53383559</td>
<td>330</td>
</tr>
<tr>
<td>19</td>
<td> Católico</td>
<td>3,413066071</td>
<td>-76,53984374</td>
<td>976</td>
</tr>
<tr>
<td>20</td>
<td> Santa María Stella</td>
<td>3,427031556</td>
<td>-76,55134505</td>
<td>1975</td>
</tr>
<tr>
<td>21</td>
<td> Santa Isabel</td>
<td>3,40805355</td>
<td>-76,50817223</td>
<td>936</td>
</tr>
<tr>
<td>22</td>
<td> Compartir</td>
<td>3,431957663</td>
<td>-76,47495575</td>
<td>1563</td>
</tr>
<tr>
<td>23</td>
<td> Lancaster</td>
<td>3,400770816</td>
<td>-76,55177421</td>
<td>1219</td>
</tr>
<tr>
<td>24</td>
<td> Parroquial Divino Salvador</td>
<td>3,397086588</td>
<td>-76,54259033</td>
<td>1954</td>
</tr>
<tr>
<td>25</td>
<td> Reyes Católicos</td>
<td>3,393316667</td>
<td>-76,53735466</td>
<td>399</td>
</tr>
<tr>
<td>26</td>
<td> Liceo Anglo del Valle</td>
<td>3,387318719</td>
<td>-76,51975937</td>
<td>1741</td>
</tr>
<tr>
<td>27</td>
<td> Laurence</td>
<td>3,383420238</td>
<td>-76,52078934</td>
<td>1111</td>
</tr>
<tr>
<td>28</td>
<td> Los Almendros</td>
<td>3,381278208</td>
<td>-76,52023144</td>
<td>1826</td>
</tr>
<tr>
<td>29</td>
<td> Bautista</td>
<td>3,37720834</td>
<td>-76,52327843</td>
<td>1772</td>
</tr>
<tr>
<td>30</td>
<td> Lacordaire</td>
<td>3,378150837</td>
<td>-76,54460736</td>
<td>1965</td>
</tr>
<tr>
<td>31</td>
<td> General José María Córdoba</td>
<td>3,393573314</td>
<td>-76,54932805</td>
<td>841</td>
</tr>
<tr>
<td>32</td>
<td> El Hogar</td>
<td>3,390745864</td>
<td>-76,5503151</td>
<td>770</td>
</tr>
<tr>
<td>33</td>
<td> Americano</td>
<td>3,379093255</td>
<td>-76,54688187</td>
<td>650</td>
</tr>
<tr>
<td>34</td>
<td> Santa Filomena</td>
<td>3,401969935</td>
<td>-76,51345082</td>
<td>1401</td>
</tr>
<tr>
<td>35</td>
<td> Tomás Vasconi</td>
<td>3,403040928</td>
<td>-76,5173132</td>
<td>1474</td>
</tr>
<tr>
<td>36</td>
<td> República del Salvador</td>
<td>3,404454636</td>
<td>-76,52143308</td>
<td>1926</td>
</tr>
<tr>
<td>37</td>
<td> Los Andes</td>
<td>3,429601077</td>
<td>-76,53761216</td>
<td>1566</td>
</tr>
<tr>
<td>38</td>
<td>Villacolombia</td>
<td>3,445493943</td>
<td>-76,50169202</td>
<td>2354</td>
</tr>
<tr>
<td>39</td>
<td>Las Américas</td>
<td>3,449220822</td>
<td>-76,50594064</td>
<td>2043</td>
</tr>
<tr>
<td>40</td>
<td>SantaFe</td>
<td>3,442238267</td>
<td>-76,50988885</td>
<td>2333</td>
</tr>
<tr>
<td>41</td>
<td>Evaristo García</td>
<td>3,440781776</td>
<td>-76,51752778</td>
<td>696</td>
</tr>
<tr>
<td>42</td>
<td>Alfredo Vasquez Cobo</td>
<td>3,435598366</td>
<td>-76,5164549</td>
<td>1073</td>
</tr>
<tr>
<td>43</td>
<td>Ciudad de Cali</td>
<td>3,431143181</td>
<td>-76,51272126</td>
<td>1275</td>
</tr>
<tr>
<td>44</td>
<td>INEM</td>
<td>3,482761991</td>
<td>-76,49976083</td>
<td>1485</td>
</tr>
<tr>
<td>45</td>
<td>Olaya Herrera</td>
<td>3,478178519</td>
<td>-76,51280709</td>
<td>1470</td>
</tr>
<tr>
<td>46</td>
<td>Guillermo Valencia</td>
<td>3,47449459</td>
<td>-76,5136654</td>
<td>1248</td>
</tr>
<tr>
<td>47</td>
<td>José Ignacio Rengifo</td>
<td>3,471624543</td>
<td>-76,5136654</td>
<td>2160</td>
</tr>
<tr>
<td>48</td>
<td>Santo Tomás</td>
<td>3,45830227</td>
<td>-76,5164549</td>
<td>1776</td>
</tr>
<tr>
<td>49</td>
<td>La Merced</td>
<td>3,46271449</td>
<td>-76,5024645</td>
<td>706</td>
</tr>
<tr>
<td>50</td>
<td>Pedro Antonio Molina</td>
<td>3,482804827</td>
<td>-76,48761579</td>
<td>2369</td>
</tr>
<tr>
<td>51</td>
<td>Santa Librada</td>
<td>3,46228612</td>
<td>-76,52302095</td>
<td>2498</td>
</tr>
<tr>
<td>52</td>
<td>República de Israel</td>
<td>3,463656904</td>
<td>-76,51053258</td>
<td>1510</td>
</tr>
<tr>
<td>53</td>
<td>San Vicente Paul</td>
<td>3,466227117</td>
<td>-76,50950261</td>
<td>2330</td>
</tr>
<tr>
<td>54</td>
<td>Manuel María Mallarino</td>
<td>3,456760129</td>
<td>-76,48851701</td>
<td>1464</td>
</tr>
<tr>
<td>55</td>
<td>Sebastían de Belalcazar</td>
<td>3,460229941</td>
<td>-76,48521253</td>
<td>628</td>
</tr>
<tr>
<td>56</td>
<td>Liceo Departamental</td>
<td>3,423860462</td>
<td>-76,5385563</td>
<td>364</td>
</tr>
<tr>
<td>57</td>
<td>Libardo Madrid</td>
<td>3,422061154</td>
<td>-76,54383489</td>
<td>2439</td>
</tr>
<tr>
<td>58</td>
<td>Metropolitano Santa Anita</td>
<td>3,401691038</td>
<td>-76,54218265</td>
<td>1815</td>
</tr>
<tr>
<td>59</td>
<td>San José</td>
<td>3,396935816</td>
<td>-76,55031511</td>
<td>2230</td>
</tr>
</tbody>
</table>
<hr />
<p>Para tales efectos, desarrollaremos un modelo que apoye el análisis preliminar y la localización de los múltiples contenedores. También, que tenga la capacidad de predecir el grupo (clúster) al que pertenecería un nodo nuevo.</p>
<hr />
<h3>Paso 1: Crear el entorno de trabajo en Colaboratory</h3>

		<div id="paso-1-crear-el-entorno-de-trabajo-en-colaboratory" data-title="Paso 1: Crear el entorno de trabajo en Colaboratory" class="index-title"></div>
	
<p><span>Lo primero que vamos a hacer consiste en crear un entorno de trabajo en <em>Google</em> </span><em>Colaboratory</em><span>, así que vayamos allá: </span><a href="https://colab.research.google.com/#create=true" target="_blank" rel="noopener"><em><strong>Abrir cuaderno nuevo</strong></em></a><span>.</span></p>
<p>Verán que tienen un lienzo para programar el modelo, así que en este cuaderno podemos ir generando las líneas de código que explicaremos en los pasos siguientes.</p>
<h3>Paso 2: Importar las librerías necesarias</h3>

		<div id="paso-2-importar-las-librerias-necesarias" data-title="Paso 2: Importar las librerías necesarias" class="index-title"></div>
	
<p>Respecto a las librerías, en la introducción del artículo hicimos una descripción de la funcionalidad de cada una, veamos como importarlas en nuestro entorno:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Importar las librerías necesarias
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans</code></pre>
</div>
<p>De esta manera, tenemos todo lo necesario para empezar a desarrollar nuestro código.</p>
<h3>Paso 3: Importar los datos desde Excel</h3>

		<div id="paso-3-importar-los-datos-desde-excel" data-title="Paso 3: Importar los datos desde Excel" class="index-title"></div>
	
<p>De acuerdo a las necesidades del modelo, podemos desarrollar un código que permita la entrada manual de la información, la captura de los datos desde entornos digitales (Internet, por ejemplo), o podemos, desde luego, alimentar nuestro modelo con información contenida en documentos externos, como es el caso de un archivo de Microsoft Excel.</p>
<p>Esta puede considerarse como una de las ventajas de utilizar <em>Python, </em>su capacidad de integrarse con cualquier fuente de datos. En nuestro caso, toda la información se encuentra contenida en un documento de Excel, el cual presenta el siguiente formato:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/datos_excel.png" alt="datos_excel" width="612" height="241" class="size-full wp-image-28446 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/datos_excel.png 612w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/datos_excel-300x118.png 300w" sizes="(max-width: 612px) 100vw, 612px" /></p>
<p>Ya veremos cómo, parte de estos datos son prescindibles y otros indispensables.</p>

		<div class="box download  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>Puedes descargar el documento de Excel que utilizamos en este ejemplo: <a href="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/cluster.xlsx" target="_blank" rel="noopener"><strong>Base de datos</strong></a>
			</div>
		</div>
	
<p>En <em>Colaboratory</em>, el siguiente fragmento permitirá cargar un archivo al entorno de ejecución:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>from google.colab import files

uploaded = files.upload()

for fn in uploaded.keys():
  print('User uploaded file "{name}" with length {length} bytes'.format(
      name=fn, length=len(uploaded[fn])))</code></pre>
</div>
<p>Al ejecutar este fragmento de código, se abrirá una ventana emergente del explorador que permitirá cargar nuestra base de datos, en nuestro caso el archivo tienen el nombre de <em>cluster.xlsx.</em></p>
<p>La siguiente línea de código permitirá almacenar los datos contenidos en el documento en un <em>Dataframe</em> de nuestro entorno, dentro de la variable <em>data</em>.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Leer el documento de Excel y almacenar los datos en la variable data
data = pd.read_excel('cluster.xlsx')</code></pre>
</div>
<p>Podemos en cualquier momento confirmar si la carga de los datos se ha realizado correctamente, para eso imprimiremos las primeras cinco filas del  <em>DataFrame:</em></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>data.head()</code></pre>
</div>
<p>Al ejecutar esta instrucción tenemos la siguiente salida:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/head_cluster.png" alt="head_cluster" width="539" height="237" class="size-full wp-image-28448 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/head_cluster.png 539w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/head_cluster-300x132.png 300w" sizes="(max-width: 539px) 100vw, 539px" /></p>
<h3>Paso 4: Graficar los puntos dados iniciales (Nodos)</h3>

		<div id="paso-4-graficar-los-puntos-dados-iniciales-nodos" data-title="Paso 4: Graficar los puntos dados iniciales (Nodos)" class="index-title"></div>
	
<p>Nuestros puntos iniciales, o las ubicaciones de partida son las instituciones de educación que nos otorga el planteamiento del problema.</p>
<p>Para graficar estos puntos utilizamos el sistema de coordenadas disponible: Latitud y Longitud. Así entonces, debemos extraer estos datos de la hoja de cálculo (<em>DataFrame</em>) que hemos importado al modelo; convertir estas coordenadas en una matriz bidimensional (Latitud y Longitud) y graficar los puntos:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Graficar los nodos dados (ubicaciones)
Lat= data['Latitud']
Lon = data['Longitud']
Peso = data['Peso']
X = []
for i in range(len(data['Latitud'])):
    X.append(Lat[i])
    X.append(Lon[i])

X = np.array(X)

X = X.reshape(-1, 2,)


plt.scatter(Lat, Lon)
plt.show()</code></pre>
</div>
<p>Al ejecutar este fragmento de código, tendremos:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/ubicaciones-iniciales.png" alt="ubicaciones iniciales" width="393" height="248" class="size-full wp-image-28449 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/ubicaciones-iniciales.png 393w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/ubicaciones-iniciales-300x189.png 300w" sizes="(max-width: 393px) 100vw, 393px" /></p>
<p>Podemos apreciar cómo se encuentran dispersos los nodos iniciales, formando parte un mismo conjunto que es la población. Las coordenadas son latitud y longitud. Los nodos son, una vez más recordamos, las instituciones educativas, de acuerdo al caso de estudio.</p>
<h3>Paso 5: Agrupar los nodos geoespacialmente mediante Machine Learning</h3>

		<div id="paso-5-agrupar-los-nodos-geoespacialmente-mediante-machine-learning" data-title="Paso 5: Agrupar los nodos geoespacialmente mediante Machine Learning" class="index-title"></div>
	
<p>Cuando mencionamos Machine Learning, a menudo la primera consideración que tenemos es de complejidad. Pues bien, muchos de los algoritmos que hemos utilizado durante décadas son en realidad de aprendizaje automático, como por ejemplo la <a href="https://ingenieriaindustrialonline.com/pronostico-de-la-demanda/regresion-lineal-en-python/"><em><strong>regresión lineal</strong></em></a>. El algoritmo de <em>K-Means </em>que emplearemos de forma automatizada mediante <em>Python</em>, utiliza centroides que minimizan la inercia, o el criterio de suma de cuadrados de cada clúster:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/formula_cluster.png" alt="formula_cluster" width="203" height="65" class="size-full wp-image-28451 aligncenter" /></p>
<p>Me pareció conveniente explicar un poco la teoría, pero vayamos a la práctica. Toda vez que tenemos los nodos del modelo, lo siguiente que debemos indicar es la cantidad de agrupaciones que queremos (clúster). Ya que el problema plantea la disposición de 4 contenedores, vamos a dividir la población de nodos en 4 conjuntos.</p>
<p>Luego, correremos el algoritmo <em>K-Means, </em>veamos cómo:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Ejecutar el algoritmo KMeans
clusters = 4
KMean = KMeans(n_clusters=clusters)
KMean_g = KMean.fit_predict(X)
KMean.fit(X)</code></pre>
</div>
<p>Lo siguiente que haremos será establecer los centroides de cada clúster, es decir, la ubicación de nuestros contendores. En primer lugar, el modelo nos dará las coordenadas. Utilizaremos la siguiente línea de código:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Determinar los centroides de cada clúster
KMean.cluster_centers_</code></pre>
</div>
<p>Al ejecutarla tendremos:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centroides.png" alt="centroides" width="436" height="129" class="size-full wp-image-28452 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centroides.png 436w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centroides-300x89.png 300w" sizes="(max-width: 436px) 100vw, 436px" /></p>
<p>Estas son las coordenadas que indican el centro de cada uno de nuestros grupos de nodos. Y teóricamente ahí deberíamos disponer nuestros contenedores.</p>
<h3>Paso 6: Graficar los clusters y los centroides (Localizaciones múltiples)</h3>

		<div id="paso-6-graficar-los-clusters-y-los-centroides-localizaciones-multiples" data-title="Paso 6: Graficar los clusters y los centroides (Localizaciones múltiples)" class="index-title"></div>
	
<p>El siguiente paso consiste en graficar todas las coordenadas que ya tenemos: tantos los nodos iniciales, como los los centroides, o las localizaciones solución. Veamos cómo:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Graficar todas las coordenadas (Puntos y centroides)
plt.scatter(X[:,0], X[:,1], c=KMean_g) #Puntos iniciales

#Centroides
plt.scatter(KMean.cluster_centers_[0][0], KMean.cluster_centers_[0][1], s=50, c='r')
plt.scatter(KMean.cluster_centers_[1][0], KMean.cluster_centers_[1][1], s=50, c='r')
plt.scatter(KMean.cluster_centers_[2][0], KMean.cluster_centers_[2][1], s=50, c='r')
plt.scatter(KMean.cluster_centers_[3][0], KMean.cluster_centers_[3][1], s=50, c='r')</code></pre>
</div>
<p>Al ejecutar el fragmento tendremos:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centroides_II.png" alt="centroides_II" width="393" height="248" class="size-full wp-image-28453 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centroides_II.png 393w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centroides_II-300x189.png 300w" sizes="(max-width: 393px) 100vw, 393px" /></p>
<p>Vemos cómo se han efectuado las agrupaciones de los nodos (colores), y los marcadores rojos indican los centroides. Este debería ser el final de nuestro desarrollo, sin embargo, no sé si lo han notado, siempre hemos hablado de centroides, nunca de centros de gravedad o centros de masa. Bien, no sé si también han identificado que en ningún momento hemos considerado el peso de cada nodo, en este caso la <em>población estudiantil </em>de cada institución.</p>
<p><em>¿Esto qué implica?</em> Implica que hemos desarrollado un modelo que tiene exclusivamente consideraciones espaciales. De hecho, visualmente puede observarse cómo, básicamente los centroides se ubican en lo que podría considerarse el medio de cada clúster, sin ninguna consideración adicional aparente, por lo menos a la vista.</p>
<p>Pues bien, vamos a solucionarlo, para ello debemos retocar algunos de los pasos anteriores:</p>
<h3>Paso 5 (Recargado): Agrupar los nodos geoespacialmente mediante Machine Learning (Considerando atributos espaciales y no espaciales)</h3>

		<div id="paso-5-recargado-agrupar-los-nodos-geoespacialmente-mediante-machine-learning-considerando-atributos-espaciales-y-no-espaciales" data-title="Paso 5 (Recargado): Agrupar los nodos geoespacialmente mediante Machine Learning (Considerando atributos espaciales y no espaciales)" class="index-title"></div>
	
<p>Dentro de nuestro marco de datos (<em>DataFrame</em>) tenemos la información relacionada al peso de cada nodo (<em>Población estudiantil</em>). Pues bien, vamos a considerarla al ejecutar el algoritmo <em>K-Means</em>.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Ejecutar el algoritmo KMeans (Considerando el peso de los nodos)
clusters = 4
KMean = KMeans(n_clusters=clusters)
KMean_g = KMean.fit_predict(X)
KMean.fit(X, sample_weight=Peso)</code></pre>
</div>
<p>Lo siguiente que haremos será establecer los centroides de cada clúster, que ahora sí serán Centros de Gravedad; es decir, la ubicación de nuestros contendores. En primer lugar, el modelo nos dará las coordenadas. Utilizaremos la siguiente línea de código:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Determinar los centroides de cada clúster
KMean.cluster_centers_</code></pre>
</div>
<p>Al ejecutarla tendremos:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centroides_recargado.png" alt="centroides_recargado" width="436" height="129" class="size-full wp-image-28454 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centroides_recargado.png 436w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centroides_recargado-300x89.png 300w" sizes="(max-width: 436px) 100vw, 436px" /></p>
<p>Los centroides han cambiado, ahora son centros de gravedad afectados por el peso de cada nodo. Es posible que incluso haya cambiado la agrupación de los nodos (composición de los clusters).</p>
<h3>Paso 6 (Recargado): Graficar los clusters y los Centros de Gravedad (Localizaciones múltiples)</h3>

		<div id="paso-6-recargado-graficar-los-clusters-y-los-centros-de-gravedad-localizaciones-multiples" data-title="Paso 6 (Recargado): Graficar los clusters y los Centros de Gravedad (Localizaciones múltiples)" class="index-title"></div>
	
<p>El siguiente paso consiste en graficar todas las coordenadas que ya tenemos: tantos los nodos iniciales, como los los Centros de Gravedad, o las localizaciones solución. Veamos cómo:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Graficar todas las coordenadas (Puntos y centroides)
plt.scatter(X[:,0], X[:,1], c=KMean_g) #Puntos iniciales

#Centroides
plt.scatter(KMean.cluster_centers_[0][0], KMean.cluster_centers_[0][1], s=50, c='r')
plt.scatter(KMean.cluster_centers_[1][0], KMean.cluster_centers_[1][1], s=50, c='r')
plt.scatter(KMean.cluster_centers_[2][0], KMean.cluster_centers_[2][1], s=50, c='r')
plt.scatter(KMean.cluster_centers_[3][0], KMean.cluster_centers_[3][1], s=50, c='r')</code></pre>
</div>
<p>Al ejecutar el fragmento tendremos:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/Centros-de-gravedad.png" alt="Centros de gravedad" width="393" height="248" class="size-full wp-image-28455 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/Centros-de-gravedad.png 393w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/Centros-de-gravedad-300x189.png 300w" sizes="(max-width: 393px) 100vw, 393px" /></p>
<p>El resultado respecto a los centroides es diferente. La consideración de un atributo no espacial, en este caso el peso de cada nodo (<em>población estudiantil de cada institución educativa</em>), ha incidido en la ubicación propuesta de las localizaciones solución. Y este debería ser el final de nuestro modelo.</p>
<p>Hemos logrado agrupar nuestros puntos iniciales en clusters, y luego hemos determinado los Centros de Gravedad de cada uno de los clusters.</p>
<p>Por último, veamos una característica de la librería <em>K-Means </em>Análisis predictivo de nodos en clusters, es decir, de acuerdo a unas coordenadas dadas, podemos estimar el grupo al que pertenecerá un nuevo nodo.</p>
<h3>Paso 7: Predicción de clusters</h3>

		<div id="paso-7-prediccion-de-clusters" data-title="Paso 7: Predicción de clusters" class="index-title"></div>
	
<p>En primer lugar ejecutaremos una línea que nos permite identificar a cada nodo dentro de un grupo. Ya que tenemos 4 grupos, estos se identificarán de la siguiente manera: 0, 1, 2, 3.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>KMean.labels_</code></pre>
</div>
<p>Al ejecutar esta línea tendremos:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/grupos_nodos.png" alt="grupos_nodos" width="622" height="111" class="size-full wp-image-28456 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/grupos_nodos.png 622w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/grupos_nodos-300x54.png 300w" sizes="(max-width: 622px) 100vw, 622px" /></p>
<p>Vemos como cada una de las 60 instituciones educativas (nodos), tienen un identificador de grupo dentro del modelo.</p>
<p>Ahor, dadas las coordenadas de un nuevo nodo, podemos predecir el grupo al cual pertenecerá:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>sample_test=np.array([-3.433,-76.22])
second_test=sample_test.reshape(1, -1)
KMean.predict(second_test)</code></pre>
</div>
<p>Al ejecutar este fragmento tendremos:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/nodos_prediccion.png" alt="nodos_prediccion" width="483" height="118" class="size-full wp-image-28457 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/nodos_prediccion.png 483w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/nodos_prediccion-300x73.png 300w" sizes="(max-width: 483px) 100vw, 483px" /></p>
<p>Es decir, el algoritmo predice que de acuerdo a las coordenada dadas, el nuevo nodo formaría parte del clúster 0.</p>
<hr />
<p>Pudimos observar cómo varía el resultado dependiendo de la consideración de atributos netamente geoespaciales, y de atributos no espaciales, como la ponderación de cada nodo.</p>

		<div class="post-content-slideshow-outer">
			<div class="post-content-slideshow">

			<div class="loader-overlay"><div class="spinner-circle"></div></div>

				<div class="tie-slick-slider">

			<div class="slide post-content-slide">
				 Atributos geoespaciales |</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centroides_II.png" alt="centroides_II" width="393" height="248" class="size-full wp-image-28453 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centroides_II.png 393w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centroides_II-300x189.png 300w" sizes="(max-width: 393px) 100vw, 393px" /></p>

			</div><!-- post-content-slide -->
		

			<div class="slide post-content-slide">
				 Atributos geoespaciales y de ponderación |</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/Centros-de-gravedad.png" alt="Centros de gravedad" width="393" height="248" class="size-full wp-image-28455 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/Centros-de-gravedad.png 393w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/Centros-de-gravedad-300x189.png 300w" sizes="(max-width: 393px) 100vw, 393px" /></p>

			</div><!-- post-content-slide -->
		


					<div class="slider-nav-wrapper">
						<ul class="tie-slider-nav"></ul>
					</div>
				</div><!-- tie-slick-slider -->
			</div><!-- post-content-slideshow -->
		</div><!-- post-content-slideshow-outer -->
	
<h2>Integración con mapas de calor y entornos geográficos reales</h2>
<p>Uno de los puntos negativos del modelo que acabamos de desarrollar es quizá que no nos permite visualizar gráficamente la densidad de los puntos. Si observamos las gráficas, todos los puntos parecen tener el mismo tamaño, y si bien esta no es una consideración para el funcionamiento del algoritmo; en el análisis preliminar quisiéramos tener esta herramienta. Otra consideración adicional sería la posibilidad de graficar todos nuestros puntos, y los centros de gravedad de cada (clúster) en un entorno geográfico real.</p>
<p>Pues bien, una de las ventajas fundamentales de <em>Python </em>consiste en que podemos integrar distintos desarrollos en nuestros modelos, tal es el caso del desarrollo que efectúanos en un artículo anterior (<a href="https://ingenieriaindustrialonline.com/localizacion-de-instalaciones/mapas-de-calor-y-algoritmo-de-centro-de-gravedad-utilizando-python/"><strong>Mapas de calor y Entornos geográficos reales</strong></a>); de tal manera que podamos complementar nuestro modelo.</p>
<p>No vamos a profundizar en la librerías, ni en la definición de las variables, para eso recomendamos leer el artículo. Veamos entonces, como complementamos este modelo:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>import folium
import statistics
from folium.plugins import HeatMap
mediaLong = statistics.mean(Lon)
mediaLat = statistics.mean(Lat)

# Crear un objeto de mapa base Map()
mapa = folium.Map(location=[mediaLat, mediaLong], zoom_start = 13)

# Crear una capa de mapa de calor
mapa_calor = HeatMap( list(zip(Lat, Lon, data["Peso"])),
                   min_opacity=0.2,
                   max_val=data["Peso"].max(),
                   radius=50, 
                   blur=50, 
                   max_zoom=1)

#Creamos el marcador de Centro de Gravedad
tooltip = 'Centro de gravedad'
folium.Marker([KMean.cluster_centers_[0][0], KMean.cluster_centers_[0][1]], popup="Centro", tooltip = tooltip).add_to(mapa)
folium.Marker([KMean.cluster_centers_[1][0], KMean.cluster_centers_[1][1]], popup="Centro", tooltip = tooltip).add_to(mapa)
folium.Marker([KMean.cluster_centers_[2][0], KMean.cluster_centers_[2][1]], popup="Centro", tooltip = tooltip).add_to(mapa)
folium.Marker([KMean.cluster_centers_[3][0], KMean.cluster_centers_[3][1]], popup="Centro", tooltip = tooltip).add_to(mapa)

# Adherimos la capa de mapa de calor al mapa principal
mapa_calor.add_to(mapa)
mapa</code></pre>
</div>
<p>Al ejecutar este fragmento tendremos el siguiente resultado:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/Mapa-de-calorII.png" alt="Mapa de calorII" width="700" height="394" class="size-full wp-image-28492 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/Mapa-de-calorII.png 700w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/Mapa-de-calorII-300x169.png 300w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/Mapa-de-calorII-390x220.png 390w" sizes="(max-width: 700px) 100vw, 700px" /></p>
<p>Ahora tenemos un modelo capaz de <strong>agrupar nuestros nodos en clusters</strong> de acuerdo a atributos geoespaciales; capaz de <strong>determinar los centros de gravedad</strong> de cada cluster de acuerdo a atributos no espaciales (en nuestro caso la población de los nodos); capaz de complementarse con una capa de visualización de <strong>mapa de calor</strong> que nos permite apreciar la densidad y todo esto <strong>puede visualizarse en un entorno geográfico real</strong>.</p>
<h2>Consideraciones finales</h2>

		<div id="consideraciones-finales" data-title="Consideraciones finales" class="index-title"></div>
	
<p>Ya lo expresamos anteriormente, la base del algoritmo <em>K-Means </em>es la consideración y minimización de la inercia, y en espacios de muy altas dimensiones, las distancias suelen inflarse, ya que esta no es una medida normalizada.</p>
<p>Sin embargo, para los efectos que hemos empleado, el algoritmo suele arrojar resultados satisfactorios.</p>
<p>El código completo de este desarrollo lo puedes encontrar en nuestro cuaderno: <a href="https://colab.research.google.com/drive/1qboyfxT1kdjn9XiqXudZBf74dUtxwCkn?usp=sharing" target="_blank" rel="noopener"><em><strong>Localización de varias instalaciones mediante agrupación geoespacial y Centro de Gravedad (Python)</strong></em></a>.</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/localizacion-de-instalaciones/localizacion-de-varios-almacenes-mediante-agrupacion-geoespacial/">Localización de varios almacenes mediante agrupación geoespacial</a> se publicó primero en <a href="https://ingenieriaindustrialonline.com">Ingenieria Industrial Online</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ingenieriaindustrialonline.com/localizacion-de-instalaciones/localizacion-de-varios-almacenes-mediante-agrupacion-geoespacial/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Mapas de calor y Algoritmo de Centro de Gravedad utilizando Python</title>
		<link>https://ingenieriaindustrialonline.com/localizacion-de-instalaciones/mapas-de-calor-y-algoritmo-de-centro-de-gravedad-utilizando-python/</link>
					<comments>https://ingenieriaindustrialonline.com/localizacion-de-instalaciones/mapas-de-calor-y-algoritmo-de-centro-de-gravedad-utilizando-python/#comments</comments>
		
		<dc:creator><![CDATA[Bryan Salazar López]]></dc:creator>
		<pubDate>Wed, 13 Oct 2021 04:14:19 +0000</pubDate>
				<category><![CDATA[Actualidad]]></category>
		<category><![CDATA[Análisis de datos]]></category>
		<category><![CDATA[Diseño y distribución en planta]]></category>
		<category><![CDATA[Gestión de almacenes]]></category>
		<category><![CDATA[Localización de instalaciones]]></category>
		<category><![CDATA[Logística]]></category>
		<category><![CDATA[Centro de masa]]></category>
		<category><![CDATA[Localización]]></category>
		<category><![CDATA[Localización de plantas]]></category>
		<category><![CDATA[Mapa de calor]]></category>
		<category><![CDATA[Mapas de calor]]></category>
		<category><![CDATA[Método del Centro de gravedad]]></category>
		<category><![CDATA[Métodos de localización]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">https://ingenieriaindustrialonline.com/?p=28400</guid>

					<description><![CDATA[<p>Ya en artículos anteriores hemos abordado el uso de tecnología como herramienta que permita desarrollar problemas de análisis preliminar y localización de instalaciones, con el objetivo de incrementar el nivel de aplicabilidad de estas herramientas, utilizando algunos entornos de programación, algunos sistemas de información geográfica, librerías de geocodificación; etc., que nos facilitan la adopción de &#8230;</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/localizacion-de-instalaciones/mapas-de-calor-y-algoritmo-de-centro-de-gravedad-utilizando-python/">Mapas de calor y Algoritmo de Centro de Gravedad utilizando 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>Ya en artículos anteriores hemos abordado el uso de tecnología como herramienta que permita desarrollar problemas de análisis preliminar y localización de instalaciones, con el objetivo de incrementar el nivel de aplicabilidad de estas herramientas, utilizando algunos entornos de programación, algunos sistemas de información geográfica, librerías de geocodificación; etc., que nos facilitan la adopción de soluciones basadas en entornos reales.</p>
<p>Algunos de los artículos que hemos desarrollado al respecto son:</p>

		<div class="checklist tie-list-shortcode">
<ul>
<li><a href="https://ingenieriaindustrialonline.com/diseno-y-distribucion-en-planta/metodo-de-localizacion-de-instalaciones-utilizando-mapas-de-calor/" target="_blank" rel="noopener"><strong>Mapas de calor utilizando Google Maps (Javascript)</strong></a></li>
<li><a href="https://ingenieriaindustrialonline.com/localizacion-de-instalaciones/metodo-del-centro-de-gravedad-utilizando-r/" target="_blank" rel="noopener"><strong>Método de Centro de Gravedad utilizando R</strong></a></li>
</ul>

		</div>
	
<p>En estos artículos mencionamos que los mapas de calor aplicados a la localización de instalaciones, <strong>son capas de visualización</strong> que no nos proporcionan como resultado una localización específica; <strong>sí nos proporcionan una visión de densidad basada en un factor de ponderación</strong> establecido (Peso). Sin embargo, al utilizar mapas de calor en entornos como por ejemplo <em>Python, </em>podemos integrar a esta herramienta, un método heurístico que nos proporcione una localización específica, como por ejemplo el <a href="https://ingenieriaindustrialonline.com/localizacion-de-instalaciones/metodo-del-centro-de-gravedad-utilizando-r/" target="_blank" rel="noopener"><strong>Centro de Gravedad</strong></a>.</p>
<p>El objetivo de este artículo será el de utilizar mapas de calor y el algoritmo de Centro de gravedad de manera simultánea a través de <em>Python</em>; como herramienta de análisis preliminar y de localización de una instalación.</p>
<p>En el desarrollo de este ejercicio emplearemos:</p>

		<div class="plus tie-list-shortcode">
<ul>
<li><em><strong>Colaboratory</strong>: </em>Este es un entorno de programación y ejecución virtual de Python desarrollado por Google. Nos permitirá no tener la necesidad de realizar ninguna instalación en nuestros equipos. Todo lo que desarrollemos lo ejecutaremos en un cuaderno virtual.</li>
<li><strong><em>Python</em></strong>: Este será el lenguaje de programación que vamos a utilizar, y advertimos: No es necesario tener conocimientos previos, y el objetivo del artículo no es convertirnos en programadores expertos. Utilizaremos fragmentos de códigos, librerías disponibles, y explicaremos lo necesario para configurar nuestro desarrollo de acuerdo a los objetivos específicos de nuestros modelos.</li>
<li><strong><em>Geopy</em></strong>: Las librerías son a <em>Python</em>, lo que las <em>apps </em>son a un teléfono celular. Esta es quizá una de las características más a tractivas de este lenguaje: Casi que existe una librería para cada necesidad. En este caso, <em>Geopy</em>, es una librería que nos permitirá geocodificar un conjunto de ubicaciones. Es decir, a partir de un listado de ciudades o direcciones, poder obtener sus coordenadas de latitud y longitud que nos permitan georeferenciar dichas ubicaciones.</li>
<li><em><strong>Statistics</strong>: </em>Esta es una librería con un conjunto de herramientas estadísticas que nos permitirán hallar algunas medidas centrales como soporte de los modelos.</li>
<li><em><strong>Folium</strong>: </em>Esta librería nos permitirá graficar sobre un sistema de geolocalización, emplear la capa de mapas de calor y georeferenciar el centro de gravedad del modelo.</li>
<li><strong><em>Pandas</em></strong>: <span>Es un paquete de Python que proporciona estructuras de datos rápidas, y flexibles, diseñadas para que el trabajo con datos estructurados (tabulares, multidimensionales, potencialmente heterogéneos) y de series de tiempo sea fácil e intuitivo.</span></li>
<li><em><strong>Numpy</strong>: </em>Es una librería que nos permitirá efectuar operaciones matriciales en Python.</li>
</ul>

		</div>
	
<hr />
<p>Para desarrollar estas herramientas, vamos a plantear un caso típico de localización de una instalación (por ejemplo un depósito) a partir de la consideración de otras instalaciones (nodos de demanda, por ejemplo).</p>
<h2>Caso de aplicación</h2>

		<div id="caso-de-aplicacion" data-title="Caso de aplicación" class="index-title"></div>
	
<blockquote class=" quote-simple "><p>La empresa Bio-Food está desarrollando un nuevo modelo de negocio en la ciudad de Cali, Colombia. Este consiste en abastecer de comida saludable a la comunidad por medio de Vending Machines (Máquinas expendedoras). En las etapas de formulación de negocio, algo quedó muy claro: El éxito de su modelo consiste en maximizar la disponibilidad de todos los SKUs en cantidades suficientes. Algunas de las referencias son productos perecederos, de manera que consideran que algunos de sus equipos requerirán visitas diarias de reposición, y otros quizá sean surtidos en más de dos ocasiones por día.</p></blockquote>
<blockquote class=" quote-simple "><p>La fase inicial de su proyecto consideró la instalación de 13 equipos expendedores en 13 instituciones de educación superior de la ciudad. La logística inicial de su proyecto fue caótica (en fase piloto), algunos equipos funcionaron como sub-bodegas; algunos equipos fueron abastecidos directamente por los proveedores; y consideran la instalación de una bodega principal desde la cual serán abastecidas todas las máquinas que tienen disponibles.</p></blockquote>
<blockquote class=" quote-simple "><p>La fase inicial del proyecto arrojó información alrededor del volumen de ventas de cada equipo. Por esta razón, el departamento de logística considera utilizar esta información para efectuar un análisis preliminar y establecer la localización de la bodega principal. A continuación, se relacionan los movimientos de los equipos (media de unidades vendidas por día):</p></blockquote>
<table width="664">
<tbody>
<tr>
<td width="80" style="text-align: center;"><strong>Máquina</strong></td>
<td width="459" style="text-align: center;"><strong>Institución / Lugar</strong></td>
<td width="125" style="text-align: center;"><strong>Unidades vendidas</strong></td>
</tr>
<tr>
<td style="text-align: center;">1</td>
<td style="text-align: center;">PONTIFICIA UNIVERSIDAD JAVERIANA</td>
<td style="text-align: center;">1800</td>
</tr>
<tr>
<td style="text-align: center;">2</td>
<td style="text-align: center;">UNIVERSIDAD DEL VALLE</td>
<td style="text-align: center;">1650</td>
</tr>
<tr>
<td style="text-align: center;">3</td>
<td style="text-align: center;">UNIVERSIDAD SAN BUENAVENTURA</td>
<td style="text-align: center;">1110</td>
</tr>
<tr>
<td style="text-align: center;">4</td>
<td style="text-align: center;">UNIVERSIDAD ICESI</td>
<td style="text-align: center;">1540</td>
</tr>
<tr>
<td style="text-align: center;">5</td>
<td style="text-align: center;">UNIVERSIDAD SANTIAGO DE CALI</td>
<td style="text-align: center;">820</td>
</tr>
<tr>
<td style="text-align: center;">6</td>
<td style="text-align: center;">UNIVERSIDAD AUTÓNOMA DE OCCIDENTE</td>
<td style="text-align: center;">1020</td>
</tr>
<tr>
<td style="text-align: center;">7</td>
<td style="text-align: center;">UNIVERSIDAD COOPERATIVA DE COLOMBIA</td>
<td style="text-align: center;">635</td>
</tr>
<tr>
<td style="text-align: center;">8</td>
<td style="text-align: center;">FUNDACIÓN UNIVERSITARIA SAN MARTÍN</td>
<td style="text-align: center;">420</td>
</tr>
<tr>
<td style="text-align: center;">9</td>
<td style="text-align: center;">UNIVERSIDAD LIBRE</td>
<td style="text-align: center;">569</td>
</tr>
<tr>
<td style="text-align: center;">10</td>
<td style="text-align: center;">UNIVERSIDAD ANTONIO NARIÑO</td>
<td style="text-align: center;">350</td>
</tr>
<tr>
<td style="text-align: center;">11</td>
<td style="text-align: center;">UNICATOLICA &#8211; FUNDACION UNIVERSITARIA CATÓLICA LUMEN GENTIUM</td>
<td style="text-align: center;">620</td>
</tr>
<tr>
<td style="text-align: center;">12</td>
<td style="text-align: center;">CECEP</td>
<td style="text-align: center;">800</td>
</tr>
<tr>
<td style="text-align: center;">13</td>
<td style="text-align: center;">UNIVERSIDAD OBRERA</td>
<td style="text-align: center;">250</td>
</tr>
</tbody>
</table>
<hr />
<p>Utilizar el algoritmo de Centro de Gravedad puede servir como referencia para establecer una ubicación tentativa. Sin embargo, las posibilidades de que las coordenadas solución correspondan con un espacio disponible para la ubicación de la instalación son, de verdad, muy pocas.</p>
<p>Por esta razón, es interesante complementar este modelo mediante una capa de visualización de mapas de calor, que consideren la densidad del volumen de ventas de los equipos. De esta manera, puede complementarse el análisis preliminar para la localización de la bodega principal.</p>
<hr />
<h3>Paso 1: Crear el entorno de trabajo en Colaboratory</h3>

		<div id="paso-1-crear-el-entorno-de-trabajo-en-colaboratory" data-title="Paso 1: Crear el entorno de trabajo en Colaboratory" class="index-title"></div>
	
<p><span>Lo primero que vamos a hacer consiste en crear un entorno de trabajo en <em>Google</em> </span><em>Colaboratory</em><span>, así que vayamos allá: </span><a href="https://colab.research.google.com/#create=true" target="_blank" rel="noopener"><em><strong>Abrir cuaderno nuevo</strong></em></a><span>.</span></p>
<p>Verán que tienen un lienzo para programar el modelo, así que en este cuaderno podemos ir generando las líneas de código que explicaremos en los pasos siguientes.</p>
<h3>Paso 2: Importar las librerías necesarias</h3>

		<div id="paso-2-importar-las-librerias-necesarias" data-title="Paso 2: Importar las librerías necesarias" class="index-title"></div>
	
<p>Respecto a las librerías, en la introducción del artículo hicimos una descripción de la funcionalidad de cada una, veamos como importarlas en nuestro entorno:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code># importar las librerías necesarias
import pandas as pd
import numpy as np
import folium
import statistics
from folium.plugins import HeatMap
import geopy
from geopy.extra.rate_limiter import RateLimiter</code></pre>
</div>
<p>De esta manera, tenemos todo lo necesario para empezar a desarrollar nuestro código.</p>
<h3>Paso 3: Importar los datos desde Excel</h3>

		<div id="paso-3-importar-los-datos-desde-excel" data-title="Paso 3: Importar los datos desde Excel" class="index-title"></div>
	
<p>De acuerdo a las necesidades del modelo, podemos desarrollar un código que permita la entrada manual de la información, la captura de los datos desde entornos digitales (Internet, por ejemplo), o podemos, desde luego, alimentar nuestro modelo con información contenida en documentos externos, como es el caso de un archivo de Microsoft Excel.</p>
<p>Esta puede considerarse como una de las ventajas de utilizar <em>Python, </em>su capacidad de integrarse con cualquier fuente de datos. En nuestro caso, toda la información se encuentra contenida en un documento de Excel, el cual presenta el siguiente formato:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/datos.png" alt="datos" width="730" height="241" class="wp-image-28403 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/datos.png 853w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/datos-300x99.png 300w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/datos-768x253.png 768w" sizes="(max-width: 730px) 100vw, 730px" /></p>

		<div class="box download  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>Puedes descargar el documento de Excel que utilizamos en este ejemplo: <a href="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/vending_machines-1.xlsx" target="_blank" rel="noopener"><strong>Base de datos</strong></a>
			</div>
		</div>
	
<p>En <em>Colaboratory</em>, el siguiente fragmento permitirá cargar un archivo al entorno de ejecución:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>from google.colab import files

uploaded = files.upload()

for fn in uploaded.keys():
  print('User uploaded file "{name}" with length {length} bytes'.format(
      name=fn, length=len(uploaded[fn])))</code></pre>
</div>
<p>Al ejecutar este fragmento de código, se abrirá una ventana emergente del explorador que permitirá cargar nuestra base de datos, en nuestro caso el archivo tienen el nombre de <em>vending_machines.xlsx.</em></p>
<p>La siguiente línea de código permitirá almacenar los datos contenidos en el documento en un <em>Dataframe</em> de nuestro entorno, dentro de la variable <em>data</em>.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>#Leer el documento de Excel y almacenar los datos en la variable data
data = pd.read_excel('vending_machines.xlsx')</code></pre>
</div>
<h3>Paso 4: Geocodificar las ubicaciones</h3>

		<div id="paso-4-geocodificar-las-ubicaciones" data-title="Paso 4: Geocodificar las ubicaciones" class="index-title"></div>
	
<p>Nosotros podemos partir desde la disponibilidad de las coordenadas geográficas de los puntos disponibles (Equipos expendedores). En cuyo caso, geocodificar las ubicaciones no sería necesario. Sin embargo, en nuestro ejemplo, disponemos del nombre de cada institución donde se encuentran ubicados los equipos, así como la ciudad y el país (todos los equipos se encuentran en la misma ciudad); y es necesario geocodificar estos puntos para obtener las coordenadas de latitud y longitud de cada ubicación.</p>
<p>Para lograrlo, utilizaremos el servicio de la librería <em>Geopy (Llamado Nominatim)</em>, el cual puede geocodificar nuestras ubicaciones. El servicio funciona de una manera sencilla, recibe una cadena con la información de nuestra ubicación, por ejemplo: ciudad, país, nombre del lugar; y devuelve las coordenadas de latitud y longitud asociadas a cada cadena.</p>
<p>Las siguientes líneas en primer lugar construyen cada cadena por punto (dirección), es decir, concatenan los datos (país, ciudad y nombre del lugar), y luego son geocodificados por <em>Geopy</em>. Veamos:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code># fusionamos los datos país, ciudad y lugar en una misma cadena de dirección
geopy.geocoders.options.default_user_agent = "my-application"
data["direccion"] = data["pais"] + ", " + data["ciudad"] + ", " + data["Institución / Lugar"]
#Envíamos los datos a geocodificación
servicio = geopy.Nominatim()
data["coordenadas"] = data["direccion"].apply(RateLimiter(servicio.geocode,min_delay_seconds=1))</code></pre>
</div>
<p>Pueden apreciar que el código establece que tanto las cadenas con las direcciones concatenadas, como las respuestas en manera de coordenadas, queden dentro del mismo <em>DataFrame </em>donde se encuentran los datos de entrada del modelo. Podemos en cualquier momento confirmar si la geocodificación se ha realizado correctamente, para eso imprimiremos las primeras cinco filas del  <em>DataFrame:</em></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>data.head()</code></pre>
</div>
<p>Al ejecutar esta instrucción tenemos la siguiente salida:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/head.png" alt="head" width="1300" height="185" class="alignnone size-full wp-image-28405" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/head.png 1300w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/head-300x43.png 300w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/head-1024x146.png 1024w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/head-768x109.png 768w" sizes="(max-width: 1300px) 100vw, 1300px" /></p>
<p>Podemos observar cómo bajo la columna &#8216;<em>direccion&#8217; </em>se han concatenado las columnas <em>&#8216;pais&#8217;, &#8216;ciudad&#8217; e &#8216;Institución / Lugar&#8217;</em>, tal como lo establecimos previamente. Así mismo, podemos observar la respuesta de <em>Geopy </em> bajo la columna <em>&#8216;coordenadas&#8217;</em>.</p>
<h3>Paso 5: Calcular el Centro de Gravedad</h3>

		<div id="paso-5-calcular-el-centro-de-gravedad" data-title="Paso 5: Calcular el Centro de Gravedad" class="index-title"></div>
	
<p>El algoritmo de <a href="https://ingenieriaindustrialonline.com/diseno-y-distribucion-en-planta/metodo-del-centro-de-gravedad/" target="_blank" rel="noopener"><strong>Centro de Gravedad</strong></a> es relativamente sencillo, mucho más cuando se cuenta con los datos debidamente organizados. Las operaciones son sencillas, y en <em>Python</em>, se pueden desarrollar fácilmente mediante productos de matrices.</p>
<p>Ahora bien, la base del algoritmo son las coordenadas. En la respuesta obtenida desde <em>Geopy</em>, que se encuentra contenida en la columna <em>&#8216;coordenadas&#8217;</em> del <em>DataFrame &#8216;data&#8217;, </em>hay información adicional a las coordenadas necesarias. De hecho el servicio nos devuelve un nombre del lugar, una subregión, puede mostrarnos alguna nomenclatura y claro está, las coordenadas de latitud y longitud. Por tal razón, lo primero que debemos hacer es extraer las coordenadas de latitud y longitud, para eso utilizaremos las siguientes líneas:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code># Extraer las coordenadas de latitud y longitud en dos variables separadas (listas)
longs = [coord.longitude for coord in data["coordenadas"]]
lats = [coord.latitude for coord in data["coordenadas"]]</code></pre>
</div>
<p>Una vez que tengamos las coordenadas de todos los puntos en un par de variables separadas, procedemos a crear nuestro algoritmo de centro de gravedad:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>centro_gravedad = {}
centro_gravedad['longs'] = np.dot(longs, data['Unidades vendidas']) / np.sum(data['Unidades vendidas'])
centro_gravedad['lats'] = np.dot(lats, data['Unidades vendidas']) / np.sum(data['Unidades vendidas'])</code></pre>
</div>
<p>De esta manera, dentro del arreglo <em>&#8216;centro_gravedad&#8217; </em>deberán quedar las coordenadas solución. Recordemos que este algoritmo utiliza puntos ponderados, en este caso el peso que determina la ponderación está dado por el volumen de ventas de cada equipo (<em>&#8216;Unidades vendidas&#8217;</em>).</p>
<p>Podemos ver el resultado, imprimiendo la variable <em>&#8216;centro_gravedad&#8217;:</em></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>print(centro_gravedad)</code></pre>
</div>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centro_gravedad.png" alt="centro_gravedad" width="618" height="85" class="size-full wp-image-28406 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centro_gravedad.png 618w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centro_gravedad-300x41.png 300w" sizes="(max-width: 618px) 100vw, 618px" /></p>
<p>Estas son las coordenadas solución del método de Centro de Gravedad. Sin embargo, recordemos que debemos complementar el desarrollo del modelo mediante un mapa de calor.</p>
<h3>Paso 6: Graficar la capa del mapa de calor y el marcador de Centro de Gravedad</h3>

		<div id="paso-6-graficar-la-capa-del-mapa-de-calor-y-el-marcador-de-centro-de-gravedad" data-title="Paso 6: Graficar la capa del mapa de calor y el marcador de Centro de Gravedad" class="index-title"></div>
	
<p>En este caso utilizaremos la librería <em>Folium </em>para ambos fines: la capa del mapa de calor, y el marcador de Centro de Gravedad.</p>
<p>Lo primero que haremos será calcular la media de las latitudes y las longitudes para centrar el mapa que obtendremos.</p>
<p>Lo segundo que haremos será crear nuestro mapa, el cual configuraremos con las medidas centrales y un zoom inicial que podemos modificar de acuerdo a nuestras necesidades.</p>
<p>Lo tercero que haremos será crear nuestra capa de mapa de calor, utilizaremos como peso las <em>&#8216;Unidades vendidas&#8217;</em> para ponderar cada punto del mapa (Vending Machines). Configuramos algunos parámetros a nuestro criterio como la <em>opacidad, la intensidad, el radio de cada punto</em>.</p>
<p>Por último crearemos el marcador de Centro de Gravedad, para ello utilizaremos las coordenadas solución que hallamos en el paso anterior.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code># Calcular la media de las latitudes y las longitudes para centrar el mapa
mediaLong = statistics.mean(longs)
mediaLat = statistics.mean(lats)

# Crear un objeto de mapa base Map()
mapa = folium.Map(location=[mediaLat, mediaLong], zoom_start = 12)

# Crear una capa de mapa de calor
mapa_calor = HeatMap( list(zip(lats, longs, data["Unidades vendidas"])),
                   min_opacity=0.2,
                   max_val=data["Unidades vendidas"].max(),
                   radius=50, 
                   blur=50, 
                   max_zoom=1)

#Creamos el marcador de Centro de Gravedad
tooltip = 'Centro de gravedad'
folium.Marker([centro_gravedad['lats'], centro_gravedad['longs']], popup="Centro", tooltip = tooltip).add_to(mapa)

# Adherimos la capa de mapa de calor al mapa principal
mapa_calor.add_to(mapa)
mapa</code></pre>
</div>
<p>Al ejecutar estas líneas tendremos el siguiente resultado:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centro_gravedad_mapa_calor.png" alt="centro_gravedad_mapa_calor" width="1404" height="760" class="alignnone size-full wp-image-28407" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centro_gravedad_mapa_calor.png 1404w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centro_gravedad_mapa_calor-300x162.png 300w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centro_gravedad_mapa_calor-1024x554.png 1024w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centro_gravedad_mapa_calor-768x416.png 768w" sizes="(max-width: 1404px) 100vw, 1404px" /></p>
<p>Podemos utilizar el zoom para explorar diversas visualizaciones de densidad:</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centro_gravedad_mapa_calor_II.png" alt="centro_gravedad_mapa_calor_II" width="1351" height="747" class="alignnone size-full wp-image-28408" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centro_gravedad_mapa_calor_II.png 1351w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centro_gravedad_mapa_calor_II-300x166.png 300w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centro_gravedad_mapa_calor_II-1024x566.png 1024w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/centro_gravedad_mapa_calor_II-768x425.png 768w" sizes="(max-width: 1351px) 100vw, 1351px" /></p>
<p>El código completo de este desarrollo lo puedes encontrar en nuestro cuaderno: <a href="https://colab.research.google.com/drive/1CWCVFeh6NibQGTg62zF0lg1A9Qow0rld?usp=sharing" target="_blank" rel="noopener"><em><strong>Mapas de Calor y Centro de Gravedad</strong></em></a>.</p>
<hr />
<p>En este caso, y a diferencia del artículo <em><strong><a href="https://ingenieriaindustrialonline.com/diseno-y-distribucion-en-planta/metodo-de-localizacion-de-instalaciones-utilizando-mapas-de-calor/" target="_blank" rel="noopener">mapas de calor utilizando Google Maps</a>, </strong></em>empleamos una capa de visualización de densidad de cada punto, y simultáneamente identificamos unas coordenadas solución de una localización de acuerdo al modelo de Centro de Gravedad (Centro de masa). De esta forma, construimos una herramienta un poco más robusta que permite soportar los procesos de análisis preliminar de localización de instalaciones, ambientada en un entorno geográfico real.</p>
<p>Así mismo, en el desarrollo de la herramienta empleamos algunas instrucciones que nos permiten automatizar procesos de georeferenciación, y de uso de datos a partir de fuentes diversas.</p>
<hr />
<p><span>El alcance de este modelo se encuentra determinado por la localización de una sola instalación (depósito, almacén, etc.), y en los casos en los que se requiera determinar múltiples localizaciones, el modelo no aplica.</span></p>

		<div class="box info  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>Para ver un modelo para varias localizaciones: <a href="https://ingenieriaindustrialonline.com/localizacion-de-instalaciones/localizacion-de-varios-almacenes-mediante-agrupacion-geoespacial/"><em><strong>Localización de varios almacenes mediante agrupación espacial</strong></em></a>
			</div>
		</div>
	
<p>La entrada <a href="https://ingenieriaindustrialonline.com/localizacion-de-instalaciones/mapas-de-calor-y-algoritmo-de-centro-de-gravedad-utilizando-python/">Mapas de calor y Algoritmo de Centro de Gravedad utilizando Python</a> se publicó primero en <a href="https://ingenieriaindustrialonline.com">Ingenieria Industrial Online</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ingenieriaindustrialonline.com/localizacion-de-instalaciones/mapas-de-calor-y-algoritmo-de-centro-de-gravedad-utilizando-python/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>¿En qué creen los gerentes?</title>
		<link>https://ingenieriaindustrialonline.com/teoria-de-restricciones/en-que-creen-los-gerentes/</link>
					<comments>https://ingenieriaindustrialonline.com/teoria-de-restricciones/en-que-creen-los-gerentes/#respond</comments>
		
		<dc:creator><![CDATA[Matías Birrell Rodríguez]]></dc:creator>
		<pubDate>Fri, 08 Oct 2021 17:43:02 +0000</pubDate>
				<category><![CDATA[Columnas]]></category>
		<category><![CDATA[Consultoría]]></category>
		<category><![CDATA[Gestión de inventarios]]></category>
		<category><![CDATA[Logística]]></category>
		<category><![CDATA[Producción]]></category>
		<category><![CDATA[Teoría de restricciones (TOC)]]></category>
		<category><![CDATA[Distribución]]></category>
		<category><![CDATA[Entregas]]></category>
		<category><![CDATA[Fill Rate]]></category>
		<category><![CDATA[Fillrate]]></category>
		<category><![CDATA[Inventarios]]></category>
		<category><![CDATA[KPI's]]></category>
		<category><![CDATA[Nivel de servicio]]></category>
		<category><![CDATA[Teoría de Restricciones]]></category>
		<category><![CDATA[TOC]]></category>
		<guid isPermaLink="false">https://ingenieriaindustrialonline.com/?p=28319</guid>

					<description><![CDATA[<p>“¿Un fill rate mayor a 94%? ¡Imposible! No es posible sostenerlo con un costo aceptable”. No es la primera vez y creo que no será la última que escuche este tipo de afirmaciones cuando hablo con gerentes generales. Y es que son personas inteligentes y con experiencia, lo que los ha llevado a tener ciertas &#8230;</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/teoria-de-restricciones/en-que-creen-los-gerentes/">¿En qué creen los gerentes?</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><em>“¿Un fill rate mayor a 94%? ¡Imposible! No es posible sostenerlo con un costo aceptable”.</em></p>
<p><span>No es la primera vez y creo que no será la última que escuche este tipo de afirmaciones cuando hablo con gerentes generales. Y es que son personas inteligentes y con experiencia, lo que los ha llevado a tener ciertas convicciones que les permiten tomar decisiones rápidamente, sin entretener su escaso tiempo en fantasías.</span></p>
<p><em>¿Pero qué es lo que en el pasado ocurrió y lo llevó a tener este convencimiento de que no es posible tener un fill rate cercano a 100% y a la vez que eso sea rentable?</em></p>
<h2><span>¿Qué es fill rate?</span></h2>

		<div id="que-es-fill-rate" data-title="¿Qué es fill rate?" class="index-title"></div>
	
<p><span>Este es un término en inglés de uso habitual en logística para medir el grado de cumplimiento de un pedido. En su expresión más simple y ácida, es el porcentaje de líneas del pedido que se ha logrado satisfacer completamente.</span></p>
<p><span>Claro que, si el pedido tiene solo dos ítems de, digamos 900 unidades del primero y 100 unidades del segundo, y entregamos 800 unidades y 100 respectivamente, con esta definición podríamos tener un <em>fill rate</em> de 50%. Entonces podemos afinar nuestra definición al considerar las cantidades también. Una manera es calcular el <em>fill rate</em> como las unidades entregadas divido por el total. En este caso tendríamos 90%.</span></p>
<p><span>Pero si las 900 unidades representan el 50% en dinero, ahora podríamos hacer otro cálculo que nos dé 94.4%.</span></p>
<p><span>Ya ve que el <em>fill rate</em> es un KPI que puede significar distintas cosas, pero, aun así, ese gerente consideraba imposible sostenerlo sobre 94%.</span></p>
<h2><span>¿Cómo se conforman las decisiones?</span></h2>

		<div id="como-se-conforman-las-decisiones" data-title="¿Cómo se conforman las decisiones?" class="index-title"></div>
	
<p><span>El caso que estoy relatando es el de un fabricante de bienes de consumo que vende su producción a una cadena de suministro, donde hay mayoristas, distribuidores y <a href="https://ingenieriaindustrialonline.com/teoria-de-restricciones-toc/como-mejorar-el-desempeno-del-retail-preguntas-clave/"><em>retail</em></a>.</span></p>
<p><span>En esa compañía, como en muchas otras, los gerentes tienen estudios superiores, y con bastante seguridad aprendieron las técnicas más conocidas de optimización de costos para la gestión de empresas que comercializan bienes de consumo. Entre otras, <strong><a href="https://ingenieriaindustrialonline.com/produccion/balanceo-de-linea/">balancear líneas de producción</a></strong>, usar <strong><a href="https://ingenieriaindustrialonline.com/gestion-de-inventarios/control-de-inventarios/">MIN/MAX</a></strong> y <strong><a href="https://ingenieriaindustrialonline.com/gestion-de-inventarios/cantidad-economica-de-pedidos-eoq/">EOQ</a></strong>, y cálculo de costos unitarios con las últimas técnicas de ABC (costeo basado en actividades).</span></p>
<p><span>Cuando uno usa esas técnicas, el resultado inevitable es que la capacidad apenas alcanza para satisfacer la demanda y se acumula mucho inventario. El inventario acumulado utiliza dos recursos fundamentales: espacio en bodega y capital de trabajo. Cuando hay mucho inventario, ambos recursos están a su límite, por lo que sugerir incrementar el inventario inmediatamente incrementa el costo de la operación.</span></p>
<p><span><em>¿Y eso qué tiene que ver con el fill rate?</em>, dirá usted.</span></p>
<p><span>Veamos, si hay mucho inventario acumulado, necesariamente eso representa más días de venta. Es decir, la programación de producción debe considerar un horizonte de venta más lejano en el futuro, por lo que cada vez más depende de la exactitud del <a href="https://ingenieriaindustrialonline.com/teoria-de-restricciones-toc/por-que-salen-mal-los-pronosticos/"><strong>pronóstico</strong></a>. <strong>Lo único que sabemos con certeza acerca del pronóstico es que está equivocado</strong>, por lo que esos planes de producción van a terminar con algunos ítems agotados, lo que redunda en un <em>fill rate</em> menor.</span></p>
<blockquote class=" quote-simple "><p>Lo único que sabemos con certeza acerca del pronóstico es que está equivocado</p></blockquote>
<p><span>Pero es peor todavía: cada vez que a un pedido le falta un ítem, hay reprogramaciones de producción, lo que desperdicia capacidad y ahora debemos pagar un costo mayor para lograr todo el plan de producción.</span></p>
<h2><span>¿Y los gerentes no se dan cuenta de todo este círculo vicioso?</span></h2>

		<div id="y-los-gerentes-no-se-dan-cuenta-de-todo-este-circulo-vicioso" data-title="¿Y los gerentes no se dan cuenta de todo este círculo vicioso?" class="index-title"></div>
	
<p><span>Es más fácil preguntarlo que responderlo. <em>¿Cómo pueden saber que eso es un círculo vicioso?</em> O mejor, <em>¿cómo podrían saber que no están optimizando la operación?</em> Después de todo están siguiendo las “<em>mejores prácticas</em>” y aplicando principios básicos que se enseñan hasta el día de hoy en universidades muy prestigiosas.</span></p>
<p><span>Y además son conceptos practicados por muchos otros en la industria.</span></p>
<p><span>Después de varios años optimizando, en esa empresa han logrado 94% como un máximo realista y sostenible. Cada vez que intentaron mejorarlo, manteniendo las optimizaciones productivas, se elevaron tanto los inventarios y aparecieron tantas mermas, que la conclusión lógica es que intentar mejorar el <em>fill rate</em> no es rentable, y no es realista que se lo sugieran después de tanta experiencia que demuestra lo contrario.</span></p>
<h2><span>¿Hay salida?</span></h2>

		<div id="hay-salida" data-title="¿Hay salida?" class="index-title"></div>
	
<p><span>Esta es una pregunta que hace alguien inconformista. Alguien que no acepta el <a data-toggle="tooltip" data-placement="top" class="post-tooltip tooltip-top" title="un equilibrio logrado entre dos características deseables pero incompatibles; un compromiso."><em>trade off</em></a> entre <em>fill rate</em> y costo. El <a href="https://ingenieriaindustrialonline.com/teoria-de-restricciones-toc/la-meta-y-las-3-lecciones-inmortales-de-eli-goldratt/">Dr. Goldratt</a> me enseñó que no acepte las <a href="https://ingenieriaindustrialonline.com/teoria-de-restricciones-toc/dilemas-en-la-toma-de-decisiones-contradicciones/">contradicciones</a>; que un científico debe pensar hasta lograr eliminarlas. También Genrich Altshuller pensaba así, poniendo como base de TRIZ el convencimiento de que un invento surge de eliminar una contradicción técnica.</span></p>
<p><span>Me remito a dos artículos anteriores para ver cómo se invalidan algunos de los conceptos básicos que siguen usando los gerentes. Vea <a href="https://ingenieriaindustrialonline.com/consultoria/refutacion-al-balanceo-de-lineas/"><strong>Refutación al balanceo de líneas</strong></a> y <a href="https://ingenieriaindustrialonline.com/consultoria/la-falacia-del-min-max-y-eoq/"><strong>La Falacia de MIN/MAX y EOQ</strong></a> para saber por qué esos conceptos están equivocados.</span></p>
<p><span>En general, el gran problema actual en la gestión de empresas es desconocer el <a href="https://ingenieriaindustrialonline.com/teoria-de-restricciones-toc/las-empresas-como-un-sistema-un-todo-indivisible/"><strong>carácter sistémico de las organizaciones</strong></a>. Estos ejemplos presentados aquí son solo una muestra.</span></p>
<p><span>La salida al problema del <em>fill rate</em> sub óptimo es cuestionar los conceptos que dan origen a las decisiones diarias de la fábrica y de la cadena de suministro. Al abandonar esas “<em>creencias</em>”, se debe adoptar otro conjunto de políticas. Afortunadamente ya hemos recorrido ese camino, y conocemos cuáles son los nuevos conceptos y las nuevas políticas. Y hemos visto a cientos de empresas (tal vez miles) que en los últimos 30 años han logrado un <em>fill rate</em> cercano al 100% junto con reducir costos e inventarios.</span></p>
<h2><span>¿Por qué es lenta la adopción del pensamiento sistémico?</span></h2>

		<div id="por-que-es-lenta-la-adopcion-del-pensamiento-sistemico" data-title="¿Por qué es lenta la adopción del pensamiento sistémico?" class="index-title"></div>
	
<p><span>Russell Ackoff respondió esta pregunta hace varios años en un artículo corto. Y dio dos razones, una general y una específica.</span></p>
<p><span><strong>La razón general tiene que ver con la educación prevaleciente, donde los errores se castigan, desde el colegio, pasando por la universidad, y hasta en el trabajo</strong>. Y la manera más segura de minimizar la cantidad de errores es minimizar la cantidad de oportunidades de cometerlos. Al menos esa es una de las estrategias. Por lo tanto, el instinto de supervivencia y la poca urgencia de hacer algo nuevo lleva a la mayoría de las personas a evitar cambios profundos. Y adoptar el pensamiento sistémico, también en palabras del Dr. Ackoff, es un cambio de era: son tan profundos y numerosos los paradigmas que deben cambiar, que equivale a cambiarle el conjunto de creencias compartidas a un gran grupo de personas; es un cambio de su visión del mundo.</span></p>
<p><span><em>¿Para qué “arriesgarse” con algo que contradice la corriente principal?</em> Es defendible hasta cierto punto esta posición.</span></p>
<p><span>La razón específica tiene relación con el pensamiento sistémico mismo, donde los expertos se reúnen en conferencias para presentar sus investigaciones y casos en una jerga casi hermética al resto.</span></p>
<p><span>Yo estoy más de acuerdo con lo primero que lo segundo, aunque es verdad que a veces la jerga técnica espanta, pero no puede ser la razón principal.</span></p>
<h2><span>Temores que bloquean</span></h2>

		<div id="temores-que-bloquean" data-title="Temores que bloquean" class="index-title"></div>
	
<p><span>Antes de su partida, el Dr. Goldratt dejó escrito un prefacio al libro que no pudo escribir acerca de la ciencia de la gerencia. En ese prefacio habla de tres temores que provocan comportamientos en muchos gerentes. Depende del gerente el grado en que le afecte cada uno.</span></p>

		<div class="lightbulb tie-list-shortcode">
<ul>
<li><span>El primero es el <strong>temor a la complejidad</strong>. La consecuencia es que el gerente divide el sistema en partes pensando que es más simple administrar cada una por separado.</span></li>
<li><span>El segundo es el <strong>temor a la incertidumbre</strong>, por lo que el gerente busca tener control a un mayor nivel de detalle, pensando que así puede lidiar mejor con la variabilidad.</span></li>
<li><span>El tercero es el <strong>temor a los conflictos</strong>, donde el gerente busca una solución amistosa a los numerosos conflictos que surgen en la empresa, lo que en la práctica se traduce en transigencias.</span></li>
</ul>

		</div>
	
<h2><span>Conclusión</span></h2>

		<div id="conclusion" data-title="Conclusión" class="index-title"></div>
	
<p><span>Con una experiencia laboral muy compleja, donde nunca ha experimentado lo que significa eliminar los conflictos y manejar de modo simple un sistema complejo, donde la incertidumbre solo crece e incrementa la complejidad del sistema, el gerente se aferra a las pocas certezas que tiene, esas que adquirió en sus estudios, como si fueran dogmas. </span></p>
<p><span>Invito a todos los lectores a revisar sus propias creencias, al menos en administración de empresas, y confiar más en su capacidad de razonamiento. Tendrá sorpresas agradables.</span></p>
<hr />

		<div class="clearfix"></div>
		<div class="about-author about-author-box container-wrapper">
			<div class="author-avatar">
				<img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/avatars/940/60e72e2d7b452-bpfull.jpg" alt="">
			</div>
			<div class="author-info">
				<h4><strong>Matías Birrell Rodríguez</strong></h4>De profesión, ingeniero civil de industrias, con mención en mecánica, con un MBA en finanzas. Pero principalmente, experto en Teoría de Restricciones y autor de libros acerca de este tema, habiendo trabajado y aprendido directamente con el Dr. Goldratt en Goldratt Group. Adicionalmente es director de <strong><a href="http://www.goldfish.cl">www.goldfish.cl</a></strong>, empresa que ofrece aplicaciones en la nube, simples y asequibles, para aplicar estos conceptos a las decisiones diarias. <a href="https://otif100.com"><strong>OTIF100</strong></a> (manufactura), <a href="https://fillrate100.com"><strong>Fill Rate 100</strong></a> (cadena de suministro).</p>
<p style="text-align: center;"><a href="https://goldfish.cl/" target="_blank" class="shortc-button small black">¿Quieres optimizar tus procesos? Contáctame</a>

			</div>
		</div>
	
<p>La entrada <a href="https://ingenieriaindustrialonline.com/teoria-de-restricciones/en-que-creen-los-gerentes/">¿En qué creen los gerentes?</a> se publicó primero en <a href="https://ingenieriaindustrialonline.com">Ingenieria Industrial Online</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ingenieriaindustrialonline.com/teoria-de-restricciones/en-que-creen-los-gerentes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>¿Qué son los gemelos digitales? Aplicaciones en la Industria</title>
		<link>https://ingenieriaindustrialonline.com/transformacion-digital/que-son-los-gemelos-digitales-aplicaciones-en-la-industria/</link>
					<comments>https://ingenieriaindustrialonline.com/transformacion-digital/que-son-los-gemelos-digitales-aplicaciones-en-la-industria/#respond</comments>
		
		<dc:creator><![CDATA[Bryan Salazar López]]></dc:creator>
		<pubDate>Wed, 06 Oct 2021 23:26:47 +0000</pubDate>
				<category><![CDATA[Actualidad]]></category>
		<category><![CDATA[Análisis de datos]]></category>
		<category><![CDATA[Automatización]]></category>
		<category><![CDATA[Industria 4.0]]></category>
		<category><![CDATA[Inteligencia artificial]]></category>
		<category><![CDATA[Logística]]></category>
		<category><![CDATA[Transformación digital]]></category>
		<category><![CDATA[Big data]]></category>
		<category><![CDATA[Gemelos digitales]]></category>
		<category><![CDATA[IIoT]]></category>
		<category><![CDATA[IoT]]></category>
		<guid isPermaLink="false">https://ingenieriaindustrialonline.com/?p=28281</guid>

					<description><![CDATA[<p>Los principales impulsores de lo que denominamos Industria 4.0 son sin duda la conectividad y el desarrollo vertiginoso de las tecnologías de la información. Uno de los principales factores que nos traen hasta aquí es la incorporación – cada vez mayor – de sensores. La capacidad de integrar sensores a casi cualquier dispositivo hace que &#8230;</p>
<p>La entrada <a href="https://ingenieriaindustrialonline.com/transformacion-digital/que-son-los-gemelos-digitales-aplicaciones-en-la-industria/">¿Qué son los gemelos digitales? Aplicaciones en la Industria</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>Los principales impulsores de lo que denominamos <a href="https://ingenieriaindustrialonline.com/industria-4-0/de-que-se-trata-todo-esto-de-industria-40/"><strong>Industria 4.0</strong></a> son sin duda la <strong>conectividad</strong> y el desarrollo vertiginoso de las <strong>tecnologías de la información</strong>. Uno de los principales factores que nos traen hasta aquí es la incorporación – cada vez mayor – de sensores. La capacidad de integrar sensores a casi cualquier dispositivo hace que también aumente la capacidad de recopilar y transmitir datos en tiempo real, para su posterior análisis. El avance de la tecnología de sensores, su diseño cada vez más compacto, sus precios cada vez más bajos, y su capacidad de integración cada vez mayor, hace que su aplicación trascienda del uso en sistemas de producción, e incluso podemos interactuar con ellos día a día en un entorno doméstico; a este fenómeno se le conoce como la <strong>Internet de las Cosas (IoT)</strong> y la <strong>Internet Industrial de las Cosas (IIoT)</strong>.</p>

		<div class="box info  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>IoT no es el único conjunto de tecnologías de conectividad y seguimiento. Más adelante mencionaremos algunas de las tecnologías disponibles.
			</div>
		</div>
	
<p><em>¿Qué logramos a través de la Internet de las Cosas? ¿Cómo puede representar un factor de transformación digital?</em> Básicamente, las proyecciones al año 2021 estiman que cerca de 4.000 millones de personas estén conectadas a Internet; y el siguiente paso implica que no solo las personas, sino las cosas, los procesos, las instalaciones o los negocios en general, puedan conectarse entre sí, formando una red de redes; en este caso, las proyecciones estiman que más de 50 billones de objetos estén conectados a lo que hoy conocemos como Internet (2021).</p>
<p><em>¿Qué evolución estamos viendo en este contexto?</em> En este sentido, considero que estamos siendo testigos de la materialización de muchas de las ideas más disruptivas de los 90s y de los años 2000; tal es el caso de los <strong>gemelos digitales</strong> (<em>digital twins</em>).</p>
<p>&nbsp;</p>
<h2>¿Qué es un gemelo digital (digital twin)?</h2>

		<div id="que-es-un-gemelo-digital-digital-twin" data-title="¿Qué es un gemelo digital (digital twin)?" class="index-title"></div>
	
<p>Un gemelo digital <strong>es una representación virtual computarizada de un objeto</strong> (entidad), una persona, un activo, sistema o un servicio físico. En esencia, un objeto físico transmite la información deseada la cual es procesada y proyectada en un entorno digital, esta información se actualiza periódicamente a través de los datos de sensores, a través de tecnologías de seguimiento, y en teoría, una mayor frecuencia de actualización y una mayor calidad de los datos, mejorará la precisión del modelo digital.</p>
<p>Los gemelos digitales pueden contener y rastrear el contexto histórico de los objetos digitalizados, y esto puede resultar útil para para probar, registrar, reparar determinados comportamientos de la entidad que se duplica digitalmente, e incluso predecir el comportamiento futuro de la misma. Uno de los principales atractivos de los gemelos digitales consiste en la posibilidad de conectar a un objeto físico para recopilar datos en tiempo real de este. El concepto ha existido desde los primeros días de la computación, pero se está volviendo cada vez más importante en el siglo XXI a medida que se desarrollan las tecnologías habilitadoras, como las tecnologías de seguimiento, Big Data y Cloud Computing.</p>
<p>En teoría, los gemelos digitales deberían funcionar exactamente como el objeto o el sistema del mundo real; para lograrlo, debe articular tres conceptos claves: el objeto (la entidad física), la conectividad entre el mundo físico y el mundo digital (mediante sensores, actuadores y controladores) y la simulación (el entorno 3D que sirve como interfaz entre los usuarios y el gemelo digital).</p>

		<div class="box info  ">
			<div class="box-inner-block">
				<span class="fa tie-shortcode-boxicon"></span>La primera introducción formal del concepto de crear una representación virtual de un sistema físico ocurrió en 2002: Los investigadores de la Universidad de Michigan propusieron crear una imagen reflejada computarizada del ciclo de vida real de un producto manufacturado. Su propuesta tenía como objetivo ayudar a los fabricantes a crear productos de una manera más eficiente y rentable. Fuente: Research Starters
			</div>
		</div>
	
<h2>¿Cuáles son las aplicaciones de los gemelos digitales?</h2>

		<div id="cuales-son-las-aplicaciones-de-los-gemelos-digitales" data-title="¿Cuáles son las aplicaciones de los gemelos digitales?" class="index-title"></div>
	
<p>Una organización puede emplear un gemelo digital en múltiples contextos, por ejemplo, es posible obtener una representación virtual de un automóvil, de los ascensores de una unidad residencial, de las bahías de parqueo de un centro comercial, de una planta completa de producción, etc. En este sentido, los gemelos digitales tienen la capacidad potencial de proporcionar formas eficientes de probar cómo funciona cada unidad digitalizada, como un homólogo de la entidad en el mundo real.</p>
<p>Puede considerarse como una evolución de la simulación convencional, toda vez que los parámetros de cada entidad estarían recibiendo información posiblemente en tiempo real de acuerdo a la conectividad establecida: sensores, tecnologías de seguimiento y parámetros de medición.</p>
<p>Una de las principales aplicaciones de los gemelos digitales es la monitorización de productos en busca de fallas, antes de su salida al mercado; en este orden, sería posible predecir problemas, soportar la identificación de soluciones y probar escenarios a través de los entornos digitales.</p>
<p>El alcance de los gemelos digitales guarda directa relación con la naturaleza de los sensores y la capacidad de procesamiento de los datos, y su ámbito de aplicación dependerá del tipo de información que cada dispositivo pueda obtener y procesar de la entidad física. De acuerdo al desarrollo de la industria de sensores, de los procesadores y de la Big Data, los gemelos digitales tienen ámbitos ilimitados de aplicación: Producción, locaciones administrativas, logística, salud, energía, industria aeroespacial, etc.</p>
<h2>¿Qué tecnología de seguimiento utilizan los gemelos digitales?</h2>

		<div id="que-tecnologia-de-seguimiento-utilizan-los-gemelos-digitales" data-title="¿Qué tecnología de seguimiento utilizan los gemelos digitales?" class="index-title"></div>
	
<p>De acuerdo Michal Ukropec (Experto en gemelos digitales), elegir la mejor tecnología de seguimiento es complicado. Existen en el mercado tecnologías como: GPS, BLE, UWB, RFID, WiFi, IoT o cámaras, las cuales no son excluyentes, pero la elección del conjunto de tecnologías dependerá del contexto de aplicación.</p>
<p>Algunas consideraciones que comparte Michal:</p>

		<div class="checklist tie-list-shortcode">
<ul>
<li>Para un posicionamiento general de alta precisión en interiores, UWB puede ser la opción correcta: hay muchas etiquetas disponibles, montables, portátiles. La infraestructura es más costosa, pero básicamente es posible rastrear casi cualquier cosa.</li>
<li>Para auditoría logística interna / externa parece ser la combinación correcta de BLE y GPS. No es tan preciso, pero la instalación es rápida y fácil (no se necesita entrenamiento especial) y el dispositivo inteligente rastreado le permite además de posicionar también la comunicación bidireccional. Muy efectivo, pero, solo puede rastrear dispositivos inteligentes.</li>
<li>Para el seguimiento de materiales de bajo costo puede ser RFID una buena opción. Solo tiene que considerar sus especificaciones exactas, porque en la mayoría de los casos está limitado solo a georreferenciación y, en ocasiones la legibilidad limitada a etiquetas.</li>
<li>Las tecnologías Wi-Fi/IoT son bastante inexactas (precisión de 15 metros aproximadamente), pero si solo necesita saber si la etiqueta está «en la zona <em>X</em>«, puede ser suficiente.</li>
<li>Los rastreadores de IoT pueden ser muy útiles, porque si eliges <em>LoRaWAN</em>, puedes construir tu propia red, y configurarla de acuerdo a tus necesidades. Puedes enviar mensajes cada minuto, no genera costes de funcionamiento, etc. Genial, pero no hay roaming entre proveedores, por lo que, si necesita rastrear algo a nivel de campo puede ser un problema.</li>
<li>Si elige Sigfox, tiene roaming real, pero la cobertura en interiores puede ser más débil, puede enviar mensaje máximo cada 10 minutos y el sensor no tiene retroalimentación si el mensaje ha llegado.</li>
<li>Con NB -IoT tienes muy buena cobertura, confirmación de mensajes, pero no roaming en la mayoría de los casos y precios más altos.</li>
<li>Las cámaras son un tema especial: La Inteligencia Artificial le permite aportar nuevas características a la logística: seguimiento y conteo de materiales.</li>
</ul>

		</div>
	
<h2>Consideraciones al momento de implementar un gemelo digital</h2>

		<div id="consideraciones-al-momento-de-implementar-un-gemelo-digital" data-title=" Consideraciones al momento de implementar un gemelo digital" class="index-title"></div>
	
<p>Consideremos, por ejemplo, la aplicación de un gemelo digital que represente toda la operación de una planta de producción. Los datos alrededor de la operación llegarán quizá en tiempo real, las líneas reportarán rendimientos, movimientos; las máquinas registrarán su grado de utilización, etc. Los datos que anteriormente estaban disponibles en lotes cada 8, 12, 24 horas, ahora estarán disponibles cada minuto. La pregunta que me surge es <em>¿Qué va a hacer con esa información? ¿La restricción de su proceso de toma de decisiones se ve limitada por la disponibilidad de información en tiempo real? </em>No lo sé, pero es un interrogante que vale la pena formularse, y evocaré a Javier Arévalo (Goldratt Partner) quien hace poco me mencionaba: “Lo que usted no haga bien en papel y lápiz, difícilmente lo hará bien con tecnología”.</p>
<blockquote class=" quote-simple "><p>“Lo que usted no haga bien en papel y lápiz, difícilmente lo hará bien con tecnología”.</p></blockquote>
<p>Es por eso que vale la pena plantearse si la disponibilidad de información en tiempo real de mi sistema (entidad, proceso, producto, etc.) es una necesidad que justifica un proyecto de implementación de gemelos digitales.</p>
<p>El conjunto de datos requerido para la construcción del gemelo digital de un sistema de producción varía de un sistema a otro, sin embargo, puede considerar la información del siguiente cuadro como un caso típico:</p>
<table width="524">
<tbody>
<tr>
<td rowspan="6" width="184">Datos estructurales de la planta</td>
<td width="340">Layout</td>
</tr>
<tr>
<td>Número de máquinas</td>
</tr>
<tr>
<td>Número de Sistemas de Manejo de Materiales (MHS)</td>
</tr>
<tr>
<td>Rutas de los MHS</td>
</tr>
<tr>
<td>Áreas</td>
</tr>
<tr>
<td>Restricciones</td>
</tr>
<tr>
<td rowspan="3" width="184">Datos de manufactura</td>
<td>Tiempos de ciclo</td>
</tr>
<tr>
<td>Tiempos de carga (Setup)</td>
</tr>
<tr>
<td>Calendario de mantenimiento preventivo</td>
</tr>
<tr>
<td rowspan="3" width="184">Datos del flujo de materiales</td>
<td>Rutas y secuencias de productos</td>
</tr>
<tr>
<td>Rutas producto &#8211; MHS</td>
</tr>
<tr>
<td>Redes de transporte detalladas (transportadoras)</td>
</tr>
<tr>
<td rowspan="4">Datos de la producción</td>
<td>Planes de producción</td>
</tr>
<tr>
<td>Calendarios de producción</td>
</tr>
<tr>
<td>Volúmenes de producción</td>
</tr>
<tr>
<td>Tipo de producción (Masiva/Lotes)</td>
</tr>
</tbody>
</table>
<p>Así podemos ver entonces, que el desarrollo de un gemelo digital requiere del conocimiento profundo del objeto físico (entidad, activo, sistema, etc.). Además, de la consideración de las tecnologías de seguimiento, pero sobre todo, del enfoque sistémico que le permita determinar sobre la pertinencia de esta aplicación tecnológica.</p>
<p>&nbsp;</p>
<h2>Caso de aplicación: Whirlpool Corporation (Polonia)</h2>
<p>Whirlpool Corporation en Polonia con 80.000 m², docenas de montacargas y remolcadores. Más de 250 sensores <a data-toggle="tooltip" data-placement="top" class="post-tooltip tooltip-top" title="Real Time Location System">RTLS</a> para el análisis de logística y 60 estaciones de trabajo equipadas con un sistema de pedidos automatizado para la gestión logística. Diagramas de espagueti, análisis de mapas de calor y saturación para identificar cuellos de botella, ineficiencias y otros potenciales de mejora continua.</p>
<p><iframe loading="lazy" width="560" height="315" src="https://www.youtube.com/embed/Y8Mo2mFsiFU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="allowfullscreen"></iframe></p>
<hr />
<h2></h2>
<h2>¿Quieres probar demos de gemelos digitales?</h2>
<p>&nbsp;</p>
<p><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/twinzo.png" alt="gemelos digitales" width="634" height="313" class="size-full wp-image-28283 aligncenter" srcset="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/twinzo.png 634w, https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/twinzo-300x148.png 300w" sizes="(max-width: 634px) 100vw, 634px" /></p>
<p>Si quieres probar un demo de gemelo digital desde tu celular, puedes hacerlo a través de:</p>

		<div class="one_half tie-columns">
<p><a href="https://play.google.com/store/apps/details?id=eu.twinzo.digitaltwin" target="_blank" rel="noopener"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/google-play.png" alt="" width="190" height="59" class="wp-image-28285 size-full aligncenter" /></a></p>

		</div>
	

		<div class="one_half tie-columns last">
<p><a href="https://apps.apple.com/us/app/twinzo-digital-twin/id1561970281" target="_blank" rel="noopener"><img decoding="async" src="https://ingenieriaindustrialonline.com/wp-content/uploads/2021/10/app-store.png" alt="" width="188" height="59" class="wp-image-28284 size-full aligncenter" /></a></p>

		</div>
		<div class="clearfix"></div>
	
<p>La entrada <a href="https://ingenieriaindustrialonline.com/transformacion-digital/que-son-los-gemelos-digitales-aplicaciones-en-la-industria/">¿Qué son los gemelos digitales? Aplicaciones en la Industria</a> se publicó primero en <a href="https://ingenieriaindustrialonline.com">Ingenieria Industrial Online</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ingenieriaindustrialonline.com/transformacion-digital/que-son-los-gemelos-digitales-aplicaciones-en-la-industria/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
