A Clarke-Wright Savings algoritmus egy heurisztikus módszer a jármű útvonaltervezési probléma (Vehicle Routing Problem, VRP) megoldására. Az algoritmus célja, hogy minimalizálja a járművek által megtett távolságot, miközben betartja a járművek kapacitáskorlátait.
- Kezdetben minden ügyfélhez külön járművet rendelünk, amelyek mind a raktárból indulnak és oda térnek vissza. - Példa: Ha három ügyfél van, az útvonalak: , ahol a raktár.
- Minden két ügyfél között kiszámítjuk a megtakarítás értéket: ahol: * : A raktár és az -edik ügyfél közötti távolság. * : A raktár és a -edik ügyfél közötti távolság. * : Az -edik és -edik ügyfél közötti távolság.
- A megtakarításokat csökkenő sorrendbe rendezzük.
- A megtakarítások sorrendjében megpróbáljuk összefűzni az ügyfeleket egyetlen útvonalra, ha a következő feltételek teljesülnek: * Az összesített igény nem lépi túl a jármű kapacitását. * Az ügyfelek nem kerülnek többször az útvonalra.
- Az algoritmus végén kapott útvonalak minimalizálják a teljes távolságot.
Az alábbi kód a Clarke-Wright Savings algoritmus implementációját mutatja be.
import math
def distance(a, b):
"""Két pont közötti euklideszi távolság."""
return math.sqrt((a - b)**2 + (a - b)**2)
def clarke_wright(customers, depot, capacity, demands):
"""
Clarke-Wright Savings algoritmus a VRP megoldására.
Args:
customers: Az ügyfelek koordinátái .
depot: A raktár koordinátái (x, y).
capacity: A jármű kapacitása.
demands: Az ügyfelek igényei .
Returns:
routes: A járművek optimális útvonalai.
"""
n = len(customers)
# Távolságok számítása
distances = , customers) for j in range(n)] for i in range(n)]
depot_distances = ) for i in range(n)]
# Savings értékek számítása
savings =
for i in range(n):
for j in range(i + 1, n):
s = depot_distances + depot_distances - distances
savings.append(((i, j), s))
savings.sort(key=lambda x: x, reverse=True)
# Kezdeti útvonalak (egy ügyfél per jármű)
routes = for i in range(n)]
route_demands = for i in range(n)]
# Savings alkalmazása
for (i, j), _ in savings:
route_i = next((r for r in routes if i in r), None)
route_j = next((r for r in routes if j in r), None)
if route_i != route_j and route_demands + route_demands <= capacity:
# Összekötjük az útvonalakat
routes.remove(route_i)
routes.remove(route_j)
new_route = route_i + route_j
routes.append(new_route)
route_demands.append(route_demands.pop(routes.index(route_i)) + route_demands.pop(routes.index(route_j)))
return routes
# Példa bemenet
customers = # Ügyfél koordináták
depot = (0, 0) # Raktár koordinátái
capacity = 15 # Jármű kapacitása
demands = # Ügyféligények
routes = clarke_wright(customers, depot, capacity, demands)
print("Optimális útvonalak:", routes)
Optimális útvonalak: , ]
Magyarázat:
Csomagszállítás optimalizálása.
Az ellátási lánc hatékonyságának javítása.
Tömegközlekedési útvonalak optimalizálása.
A Clarke-Wright Savings algoritmus egy hatékony heurisztikus módszer, amely gyorsan képes megoldani a jármű útvonaltervezési problémát. Egyszerű implementációja és hatékony működése miatt gyakran alkalmazzák kisebb logisztikai problémákban. Nagyobb méretű vagy komplex korlátozásokkal rendelkező problémák esetén azonban érdemes metaheurisztikus módszereket (pl. genetikus algoritmus) alkalmazni.