Excerpt from the ambulance-routing implementation
priority_rows = list(csv.DictReader(csvfile))
return location_rows, ambulance_rows, calls_rows, priority_rows
def sort_calls(calls_rows, priority_rows):
# Sort by priority first, then by original order in calls.csv using original index, so it's FIFO.
priority_map = {}
for row in priority_rows:
call_type = row["Call Type"]
priority_value = int(row["Priority"])
priority_map[call_type] = priority_value
indexed_calls = list(enumerate(calls_rows))
indexed_calls.sort(
key=lambda item: (int(priority_map[item[1]["Call Type"]]), item[0])
)
sorted_calls = []
for original_index, row in indexed_calls:
sorted_calls.append(row)
return sorted_calls
def build_adjacency_list(location_rows):
# Build a adjacency list/graph from CSV rows using Travel Time + Traffic Delay as weight.
adjacency_list = {}
for row in location_rows:
start = row["Start"]
end = row["End"]
travel_time = float(row["Travel Time"])
traffic_delay = float(row["Traffic Delay"])
weight = travel_time + traffic_delay
adjacency_list.setdefault(start, []).append((end, weight))
return adjacency_list
# Build ambulances list from CSV rows.
def build_ambulances(ambulance_rows):
ambulances = []
for row in ambulance_rows:
ambulance_number = row["Ambulance Number"]
staging_location = row["Staging Location"]
ambulances.append((ambulance_number, staging_location))
return ambulances
def dijkstra(adjacency_list, ambulances, calls_sorted):
# Dispatch each call.
total_route_exec_time = 0.0
dispatch_records = []
for call in calls_sorted:
call_id = call["Call ID"]
call_type = call["Call Type"]
call_location = call["Location"]
best_route_option = NoneSample rows from the dispatch log produced by the program
| Call ID | Call Type | Selected Ambulance | Route to Call Location | Time to Call Location |
|---|---|---|---|---|
| 1 | Stroke | Ambulance 3 | Address 123 Main St -> Intersection D | 1.72 |
| 3 | House Fire | Ambulance 3 | Address 123 Main St -> Intersection D -> Address 789 Pine St | 6.34 |
| 6 | Childbirth | Ambulance 3 | Address 123 Main St -> Intersection D | 1.72 |
| 7 | Seizure | Ambulance 1 | Intersection A | 0.0 |
| 8 | Heart Attack | Ambulance 2 | Intersection C | 0.0 |
| 12 | Seizure | Ambulance 3 | Address 123 Main St -> Intersection D | 1.72 |
Project objective
Select an ambulance and route that can reach a prioritized emergency call efficiently while documenting algorithm behavior and runtime.
What I produced
- Loaded ambulances, calls, priorities, and network edges from CSV data.
- Used call-priority information to process higher-priority emergencies first.
- Implemented Dijkstra in one prototype and Bellman-Ford in another.
- Calculated candidate routes, selected dispatch assignments, and wrote detailed logs.
- Compared algorithm characteristics and measured execution time over repeated runs.
Key decisions
- Use Dijkstra for efficient shortest paths when edge weights are nonnegative.
- Use Bellman-Ford as a comparative implementation that can handle negative weights, though the dispatch graph does not require them.
- Keep network data external in CSV files so test scenarios can change without rewriting code.
- Write dispatch results to logs for traceability.
2 algorithmsDijkstra and Bellman-Ford
4 data sourcesCalls, priorities, ambulances, and network
Repeatable logsDispatch choices and routes recorded
Validation and analysis
- Ran both implementations against the same input data.
- Compared route output and measured milliseconds across multiple runs.
- Reviewed time and space complexity and algorithm suitability.