Skip to content

Commit 46ba5cb

Browse files
thomaswmorrisThomas Morris
andauthored
Remove ortools as a dependency (#115)
* add a bunch of documentation * add more documentation * refactor routing with python-tsp --------- Co-authored-by: Thomas Morris <thomas.w.morris@yale.edu>
1 parent 4b3a92d commit 46ba5cb

File tree

2 files changed

+15
-37
lines changed

2 files changed

+15
-37
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ dependencies = [
2323
"matplotlib",
2424
"numpy",
2525
"ophyd",
26-
"ortools",
26+
"python-tsp",
2727
"scipy",
2828
"tables",
2929
"torch",

src/blop/utils/__init__.py

Lines changed: 14 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import numpy as np
33
import scipy as sp # type: ignore[import-untyped]
44
import torch
5-
from ortools.constraint_solver import pywrapcp, routing_enums_pb2 # type: ignore[import-untyped]
5+
from python_tsp.heuristics import solve_tsp_simulated_annealing # type: ignore[import-untyped]
66

77
from . import functions # noqa
88

@@ -95,45 +95,23 @@ def route(start_point: np.ndarray, points: np.ndarray, dim_weights: float | np.n
9595
Returns the indices of the most efficient way to visit `points`, starting from `start_point`.
9696
"""
9797

98-
total_points = np.r_[np.atleast_2d(start_point), points]
99-
points_scale = np.ptp(total_points, axis=0)
100-
dim_mask = points_scale > 0
98+
total_points = np.concatenate(
99+
[start_point[None], points], axis=0
100+
) # add the starting point, even though we won't go there
101+
points_dim_range = np.ptp(total_points, axis=0)
102+
dim_mask = points_dim_range > 0
103+
scaled_points = (total_points - total_points.min(axis=0)) * (
104+
dim_weights / np.where(points_dim_range > 0, points_dim_range, 1)
105+
)
106+
D = np.sqrt(np.square(scaled_points[:, None, :] - scaled_points[None, :, :]).sum(axis=-1))
107+
D = (D / np.where(D > 0, D, np.inf).min()).astype(int)
108+
D[:, 0] = 0 # zero cost to return, since we don't care where we end up
101109

102110
if dim_mask.sum() == 0:
103111
return np.arange(len(points))
104112

105-
scaled_points = (total_points - total_points.min(axis=0)) * (dim_weights / np.where(points_scale > 0, points_scale, 1))
106-
107-
delay_matrix = np.sqrt(np.square(scaled_points[:, None, :] - scaled_points[None, :, :]).sum(axis=-1))
108-
delay_matrix = (1e4 * delay_matrix).astype(int) # it likes integers idk
109-
110-
manager = pywrapcp.RoutingIndexManager(len(total_points), 1, 0) # number of depots, number of salesmen, starting index
111-
routing = pywrapcp.RoutingModel(manager)
112-
113-
def delay_callback(from_index, to_index):
114-
to_node = manager.IndexToNode(to_index)
115-
if to_node == 0:
116-
return 0 # it is free to return to the depot from anywhere; we just won't do it
117-
from_node = manager.IndexToNode(from_index)
118-
return delay_matrix[from_node][to_node]
119-
120-
transit_callback_index = routing.RegisterTransitCallback(delay_callback)
121-
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
122-
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
123-
search_parameters.first_solution_strategy = routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC
124-
125-
solution = routing.SolveWithParameters(search_parameters)
126-
127-
index = routing.Start(0)
128-
route_indices, route_delays = [0], []
129-
while not routing.IsEnd(index):
130-
previous_index = index
131-
index = solution.Value(routing.NextVar(index))
132-
route_delays.append(routing.GetArcCostForVehicle(previous_index, index, 0))
133-
route_indices.append(index)
134-
135-
# omit the first and last indices, which correspond to the start
136-
return np.array(route_indices)[1:-1] - 1
113+
permutation, _ = solve_tsp_simulated_annealing(D / np.where(D > 0, D, np.inf).min())
114+
return np.array(permutation[1:]) - 1 # ignore the starting point since we're there already
137115

138116

139117
def get_movement_time(x: float | np.ndarray, v_max: float, a: float) -> float | np.ndarray:

0 commit comments

Comments
 (0)