วิธีการหนึ่งที่ตรงคือขั้นตอนแบบเรียกซ้ำที่ทำต่อไปนี้ในแต่ละการร้องขอ อินพุตไปยังโพรซีเดอร์คือรายการของคู่ที่ถูกเลือกไว้แล้วและรายการของคู่ทั้งหมด
- คำนวณจำนวนที่น้อยที่สุดซึ่งไม่ได้กล่าวถึงในรายการอินพุต สำหรับการขอร้องครั้งแรกนี้จะเป็น 0 แน่นอนเพราะไม่มีการเลือกคู่
- หากมีการครอบคลุมตัวเลขทั้งหมดคุณมีชุดค่าผสมที่ถูกต้องพิมพ์ออกมาและส่งกลับขั้นตอนก่อนหน้า มิฉะนั้นจำนวนที่น้อยที่สุดที่ไม่ถูกค้นพบคือเป้าหมายที่เราจะตั้งเป้าหมายไว้
- ค้นหาผ่านคู่ที่กำลังมองหาวิธีที่จะครอบคลุมจำนวนเป้าหมาย หากไม่มีเลยให้กลับไปที่ระดับการเรียกซ้ำก่อนหน้านี้
- หากมีวิธีที่จะครอบคลุมหมายเลขเป้าหมายให้เลือกวิธีแรกและเรียกขั้นตอนทั้งหมดซ้ำอีกครั้งด้วยการเลือกคู่เพิ่มเข้าไปในรายการคู่ที่เลือก
- เมื่อมันกลับมาให้มองหาวิธีถัดไปเพื่อให้ครอบคลุมหมายเลขเป้าหมายด้วยคู่โดยไม่ทับซ้อนคู่ที่เลือกไว้ก่อนหน้านี้ หากคุณพบหนึ่งให้เลือกและเรียกซ้ำขั้นตอนต่อไปซ้ำ
- ดำเนินการขั้นตอนที่ 4 และ 5 ต่อไปจนกว่าจะไม่มีวิธีครอบคลุมจำนวนเป้าหมาย ผ่านรายการทั้งหมดของคู่ เมื่อไม่มีตัวเลือกที่ถูกต้องให้กลับไปที่ระดับก่อนหน้าของการสอบถามซ้ำ
วิธีการมองเห็นอัลกอริธึมนี้คือต้นไม้ที่มีเส้นทางเป็นลำดับของคู่ที่ไม่ทับซ้อนกัน ระดับแรกของต้นไม้มีคู่ทั้งหมดที่มี 0 สำหรับตัวอย่างข้างต้นต้นไม้คือ
ราก
|
----------------
| | |
(0,1) (0,2) (0,3)
| | |
(2,3) (1,3) (1,2)
ในตัวอย่างนี้เส้นทางทั้งหมดผ่านต้นไม้ให้คอลเลกชันที่ถูกต้องจริง แต่ตัวอย่างเช่นถ้าเราออกจากคู่ (1,2) แล้วเส้นทางขวาสุดจะมีเพียงหนึ่งโหนดและจะสอดคล้องกับการค้นหาในขั้นตอนที่ 3 ล้มเหลว
อัลกอริธึมการค้นหาประเภทนี้สามารถพัฒนาได้สำหรับปัญหาที่คล้ายคลึงกันหลายประการในการแจกแจงวัตถุทั้งหมดของประเภทเฉพาะ
มีข้อเสนอแนะว่าบางที OP หมายความว่าทุกคู่อยู่ในอินพุตไม่ใช่แค่ชุดของพวกเขาตามที่คำถามบอก ในกรณีนั้นอัลกอริทึมนั้นง่ายกว่ามากเพราะไม่จำเป็นต้องตรวจสอบว่าได้รับอนุญาตคู่ใดแล้ว ไม่จำเป็นแม้แต่สร้างชุดของคู่ทั้งหมด รหัสเทียมต่อไปนี้จะทำในสิ่งที่ OP ถาม นี่คือจำนวนการป้อนข้อมูล "รายการ" เริ่มออกเป็นรายการที่ว่างเปล่าและ "ปิด" เป็นอาร์เรย์ของความยาวเริ่มต้นได้ที่ 0 มันอาจจะทำให้ค่อนข้างมีประสิทธิภาพมากขึ้น แต่นั่นไม่ใช่เป้าหมายของฉันทันทีnnn
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;
}