IntelliRoute is a console-based logistics decision system that uses data structures and algorithms to make delivery decisions on a simulated Pune road network.
Instead of using DSA algorithms as isolated examples, IntelliRoute combines them into one delivery workflow:
Delivery Request
↓
Check Warehouse Reachability
↓
BFS
↓
Find Shortest Route
↓
Dijkstra
↓
Select Best Warehouse
↓
PriorityQueue
↓
Assign Best Available Driver
The project is intentionally console-based so that the DSA, algorithmic decisions, and optimization techniques remain the main focus.
Consider a logistics company operating across a city.
A delivery request arrives for a particular destination.
The system needs to determine:
- Which warehouses can actually reach the destination?
- Which reachable warehouse can deliver it using the shortest route?
- Which driver should handle the delivery?
- What happens if some roads are temporarily blocked?
Instead of solving each problem independently, IntelliRoute combines multiple DSA techniques into one decision-making system.
The system has several responsibilities working together:
INTELLIROUTE
│
┌─────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
ROAD NETWORK ROUTE PLANNING DELIVERY PLANNING
│ │ │
│ ┌────┴────┐ ┌─────┴─────┐
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
Pune Graph BFS Dijkstra Warehouse Driver
+ Road Status Selection Scheduling
│
▼
PriorityQueue
Represents the Pune city road network as a weighted graph.
It stores:
- Locations
- Roads
- Road distances
- Open/blocked road status
Two algorithms are used for different purposes:
- BFS → checks whether a destination is reachable
- Dijkstra → calculates the shortest weighted route
The system evaluates multiple warehouses and selects the closest reachable warehouse.
Available drivers are maintained using a PriorityQueue based on their current simulated availability time.
Roads can be temporarily blocked.
The road is not deleted from the graph. Its status is simply changed to blocked.
This allows the road to be restored later.
When a delivery request is created:
Delivery Request
│
▼
Destination
│
▼
Check all warehouses
│
▼
BFS
│
Is it reachable?
/ \
NO YES
│ │
Skip ▼
Run Dijkstra
│
▼
Calculate distance
│
▼
Compare warehouses
│
▼
Best warehouse
│
▼
Driver PriorityQueue
│
▼
Driver with least workload
│
▼
Assign delivery
Each algorithm has a specific responsibility rather than being used only for demonstration.
The system creates a predefined Pune road network automatically.
Example locations include:
Baner
Aundh
Wakad
Hinjewadi
Shivajinagar
Kharadi
Viman Nagar
Example connections:
Baner ─── Aundh ─── Shivajinagar
│
│
Wakad ─── Hinjewadi
Shivajinagar ─── Kharadi
│
│
Viman Nagar
Each road has a distance/weight.
For example:
Baner → Aundh = 5 km
Aundh → Shivajinagar = 7 km
Baner → Wakad = 6 km
The graph is represented using an adjacency list.
Conceptually:
Location → Connected Roads
HashMaps are an important part of the implementation.
Locations have names such as:
Baner
Aundh
Wakad
Kharadi
The system needs to quickly find the neighbours of a particular location.
Conceptually:
Baner → [Aundh, Wakad]
Aundh → [Baner, Shivajinagar]
A HashMap allows direct average O(1) lookup.
HashMaps are also useful during graph algorithms for storing information such as:
Location → Distance
Location → Parent
Location → Neighbours
This avoids repeatedly scanning lists to find information.
Before calculating a shortest route, IntelliRoute first asks:
Can this warehouse reach the destination at all?
BFS explores the graph level by level.
Warehouse
↓
Neighbours
↓
Neighbours of neighbours
↓
...
↓
Destination
If the destination cannot be reached, the warehouse is skipped.
At this stage we only need to know:
Reachable?
We don't care about the exact distance.
BFS is therefore used as a simple connectivity check.
BFS is not necessarily faster than Dijkstra for every case.
If every warehouse is reachable, BFS introduces additional work.
Its main value is when the graph contains disconnected regions, especially after road closures.
For warehouses that pass the BFS reachability check, IntelliRoute runs Dijkstra's algorithm.
Dijkstra answers:
What is the shortest weighted route from this warehouse to the destination?
This is important because different roads have different distances.
For example:
Route A:
2 roads × 10 km
= 20 km
Route B:
4 roads × 3 km
= 12 km
A simple BFS shortest path would prefer Route A because it has fewer edges.
Dijkstra correctly prefers Route B because:
12 km < 20 km
A PriorityQueue is used inside Dijkstra to process the location with the smallest currently known distance.
The system does not simply choose the first warehouse.
It evaluates every warehouse.
Example:
Warehouse: Baner
↓
BFS
↓
Reachable
↓
Dijkstra
↓
18 km
Warehouse: Hinjewadi
↓
BFS
↓
Reachable
↓
Dijkstra
↓
14 km
Warehouse: Shivajinagar
↓
BFS
↓
Reachable
↓
Dijkstra
↓
8 km
The system selects:
Best Warehouse = Shivajinagar
Distance = 8 km
Choose the reachable warehouse
with the minimum shortest-path distance.
After selecting the warehouse, the system needs to assign a driver.
Drivers are maintained using:
PriorityQueue<Driver>Each driver has a simulated:
availableTime
This represents how much current workload the driver has before becoming available again.
Example:
Driver A → 20
Driver B → 5
Driver C → 12
The PriorityQueue selects:
Driver B
because:
5 < 12 < 20
After assigning a delivery, the driver's availability time is updated.
Without a PriorityQueue, we would need to repeatedly scan all drivers.
With a PriorityQueue, the driver with the smallest current workload remains at the top.
Approximate operations:
Insert → O(log D)
Remove → O(log D)
where D is the number of drivers.
Roads can be temporarily blocked.
Instead of deleting a road:
remove(edge);the system changes its status:
edge.blocked = true;BFS and Dijkstra ignore blocked roads.
A blocked road may reopen later.
Therefore:
Road
│
├── OPEN
│
└── BLOCKED
Restoring it simply changes the status back:
edge.blocked = false;- Easy restoration
- Original graph structure remains intact
- Temporary closures are easy to represent
- No need to rebuild the graph
- Historical road information is preserved during the program run
The system allows multiple roads to be blocked.
For example:
Baner - Aundh
Baner - Wakad
Baner - Hinjewadi
After these changes, BFS may determine that a destination is unreachable.
Warehouse
↓
BFS
↓
No path
↓
Warehouse skipped
This allows the system to adapt its warehouse selection to the current state of the road network.
The system does not continuously recompute every possible route whenever the graph changes.
Instead:
Road blocked
↓
Update road status
↓
Wait for delivery request
↓
Run BFS
↓
Run Dijkstra if necessary
This is a form of lazy computation.
The system performs route calculations when they are actually required.
This avoids unnecessary computation when there are no active delivery requests.
The Pune graph is created once and reused.
Conceptually:
Pune Graph
│
┌─────────────┼─────────────┐
│ │ │
▼ ▼ ▼
Manager 1 Manager 2 Manager 3
If one manager blocks:
Baner ↔ Wakad
the shared graph reflects:
Baner ↔ Wakad = BLOCKED
Other managers therefore see the same updated road network.
This provides a single source of truth for the city map.
| Data Structure | Purpose |
|---|---|
| Graph / Adjacency List | Represents the Pune road network |
| HashMap | Fast location and graph lookups |
| HashSet | Tracks visited locations in BFS |
| Queue | BFS traversal |
| PriorityQueue | Dijkstra's minimum-distance node |
| PriorityQueue | Driver scheduling |
| ArrayList | Stores roads, drivers and warehouses |
The project is not simply a collection of independent algorithms.
They form a complete decision pipeline:
Delivery Problem
│
▼
HashMap
Fast graph lookup
│
▼
BFS
Reachability check
│
▼
Dijkstra
Shortest route
│
▼
Warehouse Selection
│
▼
PriorityQueue
Driver Selection
│
▼
Delivery
Each data structure and algorithm has a specific responsibility.
The city graph is relatively sparse.
A location connects to only some other locations rather than every location.
Therefore an adjacency list is more memory-efficient.
Space complexity:
O(V + E)
instead of an adjacency matrix:
O(V²)
Locations are represented by names.
A HashMap provides average:
O(1)
lookup.
This makes it convenient to retrieve neighbours, distances and other information associated with a location.
BFS determines whether a destination is reachable.
If a warehouse cannot reach the destination:
Skip warehouse
and Dijkstra is not required for that warehouse.
If almost every warehouse is reachable, BFS adds extra computation.
Therefore, the purpose of BFS is primarily connectivity validation, not claiming that it always makes the system faster.
Roads have different weights.
BFS only minimizes the number of edges.
Dijkstra minimizes the total weighted distance.
Because all road distances are non-negative, Dijkstra is appropriate.
Drivers have different current workloads.
Instead of assigning the first available driver, the system prioritizes the driver with the smallest availability time.
This provides more balanced scheduling.
Deleting a road would permanently modify the graph structure.
Keeping the road and changing its status allows:
OPEN → BLOCKED → OPEN
without rebuilding the graph.
The graph represents the city's current road network.
Having one shared graph prevents different delivery managers from working with inconsistent versions of the city map.
The system considers several edge cases:
- Destination does not exist
- Warehouse does not exist
- No route is available
- All warehouses are unreachable
- No available drivers
- Road does not exist
- Road is already blocked
- Multiple roads are blocked
- Road is restored
- Source and destination are the same
- Negative distance input
- Empty road network
- Invalid delivery request
Let:
V = number of locations
E = number of roads
D = number of drivers
| Operation | Complexity |
|---|---|
| HashMap lookup | O(1) average |
| Graph storage | O(V + E) |
| BFS | O(V + E) |
| Dijkstra with PriorityQueue | O((V + E) log V) |
| Driver insertion | O(log D) |
| Driver removal | O(log D) |
For the current Pune graph, these operations are easily fast enough.
One optimization considered for a larger system is route caching.
Frequently requested routes could be stored:
Source + Destination
↓
Cache
↓
Existing Route?
/ \
YES NO
│ │
Return Dijkstra
Route │
▼
Store Route
However, caching introduces another problem:
Suppose:
A → B → C
is cached as the shortest route.
Then:
B → C
gets blocked.
The cached route is no longer valid.
Therefore, a production implementation would need to invalidate affected cached routes when road status changes.
This is an example of an important engineering trade-off:
Caching improves speed but makes maintaining correct data more difficult.
The current implementation intentionally focuses on DSA.
Possible extensions include:
Road weights could change according to traffic conditions.
Normal traffic → 5 km cost
Heavy traffic → higher effective cost
Drivers could have maximum package capacities.
Example:
Delivery must arrive before 5 PM
A driver could handle several packages in one trip.
This would introduce more complex route optimization.
Drivers could have battery constraints.
The system could select only warehouses that actually contain the required product.
Roads, drivers and deliveries could be stored in a database.
The predefined Pune graph could eventually be replaced with real map data through an external mapping API.
If a road closes while a driver is already travelling, the system could recalculate the driver's remaining route.
Suppose the destination is:
Kharadi
Available warehouses:
Baner
Hinjewadi
Shivajinagar
The system evaluates them:
Baner
↓
BFS
↓
Reachable
↓
Dijkstra
↓
18 km
Hinjewadi
↓
BFS
↓
Reachable
↓
Dijkstra
↓
14 km
Shivajinagar
↓
BFS
↓
Reachable
↓
Dijkstra
↓
8 km
Therefore:
Best Warehouse
↓
Shivajinagar
Shortest Distance
↓
8 km
The driver PriorityQueue then selects the driver with the lowest current workload.
- Java
- Java Collections Framework
- Graph Algorithms
- BFS
- Dijkstra
- HashMap
- HashSet
- Queue
- PriorityQueue
- Object-Oriented Programming
No database or external API is required.
IntelliRoute/
│
├── src/
│ └── IntelliRoute.java
│
├── README.md
│
└── .gitignore
The implementation is intentionally kept in a single Java file so that the DSA logic remains easy to understand and explain during technical interviews.
- Create/import the Java project.
- Open
IntelliRoute.java. - Run the
main()method. - Follow the console instructions.
Compile:
javac IntelliRoute.javaRun:
java IntelliRouteIntelliRoute is intentionally a DSA-focused console application, not a production logistics platform.
The primary goal is to demonstrate how multiple data structures and algorithms can work together to solve a realistic problem.
The core system is:
Graph
+
HashMap
+
BFS
+
Dijkstra
+
PriorityQueue
+
Dynamic Road Network
+
Warehouse Selection
+
Driver Scheduling
The project prioritizes clarity, algorithmic reasoning, and explainability over unnecessary application complexity.
Rasika Joshi
Computer Engineering Student DSA-focused Java project for technical interview preparation.
The main idea behind IntelliRoute is:
Don't just find a shortest path. Use algorithms to make a sequence of delivery decisions.
Can I reach the destination?
↓
BFS
What is the shortest route?
↓
Dijkstra
Which warehouse should I use?
↓
Minimum distance
Which driver should handle it?
↓
PriorityQueue