Braess’s Paradox and the Indian Highway Network: Why More Roads Can Mean More Traffic
Introduction
Traffic congestion remains one of Mumbai’s most intractable urban challenges, despite years of significant investment in infrastructure. The city’s roads, including some of its most iconic highways and expressways, have expanded in both scope and capacity, yet gridlocks persist. In fact, some of these expansions have paradoxically worsened congestion, rather than alleviating it.
This phenomenon, known as Braess’s Paradox, was first proposed by Dietrich Braess in 1968. It suggests that adding additional roads to an already congested traffic network can increase overall travel times, rather than reducing them. The key to understanding this paradox lies in the behavior of individual drivers. Each driver, seeking the shortest route, may inadvertently contribute to a systemic slowdown, with the cumulative effect being more traffic and longer delays.
Real-World Case Study: The Mumbai Traffic Nightmare
Mumbai provides a compelling real-world case for Braess’s Paradox. The city’s Eastern Freeway, designed to relieve traffic congestion between South Mumbai and the eastern suburbs, is a prime example. Initially, the new freeway was hailed as a solution to the city’s notorious traffic jams. However, after its completion, more and more drivers began to use the freeway, leading to severe congestion at key entry and exit points, which were not designed to handle the increased traffic volume.
Similarly, the expansion of the Western Express Highway and Eastern Express Highway also followed this pattern. While adding lanes and widening the roads was expected to alleviate congestion, the reality was far from being different. As more drivers flocked to these newly expanded routes, the system as a whole became increasingly saturated, with new bottlenecks forming at critical junctions. What was meant to be a relief for the traffic-weary turned into yet another point of gridlock.
The paradoxical outcome in Mumbai highlights the need for a deeper understanding of traffic flow and network dynamics. Expanding infrastructure without considering the collective behavior of drivers can exacerbate, rather than solve, congestion problems.
Modeling Mumbai’s Road Network
We’ll focus on a specific area in Mumbai to illustrate this phenomenon. Using the OSMnx library, we can extract and visualize the road network of the selected region.
Step 1: Extracting the Road Network
We’ll use OSMnx to download the road network data for a particular area in Mumbai.
# Define city
place_name = "Mumbai, India"
# Get the drive network of the entire city
G = ox.graph_from_place(
place_name,
network_type="drive",
retain_all=True
)
# Project the graph for better alignment and visualization
G = ox.project_graph(G)
# Plot the network
fig, ax = plt.subplots(figsize=(25, 25), facecolor="black")
ox.plot_graph(
G,
ax=ax,
bgcolor="black",
node_color="black",
node_size=2,
edge_color="black",
edge_linewidth=0.4,
show=False,
close=False
)
# Add north arrow
arrow = FancyArrow(0.9, 0.9, 0, 0.05, width=0.01, color='red', transform=ax.transAxes)
ax.add_patch(arrow)
ax.text(0.9, 0.87, 'N', transform=ax.transAxes, color='black', fontsize=20, ha='center')
plt.show()

Step 2: Mathematical Formulation
Consider a road network with three main paths between an origin and a destination. Each path has a travel time function dependent on traffic flow.
Let:
- weh, eeh, bwsl, shortcut represent the routes to commute from North to South of Mumbai i.e. the Western Express Highway, Eastern Express Highway, Bandra Worli Sea Link and a new proposed underground route, respectively.
- f(weh), f(eeh), f(bwsl), f(shortcut) be the number of vehicles using different paths.
- T(weh), T(eeh), T(bwsl), T(shortcut) be the time taken to travel each path based on traffic flow.
- N represents the projected demand of total number of vehicles on all the above routes after inclusion of the proposed shortcut route
Objective Function
The goal is to minimize the total travel time across all routes:
Minimize ∑ T(f(i)) * f(i)
which is the travel time function for route , dependent on traffic flow
Constraints
The optimization problem is subject to:
- Flow Conservation across all routes to meet the projected demand: f(weh) + f(eeh) + f(bwsl) + f(shortcut) = N
- Minimum Flow Constraints: f(weh)≥1000 ; f(eeh)≥1200; f(bwsl)≥800; f(shortcut)≥500
- Non-Negativity Constraint: f(i) ≥ 0
Initial Network (Before Adding a Road)
The travel time as a function of available paths:
- T(weh, x) = 15 + 0.0001(x**2)
- T(eeh, x) = 20 + 0.00001(x**2)
- T(bwsl, x) = 10 + 0.00012(x**2)
Where ‘x’ represents the traffic flow variable for a given route. It determines how many vehicles take a specific path
After adding a new underground shortcut route (Connecting North to South Mumbai)
Now, drivers have a fourth option using the shortcut:
T(shortcut, x) = g (fixed travel time for shortcut)
Next, we will try to assess how selfish routing leads to a new equilibrium, often worsening traffic flow.
Step 3: Iterative Selfish Routing Approach
To accurately model real-world traffic conditions, we use an iterative self-optimization model where vehicles dynamically redistribute based on perceived travel time.
This approach is rooted in the principles of User Equilibrium (UE), a fundamental concept in transportation planning and Operations Research. At equilibrium, no driver can reduce their travel time by unilaterally changing routes. Essentially, each vehicle chooses the fastest available route, but as traffic redistributes, congestion increases, dynamically shifting travel times across the network. Over successive iterations, the system approaches an equilibrium state, similar to a Nash equilibrium in game theory., where each driver chooses the fastest route available at each iteration. Over time, this process stabilizes at an equilibrium where no single driver can improve their travel time by switching routes.
The iterative process follows a gradient-based redistribution model inspired by proportional routing dynamics in traffic assignment models. The sequence of operations is as follows:
- Compute travel times for all routes based on current traffic flow.
- Identify the fastest route and shift traffic proportionally towards it.
- Repeat until flow changes are insignificant.
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import ipywidgets as widgets
from ipywidgets import interact
def selfish_routing_optimized(new_road_time):
total_demand = 15000
max_iterations = 50 # Limit iterations for faster convergence
alpha = 0.5 # Step size for gradual redistribution
# Travel time functions
def travel_time_weh(flow):
return 15 + 0.0001 * flow**2
def travel_time_eeh(flow):
return 20 + 0.00008 * flow**2
def travel_time_bws(flow):
return 10 + 0.00012 * flow**2
def travel_time_underground(flow):
return new_road_time # Constant travel time for underground road
# Initialize equal distribution of traffic
flows = np.array([total_demand / 4] * 4)
for _ in range(max_iterations):
travel_times = np.array([
travel_time_weh(flows[0]),
travel_time_eeh(flows[1]),
travel_time_bws(flows[2]),
travel_time_underground(flows[3])
])
# Redistribute flow towards lowest travel time route
best_time = np.min(travel_times)
probabilities = np.exp(-2 * (travel_times - best_time))
probabilities /= probabilities.sum()
# Adjust flow gradually for stability
new_flows = alpha * probabilities * total_demand + (1 - alpha) * flows
if np.allclose(new_flows, flows, atol=1e-2): # Stop if small changes
break
flows = new_flows
# Compute final travel times
final_travel_times = [
travel_time_weh(flows[0]),
travel_time_eeh(flows[1]),
travel_time_bws(flows[2]),
travel_time_underground(flows[3])
]
# Print results
print(f"Equilibrium Flows & Travel Times:")
print(
f" WEH: {flows[0]:.2f} vehicles,
Travel Time: {final_travel_times[0]:.2f} min"
)
print(
f" EEH: {flows[1]:.2f} vehicles,
Travel Time: {final_travel_times[1]:.2f} min"
)
print(
f" BWSL: {flows[2]:.2f} vehicles,
Travel Time: {final_travel_times[2]:.2f} min"
)
print(
f" Underground: {flows[3]:.2f} vehicles,
Travel Time: {final_travel_times[3]:.2f} min"
)
# Create network visualization with separate edges for each route
G = nx.DiGraph()
G.add_edges_from([
(
'North Mumbai',
'South Mumbai (WEH)',
{'travel_time': final_travel_times[0], 'route': 'WEH'}
),
(
'North Mumbai',
'South Mumbai (EEH)', {'travel_time': final_travel_times[1], 'route': 'EEH'}),
(
'North Mumbai',
'South Mumbai (BWSL)',
{'travel_time': final_travel_times[2], 'route': 'BWSL'}
),
(
'North Mumbai',
'South Mumbai (Underground)',
{'travel_time': final_travel_times[3], 'route': 'Underground'}
)
])
# Define distinct positions for each route to avoid overlap
pos = nx.spring_layout(G)
plt.figure(figsize=(10, 5))
edge_labels = nx.get_edge_attributes(G, 'travel_time')
formatted_labels = {
k: f"{v:.2f} min (
{G.edges[k]['route']})" for k, v in edge_labels.items()}
nx.draw(
G,
pos,
with_labels=True,
node_color='lightblue',
edge_color='gray',
node_size=3000,
font_size=10,
arrows=True
)
nx.draw_networkx_edge_labels(
G,
pos,
edge_labels=formatted_labels,
font_size=8
)
plt.title("Optimized Traffic Network with Multiple Routes")
plt.show()
return f"Total equilibrium travel time: {sum(final_travel_times) * total_demand:.2f} vehicle-minutes"
# Interactive widget for underground road travel time
interact(
selfish_routing_optimized,
new_road_time = widgets.FloatSlider(
min=0,
max=30,
step=1,
value=5,
description="New Rd Time"
)
);

Conclusion and Key Takeaways
The implementation of iterative selfish routing demonstrates how self-interested decision-making can lead to unintended inefficiencies in a transportation network. This study, inspired by Braess’s Paradox, reveals the paradoxical effect that adding infrastructure does not always improve system-wide performance. Instead, congestion effects and user equilibrium dynamics can lead to increased travel times for everyone.
Key Takeaways:
- Selfish Routing & Equilibrium: Traffic naturally redistributes towards the lowest-cost routes until equilibrium is reached.
- Infrastructure Additions Can Backfire: Introducing a new road can increase congestion instead of reducing it.
- Optimization Is Necessary: Coordinated interventions, such as tolling or optimized routing, could mitigate inefficiencies caused by selfish behavior.
- Real-World Implications: This model applies not only to urban road networks but also to internet traffic, energy distribution, and supply chains where competing agents optimize independently.