Código Clarke

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 3

Código Clarke-Wright

from typing import List, Tuple

def create_data_model():
data = {}

data['locations'] = [[0, 850, 1000, 3700, 850, 1200],


[800, 0, 1200, 3900, 1300, 1700],
[900, 1800, 0, 2800, 850, 750],
[3800, 3600, 2800, 0, 3400, 3300],
[700, 1500, 800, 3400, 0, 650],
[1100, 1900, 750, 3300, 650, 0]]
data['num_locations'] = len(data['locations'])
data['time_windows'] = [
(0, 0),
(0, 90),
(0, 90),
(0, 90),
(0, 90),
(0, 90)
]

data['demands'] = \
[0,
50,
70,
50,
30,
50]
data['time_per_demand_unit'] = 0.1
data['num_vehicles'] = 1
data['vehicle_capacity'] = 250
data['vehicle_speed'] = 417
data['depot'] = 0
return data

def savings(data: dict) -> List[Tuple[int,int,float]]:


depot = data['depot']
locations = data['locations']
num_locations = data['num_locations']
savings = []
for i in range(num_locations):
if i == depot:
continue
for j in range(i+1,num_locations):
if j == depot:
continue
saving = locations[i][depot] + locations[depot][j] -
locations[i][j]
savings.append((i,j,saving))
savings.sort(key=lambda x: x[2], reverse=True)
return savings

def merge_routes(route1: List[int], route2: List[int], data: dict) ->


List[int]:
new_route = []
if route1[-1] == data['depot'] and route2[0] == data['depot']:
new_route = route1[:-1] + route2[1:]
elif route2[-1] == data['depot'] and route1[0] == data['depot']:
new_route = route2[:-1] + route1[1:]
return new_route

def check_capacity(route: List[int], data: dict) -> bool:


demand = 0
for node in route:
demand += data['demands'][node]
if demand > data['vehicle_capacity']:
return False
return True

def clarke_wright(data: dict) -> List[List[int]]:


savings_list = savings(data)
routes = [[data['depot'], i, data['depot']] for i in
range(data['num_locations']) if i != data['depot']]
for saving in savings_list:
i, j, _ = saving
i_route = None
j_route = None
for route in routes:
if i in route:
i_route = route
if j in route:
j_route = route
if i_route and j_route:
break
if i_route != j_route:
new_route = merge_routes(i_route, j_route, data)
if new_route and check_capacity(new_route, data):
routes.remove(i_route)
routes.remove(j_route)
routes.append(new_route)
check_capacity(new_route, data) # Verifica a capacidade
da nova rota
return routes

def print_clarke_wright_solution(routes: List[List[int]], data: dict):


total_distance = 0
total_load = 0
total_time = 0
for vehicle_id, route in enumerate(routes):
route_distance = 0
route_load = 0
route_time = 0
plan_output = f'Route for vehicle {vehicle_id}: '
for i in range(len(route)-1):
from_node = route[i]
to_node = route[i+1]
route_distance += data['locations'][from_node][to_node]
route_load += data['demands'][to_node]
route_time += data['locations'][from_node][to_node] /
data['vehicle_speed']
route_time += data['demands'][to_node] *
data['time_per_demand_unit']
plan_output += f'{from_node} Load({route_load}) -> '
plan_output += f'{route[-1]}'
plan_output += f'\nDistance of the route: {route_distance}m\n'
plan_output += f'Load of the route: {route_load}\n'
plan_output += f'Time of the route: {route_time}m\n'
print(plan_output)
total_distance += route_distance
total_load += route_load
total_time += route_time
print(f'Total Distance of all routes: {total_distance}m')
print(f'Total Load of all routes: {total_load}')
print(f'Total Time of all routes: {round(total_time,2)}min')

data = create_data_model()
routes = clarke_wright(data)
print_clarke_wright_solution(routes, data)

You might also like