Create app.py
Browse files
app.py
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import numpy as np
|
| 2 |
+
import math
|
| 3 |
+
|
| 4 |
+
def euclidean(a, b):
|
| 5 |
+
return math.dist(a, b)
|
| 6 |
+
|
| 7 |
+
def clarke_wright(coords, demands, vehicle_capacity):
|
| 8 |
+
"""
|
| 9 |
+
coords: list of (x,y), first is depot
|
| 10 |
+
demands: list of demands (first is 0 for depot)
|
| 11 |
+
"""
|
| 12 |
+
N = len(coords) - 1
|
| 13 |
+
depot = 0
|
| 14 |
+
|
| 15 |
+
# Distance matrix
|
| 16 |
+
dist = [[euclidean(coords[i], coords[j]) for j in range(len(coords))] for i in range(len(coords))]
|
| 17 |
+
|
| 18 |
+
# Start with each customer in its own route
|
| 19 |
+
routes = [[0, i, 0] for i in range(1, N+1)]
|
| 20 |
+
loads = [demands[i] for i in range(1, N+1)]
|
| 21 |
+
|
| 22 |
+
# Compute savings
|
| 23 |
+
savings = []
|
| 24 |
+
for i in range(1, N+1):
|
| 25 |
+
for j in range(i+1, N+1):
|
| 26 |
+
s = dist[i][0] + dist[j][0] - dist[i][j]
|
| 27 |
+
savings.append((s, i, j))
|
| 28 |
+
savings.sort(reverse=True)
|
| 29 |
+
|
| 30 |
+
# Merge routes
|
| 31 |
+
for s, i, j in savings:
|
| 32 |
+
r_i = next((r for r in routes if r[1] == i or r[-2] == i), None)
|
| 33 |
+
r_j = next((r for r in routes if r[1] == j or r[-2] == j), None)
|
| 34 |
+
|
| 35 |
+
if r_i is None or r_j is None or r_i == r_j:
|
| 36 |
+
continue
|
| 37 |
+
|
| 38 |
+
if r_i[-2] == i and r_j[1] == j and (sum(demands[k] for k in r_i[1:-1]+r_j[1:-1]) <= vehicle_capacity):
|
| 39 |
+
new_route = r_i[:-1] + r_j[1:]
|
| 40 |
+
routes.remove(r_i)
|
| 41 |
+
routes.remove(r_j)
|
| 42 |
+
routes.append(new_route)
|
| 43 |
+
|
| 44 |
+
return routes, dist
|