Jednym bezpośrednim sposobem jest procedura rekurencyjna, która wykonuje następujące czynności przy każdym wywołaniu. Dane wejściowe do procedury to lista par, które zostały już wybrane, oraz lista wszystkich par.
- Oblicz najmniejszą liczbę, która nie jest jeszcze objęta listą wprowadzania. Dla pierwszego wywołania będzie to oczywiście 0, ponieważ nie wybrano żadnych par.
- Jeśli wszystkie liczby są uwzględnione, masz poprawną kombinację, wydrukuj ją i zwróć poprzedni krok. W przeciwnym razie najmniejsza liczba, która zostanie odkryta, to cel, do którego będziemy dążyć.
- Przeszukuj pary, szukając sposobu na pokrycie liczby docelowej. Jeśli nie ma, to po prostu wróć do poprzedniego poziomu rekurencji.
- Jeśli istnieje sposób na zakrycie numeru docelowego, wybierz pierwszy sposób i ponownie wywołaj całą procedurę rekurencyjnie, z wybraną parą dodaj do listy wybranych par.
- Kiedy to powróci, poszukaj następnego sposobu na pokrycie liczby docelowej parą, bez nakładania się na wcześniej wybraną parę. Jeśli znajdziesz taki, wybierz go i ponownie uruchom rekurencyjnie następną procedurę.
- Kontynuuj kroki 4 i 5, aż nie będzie już więcej sposobów na pokrycie liczby docelowej. Przejrzyj całą listę par. Gdy nie ma już poprawnych wyborów, wróć do poprzedniego poziomu rekurencji.
Sposobem na wizualizację tego algorytmu jest drzewo, którego ścieżki są sekwencjami nienakładających się par. Pierwszy poziom drzewa zawiera wszystkie pary zawierające 0. W powyższym przykładzie drzewo to
Korzeń
|
----------------
| | |
(0,1) (0,2) (0,3)
| | |
(2,3) (1,3) (1,2)
W tym przykładzie wszystkie ścieżki przez drzewo faktycznie dają poprawne kolekcje, ale na przykład, jeśli pominiemy parę (1,2), wówczas skrajnie prawa ścieżka będzie miała tylko jeden węzeł i nie powiedzie się wyszukiwanie w kroku 3.
Algorytmy wyszukiwania tego typu można opracować dla wielu podobnych problemów z wyliczaniem wszystkich obiektów określonego typu.
nn
sub cover {
i = 0;
while ( (i < n) && (covered[i] == 1 )) {
i++;
}
if ( i == n ) { print list; return;}
covered[i] = 1;
for ( j = 0; j < n; j++ ) {
if ( covered[j] == 0 ) {
covered[j] = 1;
push list, [i,j];
cover();
pop list;
covered[j] = 0;
}
}
covered[i] = 0;
}