sábado, 20 de diciembre de 2025

Simulador de 'bus bunching' con R

El bus bunching consiste en el encuentro de dos o más autobuses en una misma línea de transporte público, provocando que lleguen a las paradas de forma cuasi simultánea. Esto da lugar a un deterioro del servicio al alargarse los tiempos medios de espera de los usuarios, propiciando además una ocupación desigual de los vehículos.

Fuente: Wikipedia


Aunque la partida de los autobuses de una línea se haga equiespaciada en el tiempo, un retraso fortuito en cualquiera de ellos facilitará la aparición de bus bunching. Por un lado ese vehículo tardará más en llegar a las paradas, que por lo tanto habrán acumulado más usuarios de lo esperable, tardando más tiempo en acceder al autobús y retrasándolo aún más. Por el mismo motivo, el autobús siguiente al tener que absorber un menor número de viajeros reducirá sus tiempos, acercándose todavía más al primero pudiendo llegar a alcanzarlo.

Ocurrirá lo mismo si por cualquier causa uno de los autobuses se adelanta, ya que recogerá menos viajeros acercándose cada vez más al autobús que le precede, a la vez que obliga al autobús que le sigue a recoger más pasaje, provocando su retraso y separándose de él:



En un escenario de alta demanda de usuarios, la separación uniforme entre autobuses constituye un equilibrio inestable, mientras que el bus bunching es por desgracia el estado estable al que tiende el sistema de forma natural si no se toman medidas para evitarlo.

~~~

En este artículo vamos a desarrollar un simulador básico de bus bunching que nos permita tanto reproducirlo como evaluar el rendimiento de estrategias que lo mitiguen. Las pretensiones son puramente teóricas, no buscando que sirva para modelar ni optimizar ningún sistema real.

Con este enfoque teórico haremos varias asunciones razonables para eliminar ruido del análisis:
  • Las paradas de la línea a modelar se asumen equiespaciadas, así como los intervalos de salida iniciales de los autobuses.
  • Los autobuses circulan a la misma velocidad media, reciben el mismo nivel de demanda de servicio (a igual retardo de llegada) y tardan lo mismo en atender a los viajeros.
  • Se asumen autobuses de capacidad infinita ya que no buscamos hacer un estudio de carga del sistema sino de sensibilidad a desviaciones temporales.
  • Son posibles, y de hecho serán frecuentes, los adelantamientos entre autobuses agrupados en bus bunching.

Para que se den las condiciones del mundo real que propician el bus bunching vamos a aleatorizar las siguientes dos variables:
  • El proceso de llegadas de usuarios a las paradas se modela con una distribución de Poisson parametrizada por una tasa media de llegadas de pasajeros por unidad de tiempo.
  • La velocidad de los autobuses se modela con una distribución normal parametrizada por una desviación estándar alrededor de una velocidad media.

En su día elaboré una retahíla de definiciones y empecé a escribir código con OO en Python para implementar el simulador. En la era de los LLM's tomo la vía fácil pidiendo a ChatGPT: "I want to do a bus bunching simulator in the form of a R function that models a circle line (endless loop)".

Por error di a entrar sin poder detallar más el prompt, pero solo con esa frase obtuve una rutina plenamente funcional que tras algunos refinamientos (soporte de rutas lineales, introducción de mecanismos básicos de control del bus bunching, profusión de comentarios y definiciones en el código), ha concluido en una función robusta para hacer nuestras simulaciones.

~~~

Empezamos con un ejercicio base, una ruta circular de 8 paradas cubierta por 3 autobuses equiespaciados a la salida en 15min. Comprobamos que en ausencia de usuarios los autobuses no tienen ningún motivo para no lograr mantener las distancias:



A continuación introducimos un régimen de baja demanda de pasajeros (0,6 usuarios por minuto = 9 usuarios por intervalo de paso). Como era esperable los autobuses tardan más en realizar los recorridos pero esta demanda no es suficiente para generar bus bunching. Solo al cabo de 4h de simulación dos de los autobuses se empiezan a aproximar peligrosamente:



Pero si incrementamos la demanda a un nivel alto (3 usuarios por minuto = 45 pasajeros por intervalo de paso), en hora y media los autobuses verde y azul ya se solapan, y tras 3h se les ha unido el rojo en convoy:



Finalmente introducimos una estrategia de espera ('headway') de 2min: al llegar a cada parada el conductor es informado de hace cuánto tiempo salió de dicha parada el anterior autobús. Si fuera un tiempo menor a los 15min nominales establecidos, esperará hasta un máximo de 2min para cumplir ese tiempo y entonces partirá. Esa simple espera impide que los autobuses se junten y por tanto se evita el bus bunching:



Haciendo clic sobre cualquiera de las versiones se tiene un GIF animado en bucle que permite ver el efecto de cada cambio.

~~~

Vamos ahora con una simulación más densa: 10 autobuses con salidas inicialmente equiespaciadas cada 3min, haciendo un recorrido circular de 20 paradas. Aplicamos una demanda de 1,8 pasajeros por minuto = 5,4 usuarios por intervalo de paso al ser estos muy cortos.

En un escenario sin control antes de la hora empiezan a formarse convoys de bus bunching. Introducimos ahora un control por espera ('schedule') de 4min, es decir de 1min más de la distancia inicial de los autobuses. Esto deberá provocar que se vayan separando entre ellos más de lo que lo estaban inicialmente (bastante imprescindible hacer clic para ver en su resolución original):



Puede verse que buscando estas separaciones de 4min el sistema queda perfectamente optimizado. Un valor menor habría mejorado la situación inicial, pero aún se tendrían algunas agrupaciones de bus bunching.

Otra forma de visualizar la aparición/mitigación del bus bunching es con la siguiente gráfica que representa la evolución en cada hora de los tiempos entre llegadas a las paradas de todos los autobuses, independientemente de cuál sea la pareja de autobuses que contribuye a cada dato.

En un escenario ideal todas ellas deberían distribuirse entorno a determinado valor buscado. Cuando existe bus bunching, los autobuses se descomponen en el vehículo de cabecera que dispara los tiempos entre llegadas, y los demás de cada convoy cuyos tiempos entre llegadas se hacen nulos (obviamente al estar pegados al autobús precedente):



En el escenario con bus bunching veíamos que sobre las 4h ya teníamos a los 10 autobuses agrupados en dos grupos, que son los representados por los puntos crecientes. En la segunda gráfica, una vez introducido el control que busca lograr separaciones de 4min vemos que todos los tiempos se distribuyen entorno a esa cantidad.

Estos tiempos entre llegadas los podemos representar en forma de histogramas donde encontraremos mucha dispersión de valores en una línea afectada por bus bunching (histograma superior) mientras se tiene una concentración sana entorno a un único valor cuando se ha introducido un control efectivo (histograma inferior):


~~~

Aunque no lo hemos aprovechado, la rutina permite simular rutas lineales además de circulares. Una ruta lineal debe estar más estresada que una ruta circular para que llegue a aparecer bus bunching en ella ya que éste debe ocurrir en un solo recorrido, y además su efecto no se propagará en el tiempo una vez los autobuses implicados lleguen a su destino.

También existe un parámetro de régimen transitorio que permite ignorar los compases iniciales de la simulación para obtener los estadísticos finales del régimen estacionario.

Repositorio con el código R: GitHub.

No hay comentarios:

Publicar un comentario

Por claridad del blog, por favor trata de utilizar una sintaxis lo más correcta posible y no abusar del uso de emoticonos, mayúsculas y similares.