Story Transcript
Caruso’s Pizza1 Caruso Pizza es una empresa mixta de restaurantes y reparto de pizzas a domicilio. Caruso se especializa en pizzas de muy alta calidad, especialmente pizzas gruesas. Este tipo de pizzas, al tener una masa de mayor grosor, son más propensas a acumular humedad, que si no se libera adecuadamente moja la pizza y la convierte en una masa blanda de mal aspecto y peor ingestión. Por ello, Caruso ha estado siempre muy preocupado por encontrar una tecnología capaz de situar la pizza en casa del cliente, en las condiciones ideales para ser degustada a satisfacción. El cliente domestico de Caruso, el que pide pizza para que se la lleven a casa, es típicamente una madre de familia que tiene necesidad urgente de alimentar a hijos hambrientos. Por ello, cuando el cliente llama a Caruso pidiendo una pizza, espera que la entrega se produzca en unos 30 minutos. Si se tarda más, es probable que ya no quiera la pizza. Por otro lado, 30 minutos es tiempo suficiente para que la pizza se enfríe, si no se toman precauciones especiales. Y todo el mundo sabe que una pizza fría es prácticamente incomible. En el pasado, esto hacia necesario que la producción de pizzas se hiciera siempre bajo pedido. Esto llevaba a poner el máximo empeño en diseñar un proceso con un plazo de producción inferior a los 10 minutos. La mayoría de otros proveedores de pizza a domicilio tenían sistemas logísticos capaces de entregar pizzas en menos de 20 minutos, normalmente apelando al transporte en motocicletas ligeras cuya velocidad media en medios urbanos era más elevada que la de otros tipos de transporte. En una convención de fabricantes, Caruso atendió una presentación de una empresa que decía haber puesto a punto una tecnología capaz de mantener pizzas en stock, sin que se degradaran en calidad o temperatura. Se trataba de unos hornos de gas, que mantenían la pizza en atmósfera controlada y garantizaban una calidad, como de recién salida del horno, por un tiempo de almacenamiento de alrededor de dos horas. Adicionalmente, la tecnología se había implantado en unidades móviles, camionetas de reparto. Con estas camionetas, una empresa podía producir pizzas y mantenerlas en stock durante dos horas, al mismo tiempo que realizaba el reparto con la propia camioneta. En un horno cabían unas 40 pizzas. La velocidad media de las camionetas en tráfico urbano no superaba los 20 Km/hora, por lo que (al añadirle los tiempos de parada) una camioneta podía cubrir un área de 2 x 2 Km, centrada alrededor del punto de fabricación. Caruso compró cuatro camionetas y empezó el reparto de pizzas gruesas usando esta tecnología. Las camionetas cargaban sus hornos en el centro de producción, con hasta 5 variedades de pizza. A continuación salían hacia las zonas de reparto. Cuando un cliente llamaba al centro de toma de pedidos, el encargado se ponía en contacto con las camionetas, para determinar cuál era la más cercana al domicilio del cliente que tenia pizza del tipo deseado. A continuación daba la orden a la camioneta de entregar el pedido . Si ninguna camioneta tenia pizza del tipo adecuado, el operador trataba de convencer al cliente de que cambiara su pedido. Esto, que se lograba solo en un 30% de los casos, permitía servir el pedido con una pizza ya existente en una camioneta. Si el cliente no cambiaba el tipo de pizza, la camioneta debía volver al centro de producción para recoger pizza del tipo deseado. Esta circunstancia se aprovechaba para recargar los hornos con todos los tipos de pizza. Si en algún momento una
1
Hart C.W.L. Caruso’s Pizza: reparto Expres (A). Caso P-672. Division de Investigacion del IESE. Barcelona 1988
1
camioneta tenia pizzas que llevaban dos horas en la misma, la camioneta se dirigía al centro de producción para cargar pizzas nuevas. Tras unos meses de operar el nuevo sistema, Caruso empezó a notar un aumento notable en el volumen de desperdicios. Al mismo tiempo, no parecía que los clientes estuvieran muy contentos con el servicio de la empresa. A Caruso le preocupaban varios aspectos • • • • • 1.
¿Cuál era el origen del aumento de los desperdicios? ¿Cuántos tipos de pizza podía distribuir con los camiones? ¿Cuánto le costaba mover las pizzas por toda la ciudad, con respecto a la técnica tradicional de la motocicleta? ¿Qué área podía cubrirse de una forma razonable? ¿Valía la pena usar el sistema de las camionetas?
Un modelo para Caruso
Para contestar las preguntas planteadas, Caruso preparo una simulación usando PSPS, que presentaremos en esta sección. Empezaremos por la sección System de una primera versión simplificada, indicando las funciones necesarias para la implantación. Cuadro 1. Modelo “Caruso”. Sección System. System {--Inicio y lectura de datos--} GENERATE 0,1; COMPUTE Leedatos; TERMINATE 0; {--Generar demanda y buscar camion--} GENERATE Exponential(tDemanda),on; {--Determinar el punto de demanda y la disponibilidad de tipo de pizza fresca en el camion. Si no hay camion con pizza adecuada ir a reponer--} COMPUTE CargaAtributosDemandayCamion, IraCasoSegunDisponibilidad; {--si no se puede hallar un camion disponible en maxespera dejarlo--} ENTER at[camion],1,fifo,maxEspera,OutOfStock; ADVANCE Erlang(at[distancia],2); entrega: COMPUTE zz = RealizaEntrega(at[camion],at[tipo]); DEBUG step do stop; TABULATE 1,cl-at[hora]; LEAVE at[camion],1; COMPUTE zz = CalculaEstadisticas; TERMINATE 1; {--cada camion se representa por una facility. Las demandas son transacciones--} reponer: ENTER at[camion],1,fifo,maxespera,outofstock; {--ir a casa, cargar y volver--} ADVANCE Erlang(at[distancia],2); DEBUG Mapa do COMPUTE Fdrawcont(6,GCLRALL); COMPUTE camiones[at[camion],horasalida] = cargapizzas(at[camion]), entrega; {--perdidas por impaciencia--} outofstock:TERMINATE 1; perdido: TERMINATE 1; {--Informar de resultados en una tabla--} DEBUG Tablas do GENERATE Tiempo,1; DEBUG Tablas do COMPUTE zz = resultados; DEBUG Tablas do TERMINATE 0; Endsystem;
2
El modelo genera pedidos con una distribución entre pedidos exponencial, de parámetro tDemanda (un dato). A continuación, la función CargaAtributosDemanda carga en los atributos de la transacción las características del pedido, las coordenadas (x, y) del punto en que se origina la demanda, la hora a la que se produce y el tipo de pizza pedido. La función FindCamion trata de encontrar un camión que cumpla con los requisitos establecidos en el caso. Si lo encuentra, devuelve su número, que se guarda en un atributo de la transacción, para usarlo luego. Si no lo logra, puede ser por dos razones. Primero, puede haber un camión que incluso yendo al deposito a cargar, llegue a tiempo de servir al cliente en el tiempo deseado. Si lo hay, se devuelve el número del camión en negativo, para indicar que tiene que ir primero a casa a repostar pizzas. O puede ser que no haya camión a una distancia factible, en cuyo caso se da por perdido el pedido. Si hay que ir al centro, el camión se pone en movimiento (el bloque ENTER bloquea el camión elegido), espera el tiempo de transito, y una vez pasado este, recarga el camión mediante la función Cargapizzas. Si en el proceso de recarga de un tipo de pizza, se encuentra que la edad de alguno de los tipos en el camión supera un tiempo dado, antigüedad, también se sustituye este tipo de pizza, eliminando todas las unidades del mismo. El camión sale, para dirigirse a la ubicación del pedido, presumiblemente la casa del cliente. La impaciencia en el ENTER hace que si el camión que se ha hallado, pero no queda disponible en un tiempo maxespera, el proceso se abandone y el pedido se pierda. Cuando se ha encontrado un camión con la pizza adecuada, el pedido bloquea al camión mediante un bloque ENTER. De esta forma el camión puede dirigirse a casa del cliente (bloque WAITFOR) y entregar el pedido. Los tiempos de transito se muestrean de una distribución Erlang(x,2) para que tengan algo menos de variabilidad que en el caso exponencial. Una vez completada la lógica fundamental podemos pasar a escribir las funciones que implantan el detalle. El lector observará que la implantación que hemos hecho no reproduce totalmente la realidad. Esto es parte del espíritu de la metodología, llegar a un primer modelo lo más rápidamente posible. Ahora deberá empezar el proceso de refinamiento, que dejamos al lector como ejercicio. Aun con sus limitaciones el modelo tiene un poder explicativo importante, que explotaremos en las sección siguiente. Aquí tiene el lector las funciones que implementan los detalles. Cuadro 2. Modelo “Caruso”. Sección Macros. Macros {--usamos la distancia l1(manhattan distance)--} distance :function(x0,y0,x1,y1) return abs(x0-x1)+abs(y0-y1); {--halla un camion disponible, que tiene pizza del tipo deseado y más cerca de la demanda. Incluye la posibilidad de ir a repostar para los que no tienen la pizza adecuada Si ninguno la tiene manda a repostar al más cercano. Devuelve el numero de camion (positivo) si hay un camion que tiene la pizza, y el mismo numero pero negativo si hay que ir a repostar --} findcamion : function (tipopizza,timedist) Locals xx,i,hay,k,zz,acasa; begin xx = 9999999, k = 0, acasa = False, for i = 1 to numfurgo do if fc[i] == 0 then begin punto = &camiones[i,1], stockpizza = &camiones[i,stocks],
3
tiempoPizza = &camiones[i,tiempos], hay = (stockPizza[tipopizza] > 0) and ((cl-tiempoPizza[tipopizza]) 0 then return cb+1 else if at[camion] == 0 then return perdido else begin at[camion] = - at[camion], return reponer end end; cargapizzas :function(num) Locals j,zz; begin {--preparacion de las variables--} stockpizza = &camiones[num,stocks], tiempoPizza = &camiones[num,tiempos], {--mirar todos los tipos de pizza. Si su antigüedad es superior a antigüedad reponerlos. Lo mismo si su nivel ha bajado por debajo de smin --} for j = 1 to numpizzas do begin if (cl-tiempoPizza[j]) > antiguedad then begin desperdicio = desperdicio + stockpizza[j], stockpizza[j] = 0 end, if stockpizza[j] 0) then zz = Fdrawxy(1,1,cl,desperdicio/totalCargado), DEBUG dibuja do zz = FdrawXY(2,1,cl,cl/numcargas), return cl end; realizaEntrega:function(cami,tip) Locals z; begin punto = &camiones[cami,1], stockpizza = &camiones[cami,stocks], punto[posx] = at[posx], punto[posy] = at[posy], DEBUG mapa do z = FDrawXY(6,cami,punto[posx],punto[posy]),
4
distTotal = at[distancia], stockpizza[tip] = stockPizza[tip]-1, entregas = entregas + 1, return True end; CalculaEstadisticas:function () Locals zz; begin DEBUG dibuja do zz = FdrawXY(5,1,cl, statvar(&distTotal,SAVERAGE)*velocidad), if (cl-at[hora]) > tservicio then begin numretrasos = 1, retraso = cl-at[hora]-tservicio, DEBUG dibuja do zz = FdrawXY(3,1,cl, statvar(&retraso,SAVERAGE)), DEBUG dibuja do zz = FdrawXY(4,1,cl, statvar(&numretrasos,SAVERAGE)) end else numretrasos = 0, Return True end;
Resultados Veamos los resultados de este modelo y que nos dicen con respecto a los problemas de Caruso. Iniciamos el análisis básico considerando un solo tipo de pizza, y un stock de 10 pizzas en el horno del camión.
Figura 2. Resultados de la simulación
En esta simulación la demanda es de un pedido cada tres minutos. Suponemos que cada pedido es por una sola pizza.
5
Figura 3. Tabla de Procesadores.
El porcentaje de pedidos retrasados es de un 6%. Si suponemos que son aceptados por el cliente, esto no perjudica la productividad, la rentabilidad del negocio. Pero si lo hace, y gravemente, con la competitividad, la percepción que tiene el cliente del servicio de la empresa. La demanda total de pizza por hora es en promedio 60/3 = 20 unidades y por tanto de 20/4 = 5 pizzas por camión. Si se cargan en promedio 10 pizzas, y una pizza dura en promedio dos horas, habrá que vender 5 pizzas por hora en promedio para no tener que tirar pizzas Y este valor coincide exactamente con la demanda. Por tanto el sistema esta perfectamente equilibrado en cuanto a capacidad de producción. Si se opera perfectamente, no debería haber desperdicio alguno. Pero esto supone que toda la demanda se atiende, es decir que no se pierden pedidos por problemas de plazo de entrega. Contar los pedidos que se pierden no es fácil sin la simulación. Por tanto acudamos a los resultados. Según la cuenta de los bloques TERMINATE, durante los 5000 minutos de tiempo de simulación se han entregado 1116 pizzas. Se han cargado 1370 (según la variable TotalCargado) Por tanto se han tenido que tirar 1370-1272= 98 pizzas, o un desperdicio de 98/1370 = 7% Pero veamos que sucede si se cargan dos tipos de pizza. Supongamos que la demanda se reparte igualmente entre ambos tipos. Dividamos también la carga en dos partes iguales, 5 pizzas de cada tipo.
Figura 4. Resultados de la simulación
Aunque el tiempo entre visitas al centro de producción parece ser aproximadamente el mismo, el porcentaje de desperdicio ha crecido, y ahora es del 15%. Y si añadimos un nuevo tipo de pizza, con un total de 3 tipos, el porcentaje de desperdicios se eleva a un 23%. Este fenómeno se origina en la división de la demanda lo que, al obligar a repartir el stock de seguridad, hace que no se alcancen los mismos niveles de protección que consigue el stock total con la demanda consolidada. Al crecer el número de productos, crece el número de roturas de stock, y por tanto crecería el
6
número de veces que el camión debería ir a repostar. Sin embargo, como el porcentaje de roturas que encuentran al camión a más de una distancia, depende poco del número de tipos de pizza, ahora se rechazaran más pedidos, por no poder servirse en el tiempo deseado. La operación del sistema será de parecida eficiencia, o incluso mejor. Con tres productos, los camiones tienen un tiempo entre recargas de unos 35 minutos, dando un intervalo entre visitas al centro de un camión de 140 minutos. El porcentaje de entregas retrasadas disminuye desde el 4.2% al 3%. La dirección podría pensar que todo va mejor. Y esto es así, en apariencia, porque el filtro del tiempo de servicio hace desaparecer más pedidos en origen, y por tanto el sistema esta menos cargado. La venta disminuye pero la dirección puede concluir que esto es achacable al mercado, especialmente si no queda constancia de los pedidos que no se pueden atender por un mal tiempo de respuesta. También disminuye la ocupación del camión desde el 56% con un tipo, al 54% con tres tipos. ¿Qué se puede hacer?. ¿Aumentar la velocidad de los camiones? ¿Arreglara esto algo?. ¿Y cómo se puede hacer ?. El lector puede explorar el sistema analizando posibilidades. Aunque los refinamientos le darán una mejor perspectiva, verá que el diagnostico general ya esta perfectamente establecido. El sistema esta mal planteado. Obliga a tener stocks de seguridad perecederos en un almacén móvil, la camioneta. El fenómeno de la división de demanda, al que nos hemos referido más arriba, se agrava por estas dos circunstancias. Caruso cayo en la trampa tecnológica, usando una tecnología poco adaptada a su proceso productivo y de servicio. Posiblemente debe replantearse el problema desde el principio: ¿Cómo atender a los clientes en flexibilidad (la pizza que quieran) y en rapidez?. Producir a medida, Just In Time, parece ser la única alternativa viable. El potencial de desastre de la situación de Caruso es grande, pero difícil de ver sin un análisis del tipo que hemos hecho. Esta es otra ventaja de las simulación en la empresa: Ayudar en el diagnostico de los motivos, en casos complicados. En Caruso, la dirección solo se ha alarmado por el aumento de los desperdicios y la disminución de los beneficios, sin entender el problema. Con la simulación hemos logrado entenderlo. Lo de menos son los números concretos, y hasta la precisión del modelo. ¿En estas condiciones, vale la pena refinar el modelo?. Creemos que no. Que la diferencia serán unos puntos en los porcentajes, pero probablemente no un mejor entendimiento de la naturaleza del problema. Y refinarlo toma tiempo de diseño, de programación y de análisis. En nuestra experiencia el balance se inclina siempre hacia modelos sencillos y rápidos de preparar y entender2 .
2
Una vez vimos un modelo de una factoría tan detallado, que simulaba a velocidad menor que el sistema real. Se tardaba una hora en simular media hora de proceso de la factoría. Costaba tanto entenderlo que se terminó abandonando, ante la imposibilidad de saber lo que hacia. Sus propios creadores renunciaron a comprenderlo…
7