Метод, який я реалізував на декількох мовах і вважаю, що ESRI використовує (вибачте, жодних посилань, окрім Jenson та Domingue, цитованих в інших місцях на цій сторінці), - це запустити в надану користувачем клітинку "point-point" або клітинку на краю сітки напрямку потоку (fdr) вивчіть вісім його сусідів, щоб знайти, хто з цих прямих потоків в поточну комірку, і призначити ці комірки поточному "вододілу" у вихідній сітці. Потім функція рекурсивно викликає себе один раз для кожного з припливних сусідів. Цей процес повторюється до тих пір, поки всі осередки, що надходять, не будуть вичерпані для точки виливу, а потім повторяться для всіх точок виливу.
Дизайн рекурсивного алгоритму може бути досить дорогим, оскільки він може закінчитися спробою зберігати багато даних в пам'яті, потребуючи поміняти сторінку / сторінку на диск, а отже, загалом страждає повільний спад.
(див. коментар Ваубера нижче щодо різних методів рекурсії, якщо ви збираєтесь RYO)
_____________ РЕДАКЦІЯ _____________
Прикладіть мій старий код С як приклад (зауважте: Хоча більшість пітонерів, можливо, захоче бігти з кімнати, це не повинно бути дуже погано). Думав, що це може бути цікаво проілюструвати. Хоча я лише зараз поверхово знайомий з першою глибиною та глибиною першою рекурсією, я думаю, що моя рутина справді є глибиною першою (і що мій опис природної мови вище був оманливим) на основі цієї публікації stackoverflow (сподіваюсь @ whuber чи інша людина, розумніша за мене, може підтвердити / заперечити).
Код: пояснення: idir
це растр значень напрямку потоку. offset
відноситься до центральної комірки, яка в даний час аналізується, і off
перевіряє кожного з сусідів цієї комірки. Це викликає іншу функцію, does_it_flow_into_me
яка повертає булеве значення про те, чи вказує потоковий сигнал сусідньої комірки на поточну комірку. Якщо вірно для сусіда, то поверніться до цього місця.
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 */
}