Метод, который я реализовал на нескольких языках и считаю, что ESRI использует (извините, никаких ссылок, кроме Дженсона и Доминге, процитированных в другом месте на этой странице), состоит в том, чтобы начать с предоставленной пользователем ячейки "точки застывания" или ячейки на краю сетки направления потока (fdr), исследуйте ее восемь соседей, чтобы найти, какой из этих прямых течет в текущую ячейку, и назначьте эти ячейки текущему «водоразделу» в выходной сетке. Затем функция рекурсивно вызывает себя один раз для каждого из входящих соседей. Этот процесс повторяется до тех пор, пока все входящие клетки не будут исчерпаны для точки застывания, а затем будет повторяться для всех точек застывания.
Проектирование рекурсивного алгоритма может быть довольно дорогим, потому что в конечном итоге он может пытаться удержать много данных в памяти, вынужден перенести страницу на диск и, как правило, испытывать замедление ввода-вывода.
(см. ниже комментарий Вубера о различных методах рекурсии, если вы собираетесь RYO)
_____________ РЕДАКТИРОВАТЬ _____________
В качестве примера выкопали мой старый C-код (примечание: хотя большинство питонеров могут захотеть бежать из комнаты, это не должно быть слишком плохо). Думаю, это может быть интересно проиллюстрировать. Несмотря на то, что я только сейчас поверхностно знаком с рекурсией в ширину и глубиной, я думаю, что моя рутина действительно в глубину (и что мое описание на естественном языке выше вводит в заблуждение), основываясь на этой публикации в стеке (надеюсь, @) whuber или другой человек умнее меня может подтвердить / опровергнуть).
Код: объяснение: idir
это растр значений направления потока. offset
относится к центральной ячейке, которая в настоящее время анализируется, и off
проверяет каждого из соседей этой ячейки. Это вызывает другую функцию, does_it_flow_into_me
которая возвращает логическое значение относительно того, указывает ли flowdir соседней ячейки на текущую ячейку. Если верно для соседа, вернитесь в это место.
void shed(int init_x, int init_y, int basin_id){
int i, j, offset, off, flow_dir;
offset = ((init_y - 1) * nc) + (init_x - 1);
*(basin + offset) = basin_id;
/* kernel analysis */
for (i = -1; i < 2; i++) {
for (j = -1; j < 2; j++) {
if ((i) || (j)) {
off = offset + (j * nc + i);
flow_dir = *(idir + off);
if (does_it_flow_into_me(i,j,flow_dir)){
shed(init_x+i, init_y+j,basin_id);
}
} /*not center */
} /* do - j */
} /* do - i */
}