Delivery Route Optimization using Python: A Step-by-Step Guide

Optimizing Delivery Route Planning

Delivery route planning is one of the most important aspects that helps minimize drivers’ delivery cost and travel time. Popular techniques like Just in Time ( JIT ) and lean management depend tremendously on Delivery route planning.

Delivery route optimization involves finding the most efficient sequence of stops for a delivery vehicle to minimize time, distance, and resources. Python’s powerful libraries like Numpy, Scipy, and Pandas provide tools for data manipulation, mathematical optimization, and network analysis, making it an ideal choice for solving complex delivery route optimization problems. With these optimization algorithms in Python, businesses can reduce operational costs and improve efficiency in their delivery processes.

In this article, we will use Python’s tremendous power to find the optimum delivery routes. We will also observe how different libraries in Python are utilized to achieve this purpose.

Recommended: A Beginner’s Guide to Non-linear Equations and Constraints

Introduction to Delivery Route Optimization

Delivery route optimization generally requires finding a delivery vehicle’s most efficient sequence of stops to minimize time, distance, and resources. Additionally, certain constraints include time, vehicle capacity, fuel, and traffic conditions. Generally, this problem has been tackled with simple heuristics and human judgment, leading to increased operational costs.

The Role of Python in Delivery Route Optimization

Python has a rich environment with powerful optimization tools and algorithms. Python libraries like Numpy, Scipy, and Pandas provide us with different functions for data manipulation, mathematical optimization, network analysis, etc. This makes Python a popular choice for solving complex optimization problems.

Recommended: Improve Random Forest Accuracy with Linear Regression Stacking

Implementing Delivery Route Optimization in Python

Let us first understand how delivery route optimization is done in Python. Let us look at the different steps involved in the same.

  • Step 1: Data Collection
  • Step 2: Data Preprocessing
  • Step 3: Graph Visualization
  • Step 4: Defining the Objective Function
  • Step 5: Optimization Algorithm
  • Step 6: Result Analysis

Now let us understand the topic with the Python code below.

import numpy as np
import matplotlib.pyplot as plt

# Sample delivery locations (latitude, longitude)
delivery_locations = np.array([
    [37.7749, -122.4194],  # San Francisco
    [34.0522, -118.2437],  # Los Angeles
    [40.7128, -74.0060],   # New York
    [41.8781, -87.6298]    # Chicago
])

# Calculate pairwise distances between locations
def calculate_distances(locations):
    num_locations = locations.shape[0]
    distances = np.zeros((num_locations, num_locations))
    for i in range(num_locations):
        for j in range(num_locations):
            if i != j:
                # Using Haversine formula to calculate distances between coordinates
                lat1, lon1 = np.radians(locations[i])
                lat2, lon2 = np.radians(locations[j])
                dlon = lon2 - lon1
                dlat = lat2 - lat1
                a = np.sin(dlat / 2) ** 2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon / 2) ** 2
                c = 2 * np.arcsin(np.sqrt(a))
                distances[i][j] = 6371 * c  # Radius of Earth in kilometers
    return distances

distances = calculate_distances(delivery_locations)

# Define optimization objective function (total distance)
def total_distance(route, distances):
    total = 0
    for i in range(len(route) - 1):
        total += distances[route[i]][route[i + 1]]
    total += distances[route[-1]][route[0]]  # Return to starting point
    return total

# Implement simple greedy algorithm for route optimization
def optimize_route_greedy(distances):
    num_locations = distances.shape[0]
    route = [0]  # Starting location
    remaining_locations = list(range(1, num_locations))  # Exclude starting location

    while remaining_locations:
        last_location = route[-1]
        nearest_location = min(remaining_locations, key=lambda x: distances[last_location][x])
        route.append(nearest_location)
        remaining_locations.remove(nearest_location)

    return route

# Perform route optimization
optimized_route = optimize_route_greedy(distances)
total_dist = total_distance(optimized_route, distances)

# Plot delivery locations and optimized route
def plot_route(locations, route):
    plt.figure(figsize=(10, 6))
    plt.scatter(locations[:, 1], locations[:, 0], c='blue', label='Delivery Locations')
    for i in range(len(route) - 1):
        start = route[i]
        end = route[i + 1]
        plt.plot([locations[start][1], locations[end][1]], [locations[start][0], locations[end][0]], c='red')
    plt.plot([locations[route[-1]][1], locations[route[0]][1]], [locations[route[-1]][0], locations[route[0]][0]], c='red')
    plt.title('Optimized Delivery Route')
    plt.xlabel('Longitude')
    plt.ylabel('Latitude')
    plt.legend()
    plt.grid(True)
    plt.show()

# Plot the route
plot_route(delivery_locations, optimized_route)

print("Optimized Route:", optimized_route)
print("Total Distance:", total_dist, "km")

From the code above, we can randomly create data using the libraries. We then calculate delivery locations between every pair. We minimize the objective function and optimize it afterwards using a simple greedy algorithm. Let us look at the result below.

Route Optimization Output
Route Optimization Output
Route Optimization Algorithm Result
Route Optimization Algorithm Result

Here [0,1,2,3] refers to [ San Francisco, Los Angeles, New York, Chicago ] as defined in the code above.

Conclusion

Here you go! Now you know how to optimize delivery routes, which is very important in operational efficiency. Moreover, we also learned how to leverage the power of Python programming language and its optimization algorithms to achieve our purpose.

Hope you enjoyed reading it!!

Recommended: Converting Between Pytorch Tensors and Numpy Arrays in Python