Doğrudan bir yol, her başvuruda aşağıdakileri yapan özyinelemeli bir prosedürdür. Prosedürün girişi, daha önce seçilmiş olan çiftlerin ve tüm çiftlerin bir listesidir.
- Giriş listesi tarafından kapsanmayan en küçük sayıyı hesaplayın. İlk çağrı için, elbette 0 olacaktır, çünkü hiçbir çift seçilmedi.
- Tüm numaralar kaplanmışsa, doğru bir kombinasyonunuz vardır, yazdırın ve önceki adıma geri dönün. Aksi halde, ele geçen en küçük sayı hedefleyeceğimiz hedeftir.
- Hedef numarayı kapsayacak bir yol arayan çiftleri arayın. Eğer yoksa, o zaman önceki özyinelemeye geri dönün.
- Hedef numarayı gizlemenin bir yolu varsa, ilk yolu seçin ve tekrar tekrar tüm işlemi tekrar arayın, seçilen çiftler seçilen çiftlerin listesine eklenir.
- Bu geri döndüğünde, daha önce seçilen bir çifti üst üste binmeden hedef numarayı bir çift ile örtmek için bir sonraki yolu arayın . Bir tane bulursanız, onu seçin ve tekrarlı olarak bir sonraki prosedürü çağırın.
- Hedef numarayı kapatacak başka yol bulunmayana kadar 4. ve 5. adımlara devam edin. Tüm çiftlerin listesine göz atın. Başka doğru seçenek olmadığında, önceki özyinelemeye geri dönün.
Bu algoritmayı görselleştirmenin yolu, yolları örtüşmeyen çiftlerin dizileri olan bir ağaçtır. Ağacın ilk seviyesi, 0 içeren tüm çiftleri içerir. Yukarıdaki örnekte, ağaç
Kök
|
----------------
| | |
(0,1) (0,2) (0,3)
| | |
(2,3) (1,3) (1,2)
Bu örnekte, ağaçtaki tüm yollar aslında doğru koleksiyonlar verir, ancak örneğin çifti (1,2) dışarıda bırakırsak, en sağdaki yol yalnızca bir düğüme sahip olur ve 3. adımdaki aramaya karşılık gelir.
Bu tür arama algoritmaları, belirli bir türdeki tüm nesneleri numaralandırmada benzer birçok problem için geliştirilebilir.
Belki de OP’nin tüm çiftlerin girişte olduğu, sadece sorunun söylediği gibi bir dizi anlamına geldiği öne sürülmüştür . Bu durumda algoritma çok daha kolaydır çünkü hangi çiftlere izin verildiğini kontrol etmek artık gerekli değil. Tüm çiftlerin setini oluşturmak bile gerekli değildir; Aşağıdaki sözde kod OP'nin istediğini yapacaktır. Burada giriş numarasıdır, "liste" boş bir liste olarak başlar ve "örtülü" 0 ile başlayan n uzunluğundaki bir dizidir. Biraz daha verimli yapılabilir ama bu benim asıl amacım değil.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;
}