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: idir
jest rastrem wartości kierunku przepływu. offset
odnosi się do komórki centralnej, która jest obecnie analizowana, i off
sprawdza każdego z sąsiadów tej komórki. does_it_flow_into_me
Wywoł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 */
}