Это должно быть возможно гораздо эффективнее, напрямую взаимодействуя с классом skimage.graph.MCP
Cython.Удобная оболочка route_through_array
недостаточно универсальна.Предполагая, что я правильно понимаю ваш вопрос, вам нужен метод MCP.find_costs()
.
Ваш код будет выглядеть так (без импорта)
img = np.random.rand(400,400)
img = img.astype(dtype=int)
starts = [[1,1], [2,2], [3,3], [4,5], [6,17]]
ends = [[301,201], [300,300], [305,305], [304,328], [336,317]]
# Pass full set of start and end points to `MCP.find_costs`
from skimage.graph import MCP
m = MCP(img)
cost_array, tracebacks_array = m.find_costs(starts, ends)
# Transpose `ends` so can be used to index in NumPy
ends_idx = tuple(np.asarray(ends).T.tolist())
costs = cost_array[ends_idx]
# Compute exact minimum cost path to each endpoint
tracebacks = [m.traceback(end) for end in ends]
Обратите внимание, что необработанный вывод cost_array
на самом деле является полностью плотным массивом той же формы, что и img
, который имеет конечные значения только там, где вы запрашивали конечные точки.Единственная возможная проблема с этим подходом - это если минимальный путь из более чем одной начальной точки сходится к одной и той же конечной точке.Полный код трассировки вы получите только для нижнего из этих конвергентных путей с помощью приведенного выше кода.
Шаг трассировки по-прежнему имеет цикл.Это, вероятно, можно удалить, используя tracebacks_array
и взаимодействуя с `m.offsets, что также устранит неоднозначность, отмеченную выше.Однако, если вам нужны только минимальная стоимость (и) и лучший путь (и), этот цикл можно пропустить - просто найдите минимальную стоимость с помощью argmin и проследите эту единственную конечную точку (или несколько конечных точек, если несколько связаны для наименьшего) назад.