Un modo diretto è una procedura ricorsiva che procede come segue per ogni invocazione. L'input per la procedura è un elenco di coppie che sono già state scelte e un elenco di tutte le coppie.
- Calcola il numero più piccolo non già coperto dall'elenco di input. Per la prima invocazione, questo sarà ovviamente 0, perché non sono state scelte coppie.
- Se tutti i numeri sono coperti, hai una combinazione corretta, stampalo e ritorna al passaggio precedente. Altrimenti, il numero più piccolo che viene scoperto è l'obiettivo a cui mireremo.
- Cerca tra le coppie in cerca di un modo per coprire il numero di destinazione. Se non ce n'è, allora torna al precedente livello di ricorsione.
- Se esiste un modo per coprire il numero di destinazione, selezionare il primo modo e chiamare nuovamente in modo ricorsivo l'intera procedura, con la coppia appena selezionata aggiungere all'elenco delle coppie scelte.
- Quando ciò ritorna, cerca il modo successivo di coprire il numero di destinazione con una coppia, senza sovrapporre una coppia scelta in precedenza. Se ne trovi uno, selezionalo e chiama nuovamente in modo ricorsivo la procedura successiva.
- Continua i passaggi 4 e 5 fino a quando non ci sono più modi per coprire il numero di destinazione. Passa attraverso l'intero elenco di coppie. Quando non ci sono più scelte corrette, tornare al livello precedente della ricorsione.
Il modo per visualizzare questo algoritmo è con un albero i cui percorsi sono sequenze di coppie non sovrapposte. Il primo livello dell'albero contiene tutte le coppie che contengono 0. Per l'esempio sopra, l'albero è
Radice
|
----------------
| | |
(0,1) (0,2) (0,3)
| | |
(2,3) (1,3) (1,2)
In questo esempio tutti i percorsi attraverso l'albero forniscono effettivamente raccolte corrette, ma ad esempio se si escludesse la coppia (1,2), il percorso più a destra avrebbe solo un nodo e corrisponderebbe alla ricerca nel passaggio 3 non riuscita.
Algoritmi di ricerca di questo tipo possono essere sviluppati per molti problemi simili di enumerazione di tutti gli oggetti di un tipo particolare.
È stato suggerito che forse l'OP ha significato che tutte le coppie sono nell'input, non solo un insieme di esse come dice la domanda. In tal caso l'algoritmo è molto più semplice perché non è più necessario verificare quali coppie sono consentite. Non è nemmeno necessario generare l'insieme di tutte le coppie; il seguente pseudocodice farà ciò che l'OP ha chiesto. Qui è il numero di input, "list" inizia come un elenco vuoto e "coperto" è un array di lunghezza n inizializzato su 0. Potrebbe essere reso un po 'più efficiente ma non è il mio obiettivo immediato.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;
}