Metodą, którą wdrożyłem w kilku językach i uważam, że używa ESRI (przepraszam, brak odniesień innych niż Jenson i Domingue cytowane w innym miejscu na tej stronie) jest rozpoczęcie od dostarczonej przez użytkownika komórki lub komórki „punktu krzepnięcia” na krawędzi siatki kierunku przepływu (fdr), zbadaj jej ośmiu sąsiadów, aby dowiedzieć się, który z nich wpływa bezpośrednio do bieżącej komórki, i przypisz te komórki do bieżącego „zlewu” w siatce wyjściowej. Następnie funkcja rekurencyjnie wywołuje się raz dla każdego z napływających sąsiadów. Proces ten powtarza się, aż wszystkie napływające komórki zostaną wyczerpane dla punktu krzepnięcia, a następnie powtórzy się dla wszystkich punktów krzepnięcia.
Algorytm rekurencyjny może być dość kosztowny, ponieważ może skończyć się próbą przechowywania dużej ilości danych w pamięci, konieczności zamiany / stronicowania na dysk, a zatem generalnie występuje spowolnienie operacji we / wy.
(patrz komentarz Whubera poniżej na temat różnych metod rekurencji, jeśli zamierzasz RYO)
_____________ EDYCJA _____________
Odkopałem mój stary kod C jako przykład (uwaga: chociaż większość pythonerów może chcieć uruchomić z pokoju, nie powinno być tak źle). Pomyślałem, że warto to zilustrować. Chociaż dopiero teraz pozornie zaznajomiłem się z rekurencją w pierwszej kolejności w stosunku do głębokości pierwszej, myślę, że moja rutyna jest naprawdę w pierwszej kolejności (i że mój opis języka naturalnego powyżej wprowadzał w błąd) w oparciu o ten komunikat o przepełnieniu stosu (mam nadzieję, że @ whuber lub inna osoba mądrzejsza ode mnie może potwierdzić / odmówić).
Kod: wyjaśnienie: idirjest rastrem wartości kierunku przepływu. offsetodnosi się do komórki centralnej, która jest obecnie analizowana, i offsprawdza każdego z sąsiadów tej komórki. does_it_flow_into_meWywołuje to inną funkcję, która zwraca wartość logiczną określającą, czy katalog przepływu sąsiedniej komórki wskazuje na bieżącą komórkę. Jeśli to prawda dla sąsiada, wróć do tej lokalizacji.
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 */
}