รอบในซอฟต์แวร์ต้นไม้ครอบครัว


1594

ฉันเป็นผู้พัฒนาซอฟต์แวร์แผนภูมิต้นไม้บางตระกูล (เขียนด้วยภาษา C ++ และ Qt) ฉันไม่มีปัญหาจนกระทั่งลูกค้าคนใดคนหนึ่งส่งรายงานข้อผิดพลาดถึงฉัน ปัญหาคือลูกค้ามีลูกสองคนพร้อมกับลูกสาวของตนเองและทำให้เขาไม่สามารถใช้ซอฟต์แวร์ของฉันได้เนื่องจากข้อผิดพลาด

ข้อผิดพลาดเหล่านั้นเป็นผลมาจากการยืนยันและค่าคงที่ต่างๆของฉันเกี่ยวกับกราฟครอบครัวที่กำลังประมวลผล (ตัวอย่างเช่นหลังจากเดินรอบโปรแกรมระบุว่า X ไม่สามารถเป็นทั้งพ่อและปู่ของ Y)

ฉันจะแก้ไขข้อผิดพลาดเหล่านั้นโดยไม่ลบการยืนยันข้อมูลทั้งหมดได้อย่างไร



30
หากคุณติดตามแผนภูมิต้นไม้ครอบครัวของคุณย้อนหลังไปไกลพอคุณจะพบปัญหานี้บ่อยกว่าที่คุณต้องการ การละทิ้งการแสดงต้นไม้อาจเจ็บปวด แต่ในที่สุดก็จะถูกต้องมากขึ้น
โทมัส

55
คุณไม่ควรเพิ่มการยืนยันสิ่งที่ไม่น่าเป็นไปได้ แต่สิ่งที่เป็นไปไม่ได้ รอบเป็นสิ่งที่ชัดเจนที่เป็นไปไม่ได้ในกราฟต้นไม้ครอบครัว ... ไม่มีใครสามารถเป็นบรรพบุรุษของเขาได้ด้วยวิธีการใด ๆ การยืนยันอื่น ๆ เหล่านี้เป็นเพียงการปลอมและควรถูกลบออก
pgod

44
นี่ไม่ใช่คำถามโง่ ๆ ในโลกของการเพาะพันธุ์สัตว์เลี้ยง ลูกสาวกับพ่อแม่กับลูกน้องสาวกับน้องชายหลานกับปู่ย่าตายายเป็นเทคนิคมาตรฐานที่นั่นและพ่อพันธุ์แม่พันธุ์สัตว์เลี้ยงต้องการซอฟต์แวร์ต้นไม้ครอบครัวด้วย "พันธุ์แท้" ¤% # & ของฉัน
kaleissin

31
การแต่งงานกับญาติคนแรกเป็นเรื่องธรรมดามากในวิคตอเรียอังกฤษโดยเฉพาะอย่างยิ่งในหมู่ชนชั้นสูง (มันเป็นวิธีที่ยอดเยี่ยมในการเก็บเงินภายในครอบครัว) ตัวอย่างเช่นชาร์ลส์ดาร์วินแต่งงานกับลูกพี่ลูกน้องคนแรกของเขาเอ็มม่าเวดวู้ด ซอฟต์แวร์แผนภูมิต้นไม้ใด ๆ จำเป็นต้องสนับสนุนสถานการณ์เช่นนี้
rtperson

คำตอบ:


727

ดูเหมือนว่าคุณ (และ / หรือ บริษัท ของคุณ) มีความเข้าใจผิดขั้นพื้นฐานเกี่ยวกับต้นไม้ตระกูลที่ควรจะเป็น

ให้ฉันอธิบายฉันยังทำงานให้กับ บริษัท ที่มีต้นไม้ครอบครัวในผลงานของเรา (และเป็นหนึ่งในผลิตภัณฑ์ของ บริษัท ) และเรากำลังดิ้นรนกับปัญหาที่คล้ายกัน

ในกรณีของเราและฉันคิดว่ากรณีของคุณมาจากรูปแบบGEDCOMที่ให้ความเห็นอย่างมากเกี่ยวกับสิ่งที่ครอบครัวควรจะเป็น อย่างไรก็ตามรูปแบบนี้มีความเข้าใจผิดที่รุนแรงเกี่ยวกับลักษณะต้นไม้ครอบครัว

GEDCOM มีปัญหามากมายเช่นความไม่ลงรอยกันกับเพศเดียวกันการร่วมประเวณีระหว่างพี่น้องและอื่น ๆ ... ซึ่งในชีวิตจริงเกิดขึ้นบ่อยกว่าที่คุณคาดคิด

เราสร้างแบบจำลองต้นไม้ครอบครัวของเรากับสิ่งที่เกิดขึ้นในโลกแห่งความจริง: กิจกรรม (ตัวอย่างเช่นการเกิดงานแต่งงานการมีส่วนร่วมสหภาพแรงงานการเสียชีวิตการรับอุปการะ ฯลฯ ) เราไม่วางข้อ จำกัด ใด ๆ ในสิ่งเหล่านี้ยกเว้นสิ่งที่เป็นไปไม่ได้ในเชิงตรรกะ (ตัวอย่างเช่นเราไม่สามารถเป็นพ่อแม่ของตัวเองได้ความสัมพันธ์นั้นต้องการบุคคลสองคน ฯลฯ ... )

การขาดการตรวจสอบความถูกต้องทำให้เรามี "โลกแห่งความเป็นจริง" มากขึ้นง่ายขึ้นและมีความยืดหยุ่นมากขึ้น

สำหรับกรณีเฉพาะนี้ฉันขอแนะนำให้นำคำยืนยันออกเนื่องจากพวกเขาไม่ถือเป็นสากล

สำหรับการแสดงปัญหา (ที่จะเกิดขึ้น) ฉันขอแนะนำให้วาดโหนดเดียวกันหลาย ๆ ครั้งตามต้องการโดยให้คำแนะนำในการทำซ้ำโดยให้แสงสำเนาทั้งหมดเกี่ยวกับการเลือกหนึ่งในนั้น


32
ดูเหมือนว่าวิธีการที่ถูกต้องและเป็นเรื่องง่ายที่จะขยายเพื่อตรวจสอบปัญหาที่ซับซ้อนมากขึ้น คุณสามารถกำหนดความสัมพันธ์ "A ที่เกิดขึ้นก่อน B" ระหว่างเหตุการณ์ได้ ตัวอย่างเช่นบุคคลหนึ่งเกิดก่อนเหตุการณ์อื่นใดที่เกี่ยวข้องกับพวกเขา นี่คือกราฟกำกับ จากนั้นคุณสามารถตรวจสอบว่ากราฟไม่มีรอบ ดูคำถามนี้ใน StackOverflow นี่ควรจะโอเคจนกว่าจะมีการคิดค้นการเดินทางข้ามเวลา
พอลแฮร์ริสัน

41
@ paul-harrison ถ้ามันง่ายตรงไหน ในบันทึกเก่า (แม้กระทั่งใหม่) มีความไม่สอดคล้องกันของวันที่ บัพติสมาก่อนเกิดบันทึกการเกิดหลายครั้ง ฯลฯ ... ดังนั้นในขอบเขตที่เป็นทางการมีการเดินทางข้ามเวลา เราอนุญาตข้อมูลที่ไม่สอดคล้องกันนี้ เราอนุญาตให้ผู้ใช้ระบุสิ่งที่แอปพลิเคชันควรพิจารณา "บันทึก" วันเกิดในกรณีที่ซ้ำกัน และเราจะระบุระยะเวลาที่แตกถ้าพบ
Bert Goethals

38
@ ben-voigt GEDCOM เป็นรูปแบบที่สร้างขึ้นโดยศาสนจักรของพระเยซูคริสต์แห่งวิสุทธิชนยุคสุดท้าย ข้อกำหนดระบุไว้อย่างชัดเจนว่าการแต่งงาน (MARR) จะต้องอยู่ระหว่างชายและหญิง สำหรับการแต่งงานเพศเดียวกันหรือการร่วมประเวณีระหว่างพี่น้องควรใช้แท็ก ASSO (ASSOCIATES) เพื่อระบุมิตรภาพหรือการเป็นเพื่อนบ้าน เห็นได้ชัดว่าการแต่งงานเพศเดียวกันนั้นมีความสัมพันธ์ระดับสองภายในสเป็คนี้ สเป็คที่เป็นกลางมากขึ้นจะไม่เรียกร้องความสัมพันธ์หญิงชาย
Bert Goethals

1
@Bert Goethals: คุณกำลังสับสนกับ GEDCOM กับบางโปรแกรมที่ไม่สนับสนุนการแต่งงานเพศเดียวกัน (PAF, Legacy) GEDCOM ไม่ได้ห้ามการสร้างเช่น "0 @ F1 @ FAM / 1 HUSB @ I1 @ / 1 HUSB @ I2 @" ดังนั้นจึงสนับสนุนการแต่งงานเพศเดียวกันหากซอฟต์แวร์ของคุณเลือก
ปิแอร์

1
@ เปียโนคุณสามารถโกงระบบได้อย่างแน่นอน สิ่งนี้มาโดยตรงจากเอกสาร 5.5.1: "MARR {MARRIAGE}: = เหตุการณ์ทางกฎหมายกฎหมายทั่วไปหรือเหตุการณ์ที่เกิดขึ้นตามประเพณีของการสร้างหน่วยครอบครัวของชายและหญิงในฐานะสามีและภรรยา" ( homepages.rootsweb.ancestry.com/~pmcbride/gedcom/55gcappa.htm ) อย่างที่คุณเห็นไม่มีการแต่งงานเพศเดียวกันที่นี่
Bert Goethals

563

ผ่อนคลายคำพูดของคุณ

ไม่ใช่โดยการเปลี่ยนกฎซึ่งส่วนใหญ่มีประโยชน์มากกับ 99.9% ของลูกค้าของคุณในการจับข้อผิดพลาดในการป้อนข้อมูลของพวกเขา

ให้เปลี่ยนจากข้อผิดพลาด "ไม่สามารถเพิ่มความสัมพันธ์" เป็นคำเตือนด้วย "เพิ่มต่อไป" แทน


143
เมื่อพบกับสถานการณ์ที่ไม่น่าเป็นไปได้นั่นคือที่ที่ผู้ใช้มักจะทำโดยไม่ได้ตั้งใจเท่านั้นมันเป็นความคิดที่ดีที่จะแสดงคำเตือนให้กับผู้ใช้ นั่นเป็นข้อเสนอแนะที่ดี แต่จากนั้นให้ผู้ใช้ไปข้างหน้าหากพวกเขาแน่ใจจริงๆว่าพวกเขาต้องการ ดังนั้นฉันคิดว่านี่เป็นคำตอบที่ดีแม้ว่ามันจะไม่เข้ากับน็อตและสลักเกลียวของวิธีการ
thomasrutter

15
คำตอบที่ดี! ฉันแค่สงสัยว่าซอฟต์แวร์ประเภทนี้จะจัดการกับสถานการณ์ "ฉันเป็นคุณปู่ของฉันเอง" ( youtube.com/watch?v=eYlJH81dSiw ) อย่างไร
Zaur Nasibov

4
นี่ไม่ใช่คำตอบจริงๆเพราะฉันคิดว่าปัญหามาจากการสำรวจต้นไม้จริงหรือ อย่างไรก็ตามมันเป็นข้อเสนอแนะที่ดี
bdwakefield

3
@bdwakefield: คำถามคือ "ฉันจะแก้ไขข้อผิดพลาดเหล่านี้ได้อย่างไรโดยไม่ลบการยืนยันข้อมูลทั้งหมด" ฉันเชื่อว่าฉันตอบว่า
Ben Voigt

2
@Ben มันขึ้นอยู่กับสิ่งที่ยืนยันสำหรับ หากพวกเขาป้องกันลูปไม่สิ้นสุดหรือข้อผิดพลาดร้ายแรงเกิดขึ้นจากนั้นคุณจะแนะนำให้ลบการยืนยัน หากพวกเขาอยู่ที่นั่นเพียงเพื่อเตือนผู้ใช้ถึงความผิดพลาดที่อาจเกิดขึ้นคำตอบของคุณก็ดี
rm999

224

นี่คือปัญหาเกี่ยวกับต้นไม้ครอบครัว: พวกเขาไม่ใช่ต้นไม้ พวกเขาเป็นผู้กำกับกราฟ acyclic หรือ DAG ถ้าฉันเข้าใจหลักการทางชีววิทยาของการสืบพันธุ์ของมนุษย์อย่างถูกต้องจะไม่มีวัฏจักรใด ๆ

เท่าที่ฉันรู้แม้แต่คริสเตียนก็ยอมรับการแต่งงานระหว่างลูกพี่ลูกน้องซึ่งจะทำให้ต้นไม้ครอบครัวกลายเป็น DAG ครอบครัว

คุณธรรมของเรื่องราวคือเลือกโครงสร้างข้อมูลที่เหมาะสม


7
มันจะต้องมีข้อ จำกัด เพิ่มเติมของทุกโหนดที่มี 1 หรือ 2 โหนดสูงสุดที่ชี้ไปยังมันสำหรับการเพาะเชื้อในหลอดทดลองและการสืบพันธุ์แบบอาศัยเพศ แม้ว่าจะเป็นเรื่องจริงมากขึ้นในชีวิตจริงคุณอาจอนุญาตให้มีเส้นประหลายเส้นสำหรับการสืบทอดที่ไม่แน่นอนในฝั่งพ่อ (เป็นที่ชัดเจนอยู่เสมอว่าแม่คือใคร แต่การทดสอบดีเอ็นเอเท่านั้นที่สามารถประกันได้ว่าพ่อเป็นใคร หรือแม้กระทั่งสำหรับการยอมรับทั้งสองอย่างจะถูกนำมาพิจารณา
manixrock

7
@manixrock - เนื่องจากคำถามนี้เกี่ยวกับกรณีที่เกิดขึ้นได้ยากฉันจึงขอยืนยันว่าไม่ชัดเจนว่าใครเป็นแม่ ลูกบุญธรรม, ทารกที่ถูกทอดทิ้ง, แม่ตัวแทนและอื่น ๆ ทั้งหมดสามารถทำให้เรื่องซับซ้อน
Peter Recore

9
มันไม่จำเป็นต้องเป็นวงจรใช่ไหม Man-แต่งงานยาย
Ed Ropple

13
ผู้ชายที่แต่งงานกับยายของเขาจะไม่ทำให้ตัวเองเป็นปู่ของเขาเองและเพิ่มวงจร หากพวกเขามีลูกมันจะเป็นขอบกราฟปกติที่ไม่ใช่การขี่จักรยาน
exDM69

11
จริงๆแล้วมันเป็น ADG สองตัว มีกราฟบิดามารดาและกราฟความสัมพันธ์ทางกฎหมาย โดยทั่วไปแล้วจะเหมือนกัน แต่อาจมีความแตกต่างมากกว่าหนึ่งอย่าง
JSacksteder

115

ฉันเดาว่าคุณมีค่าบางอย่างที่ระบุบุคคลที่คุณสามารถใช้เช็คของคุณ

นี่เป็นสิ่งที่ยุ่งยาก สมมติว่าคุณต้องการรักษาโครงสร้างต้นไม้ฉันแนะนำสิ่งนี้:

สมมติว่า: Aมีลูกพร้อมกับลูกสาวของเขาเอง

Aเพิ่มตัวเองกับโปรแกรมที่เป็นและเป็นA Bเมื่ออยู่ในบทบาทของพ่อเราเรียกว่าเป็นแฟน

เพิ่มis_same_for_out()ฟังก์ชั่นที่บอกเอาต์พุตที่สร้างส่วนของโปรแกรมของคุณว่าลิงก์ทั้งหมดที่ไปยังBภายในควรจะAนำเสนอข้อมูล

สิ่งนี้จะทำให้การทำงานพิเศษสำหรับผู้ใช้ แต่ฉันเดาว่ามันจะง่ายต่อการติดตั้งและบำรุงรักษา

การสร้างจากนั้นคุณสามารถทำงานกับการซิงค์รหัสAและBเพื่อหลีกเลี่ยงความไม่สอดคล้องกัน

วิธีการแก้ปัญหานี้ไม่สมบูรณ์แบบแน่นอน แต่เป็นวิธีแรก


9
อาจเป็น "พร็อกซี" โหนดดังกล่าวเป็นทางออกที่เหมาะสมแน่นอน อย่างไรก็ตามฉันไม่ทราบว่าจะสามารถใส่ส่วนต่อประสานผู้ใช้กับผู้ใช้ได้อย่างไร ฉันสามารถบอกคุณได้ว่าการเขียนซอฟต์แวร์ที่เกี่ยวข้องกับคนจริง (โดยเฉพาะลูกค้าของคุณ) ไม่ใช่เรื่องง่าย
Partick Höse

6
ไม่สิ้นสุด - ลูกชายคนใหม่ของ B จะเป็นลุงของเขาเอง ฉันจะพิจารณาคืนเงินเต็มจำนวนสำหรับโปรแกรม!
โบเพอร์สัน

3
@ จะ: แล้วก็ตระหนักว่าเขายังเป็นแม่ของตัวเองและชักชวนตัวเองที่อายุน้อยกว่าของเขาเข้าไปในหน่วยงานเวลา?
Null ตั้ง

2
การทำสำเนา (และการซิงค์) ข้อมูลภายในระบบเดียวเป็นการปฏิบัติที่ไม่ดี มันบ่งชี้ว่าวิธีการแก้ปัญหาย่อยที่ดีที่สุดและควรได้รับการพิจารณาใหม่ หากต้องการสร้างโหนดพิเศษ (ซ้ำ) จะต้องระบุว่าเป็นพร็อกซีและมอบหมายข้อมูลที่อ่านและเขียนไปยังโหนดดั้งเดิม
Bert Goethals

84

คุณควรเน้นจริงๆสิ่งที่ทำให้ค่าสำหรับซอฟต์แวร์ของคุณ เวลาที่ใช้ในการทำให้ผู้บริโภคหนึ่งรายคุ้มค่าราคาของใบอนุญาตหรือไม่ น่าจะไม่

ฉันแนะนำให้คุณขอโทษลูกค้ารายนี้บอกเขาว่าสถานการณ์ของเขาอยู่นอกขอบเขตสำหรับซอฟต์แวร์ของคุณและคืนเงินให้เขา


3
จริงแท้แน่นอน. แต่ยังชั่งน้ำหนักปัญหาที่อาจเกิดขึ้นอื่น ๆ ที่มีปัญหาคล้ายกันที่คนอื่น ๆ นำมา
ศ. Falken ผิดสัญญา

2
แน่นอน. เหตุผลก็คือ: หากเป็นกรณีที่เกิดขึ้นได้ยากในแอปพลิเคชั่นที่ไม่สำคัญคุณไม่จำเป็นต้องแก้ไขหรือใช้อะไรเลย หากการทำเช่นนั้นทำให้ผู้ใช้ของคุณเจ็บจริง ๆ ก็มีคุณค่าในการทำงานกับมัน
christopheml

10
อาจทุกคนมีบางกรณีของการร่วมประเวณีระหว่างพี่น้องของเขา / เธอ ดังนั้นคุณจะพบว่าชนถ้าขุดประวัติครอบครัว (เกินไป) ลึก
datenwolf

1
การสร้างลำดับวงศ์ตระกูลของสถานการณ์แปลก ๆ (ค่าเชื้อเชื้อสายฟริตซ์ ฯลฯ ) เป็นการใช้ซอฟต์แวร์ที่ถูกต้อง
Bulwersator

1
ซอฟต์แวร์ตระกูลต้นไม้ที่ไม่อนุญาตให้ลูกพี่ลูกน้องคนที่สองแต่งงานกันนั้นไร้ประโยชน์ เกือบทุกครอบครัวมีอย่างน้อยหนึ่งกรณีนี้ นี่คือเหตุผลที่ฉันคิดว่าตัวอย่างดั้งเดิมถูกสร้างขึ้นเพื่อให้ได้ผล
Fuzzy76

79

คุณควรตั้งตระกูลAtreides (ทั้งที่ทันสมัยDuneหรือ Ancient Oedipus Rex ) เป็นกรณีทดสอบ คุณไม่พบข้อบกพร่องโดยใช้ข้อมูลที่ถูกสุขอนามัยเป็นกรณีทดสอบ


2
น่าเศร้าที่หลาย ๆ คนคิดว่าข้อมูล 'โอเค' แทนที่จะเป็นกรณีขอบที่ทำให้ระบบแตก
sjas

59

นี่คือหนึ่งในเหตุผลที่ภาษาเช่น "Go" ไม่มีการยืนยัน พวกมันถูกใช้เพื่อจัดการกับกรณีที่คุณอาจไม่ได้คิดถึงบ่อยเกินไป คุณควรยืนยันเป็นไปไม่ได้ไม่เพียง แต่ไม่น่า การทำหลังเป็นสิ่งที่ให้การยืนยันชื่อเสียงที่ไม่ดี ทุกครั้งที่คุณพิมพ์assert(เดินไปสิบนาทีแล้วคิดถึงมันจริงๆ

ในกรณีที่รบกวนคุณโดยเฉพาะอย่างยิ่งเป็นไปได้และน่าตกใจว่าการยืนยันดังกล่าวจะเป็นการหลอกลวงภายใต้สถานการณ์ที่หายาก แต่เป็นไปได้ ดังนั้นจัดการกับมันในแอพของคุณถ้าจะพูดว่า "ซอฟต์แวร์นี้ไม่ได้ออกแบบมาเพื่อจัดการกับสถานการณ์ที่คุณนำเสนอ"

การยืนยันว่าปู่ทวดผู้ยิ่งใหญ่ผู้ยิ่งใหญ่ของคุณเป็นพ่อของคุณอย่างที่เป็นไปไม่ได้เป็นสิ่งที่ควรทำ

หากฉันทำงานให้กับ บริษัท ทดสอบที่ว่าจ้างให้ทดสอบซอฟต์แวร์ของคุณแน่นอนว่าฉันจะได้นำเสนอสถานการณ์นั้น ทำไม? เด็กและเยาวชนทุกคน 'ผู้ใช้' ที่ชาญฉลาดจะทำสิ่งเดียวกันและเพลิดเพลินกับผลลัพธ์ 'รายงานบั๊ก'


5
เห็นด้วยกับข้อโต้แย้ง 'เมื่อต้องใช้การยืนยัน'; ไม่เห็นว่าเกี่ยวข้องกับ 'บางภาษามีการยืนยันไปไม่ได้'
phooji

2
@Red Hue - บางครั้งคอมไพเลอร์ทำให้เป็นไปไม่ได้ ... เป็นไปได้ gcc บางรุ่นคิดว่า -10 == 10 ในการใช้งาน abs ()
Tim Post

2
@Red Hue: จุดยืนยันทั้งหมดคือการจัดทำเอกสารและเงื่อนไขการทดสอบที่ควรเป็นจริง (หรือเท็จ) มันช่วยป้องกันคุณ (และคนอื่น ๆ ) ไม่ให้ "แก้ไข" สิ่งต่าง ๆ ในลักษณะที่กรณีที่เป็นไปไม่ได้เกิดขึ้นจากนั้นพวกเขาก็จะแยกแอปอย่างชัดเจน หากมีเหตุผลที่ถูกต้องสำหรับกรณีที่ "เป็นไปไม่ได้" ปรากฏขึ้นแสดงว่าคุณยืนยันมากเกินไป
cHao

1
@cHao @Tim โพสต์ฉันแค่พยายามที่จะเข้าใจว่าทำไม Go to assertions จึงไม่เป็นสิ่งที่ดีเพราะพวกคุณส่วนใหญ่ยอมรับว่าการยืนยันเป็นสิ่งสำคัญ
Arlen

5
การมีการยืนยัน (หรือรหัสเหมือนการยืนยัน) นั้นไม่เกี่ยวข้อง รหัสในภาษาเช่น Go สามารถและจะทำให้สมมติฐานเกี่ยวกับโครงสร้างของข้อมูล มันไม่สามารถจัดทำเอกสารและบังคับใช้สมมติฐานเหล่านั้นด้วยการยืนยัน Bottom line: แอปพลิเคชันมีข้อบกพร่อง
Tommy McGuire

41

ฉันเกลียดการแสดงความคิดเห็นในสถานการณ์ที่สับสนเช่นนี้ แต่วิธีที่ง่ายที่สุดที่จะไม่คำนวณค่าคงที่ของคุณทั้งหมดอีกครั้งคือการสร้างจุดสุดยอดภาพหลอนในกราฟของคุณซึ่งทำหน้าที่เป็นพร็อกซี


37

ดังนั้นฉันทำงานซอฟต์แวร์ต้นไม้ครอบครัวมาบ้างแล้ว ฉันคิดว่าปัญหาที่คุณพยายามแก้ไขคือคุณต้องสามารถเดินบนต้นไม้ได้โดยไม่ต้องวนซ้ำไม่ จำกัด - กล่าวอีกนัยหนึ่งต้นไม้ต้องมีลักษณะเป็นวงรอบ

อย่างไรก็ตามดูเหมือนว่าคุณกำลังยืนยันว่ามีเพียงเส้นทางเดียวระหว่างบุคคลและหนึ่งในบรรพบุรุษของพวกเขา รับรองได้ว่าจะไม่มีรอบ แต่ก็เข้มงวดเกินไป การพูดคุยทางชีวภาพการลงตำแหน่งเป็นกราฟที่มีการนำทาง (DAG) กรณีที่คุณมีเป็นกรณีที่เลวลงอย่างแน่นอน แต่สิ่งประเภทนั้นเกิดขึ้นตลอดเวลาบนต้นไม้ขนาดใหญ่

ตัวอย่างเช่นหากคุณดูบรรพบุรุษ 2 ^ n คุณมีรุ่นที่ n หากไม่มีการเหลื่อมกันคุณจะมีบรรพบุรุษมากกว่า 1,000 AD กว่าคนที่ยังมีชีวิตอยู่ ดังนั้นจะต้องมีการทับซ้อนกัน

อย่างไรก็ตามคุณมักจะได้รับรอบที่ไม่ถูกต้องเพียงข้อมูลที่ไม่ดี หากคุณกำลังสำรวจต้นไม้จะต้องจัดการกับวัฏจักร คุณสามารถทำได้ในแต่ละอัลกอริทึมหรือโหลด ฉันทำมันโหลดแล้ว

การค้นหาวัฏจักรที่แท้จริงในต้นไม้สามารถทำได้สองสามวิธี วิธีที่ผิดคือการทำเครื่องหมายทุกบรรพบุรุษจากบุคคลที่กำหนดและเมื่อข้ามถ้าคนที่คุณกำลังจะไปขั้นต่อไปมีการทำเครื่องหมายแล้วตัดการเชื่อมโยง สิ่งนี้จะตัดความสัมพันธ์ที่อาจถูกต้อง วิธีที่ถูกต้องที่จะทำคือเริ่มต้นจากแต่ละคนและทำเครื่องหมายบรรพบุรุษแต่ละคนด้วยเส้นทางไปยังบุคคลนั้น หากเส้นทางใหม่มีเส้นทางปัจจุบันเป็นเส้นทางย่อยก็เป็นวงจรและควรจะเสีย คุณสามารถจัดเก็บพา ธ เป็น vector <bool> (MFMF, MFFFMF, ฯลฯ ) ซึ่งทำให้การเปรียบเทียบและการจัดเก็บรวดเร็วมาก

มีวิธีอื่นอีกสองสามวิธีในการตรวจสอบรอบเช่นการส่งตัววนซ้ำสองตัวออกมาและดูว่าพวกเขาชนกับการทดสอบชุดย่อยหรือไม่ แต่ฉันลงเอยด้วยวิธีการใช้ที่จัดเก็บในตัวเครื่อง

นอกจากนี้โปรดทราบว่าคุณไม่จำเป็นต้องตัดการเชื่อมโยงคุณสามารถเปลี่ยนจากลิงก์ปกติเป็นลิงก์ 'อ่อน' ซึ่งไม่ได้ตามด้วยอัลกอริทึมของคุณ คุณจะต้องระมัดระวังเมื่อเลือกลิงก์ที่จะทำเครื่องหมายว่าอ่อนแอ บางครั้งคุณสามารถทราบได้ว่าควรให้วงจรเสียโดยดูที่วันเกิดของข้อมูล แต่บ่อยครั้งที่คุณไม่สามารถหาข้อมูลใด ๆ ได้เพราะข้อมูลหายไปมาก


ระมัดระวังเกี่ยวกับสมมติฐานเหล่านั้น ผู้ชายคนหนึ่งและผู้ปกครองหญิงหนึ่งคนไม่ได้รับเมื่อผู้คนปรับตัวหรือเลสบันที่คิดว่าตัวเองเป็นผู้ปกครองในอนาคตอันใกล้พวกเขาอาจจะสามารถเป็นพ่อแม่ทางชีววิทยาได้อย่างแท้จริง สำหรับเรื่องนั้นถ้าเราประยุกต์ใช้กับมนุษย์อย่างโง่เขลาแม้แต่ข้อสันนิษฐานที่ว่า "คนที่มีพ่อแม่สองคนที่แตกต่างออกไป" ก็เป็นเช่นนั้น
Agrajag

1
@Agrajag ใช่นั่นคือเหตุผลที่ฉันระบุ "การพูดทางชีววิทยา" สำหรับการตรวจสอบวงจร แม้แต่ในด้านชีววิทยาก็ยังมีอีกหลายประเด็นที่อาจเกิดขึ้นได้เช่นมารดาที่ตั้งครรภ์แทนและการผสมเทียม หากคุณอนุญาตให้มีการรับบุตรบุญธรรมและวิธีการอื่น ๆ ที่ไม่ใช่ทางชีววิทยาเพื่อกำหนดผู้ปกครองคุณอาจมีวงจรที่แท้จริงที่ใช้ได้ในต้นไม้ตัวอย่างเช่นบางคนอาจใช้ความเป็นปู่ย่าตายายเมื่ออายุมากขึ้นและไม่สามารถดูแลตัวเองได้อีกต่อไป . การตั้งสมมติฐานเกี่ยวกับชีวิตครอบครัวของผู้คนมีความซับซ้อนอยู่เสมอ แต่เมื่อเขียนซอฟต์แวร์คุณจำเป็นต้องตั้งสมมุติฐานบางอย่าง ..
tfinniga

36

อีกคำตอบที่เยาะเย้ยอย่างจริงจังสำหรับคำถามโง่ ๆ :

คำตอบที่แท้จริงคือใช้โครงสร้างข้อมูลที่เหมาะสม ลำดับวงศ์ตระกูลของมนุษย์ไม่สามารถแสดงออกได้อย่างสมบูรณ์โดยใช้ต้นไม้บริสุทธิ์ที่ไม่มีวงจร คุณควรใช้กราฟบางอย่าง นอกจากนี้ให้พูดคุยกับนักมานุษยวิทยาก่อนที่จะลงมือทำสิ่งต่อไปนี้เพราะมีสถานที่อื่นมากมายที่ทำให้เกิดข้อผิดพลาดที่คล้ายกันอาจพยายามสร้างแบบจำลองลำดับวงศ์ตระกูลแม้ในกรณีที่ง่ายที่สุดของ

แม้ว่าเราต้องการละเว้นความสัมพันธ์แบบต้องห้ามในท้องถิ่นตามที่กล่าวไว้ในที่นี้ แต่ก็มีวิธีการทางกฎหมายที่สมบูรณ์แบบและไม่คาดคิดอย่างสมบูรณ์ในการนำวงจรมาสู่ต้นไม้

ตัวอย่างเช่น: http://en.wikipedia.org/wiki/Cousin_marriage

โดยพื้นฐานแล้วการแต่งงานของลูกพี่ลูกน้องนั้นไม่เพียง แต่เป็นเรื่องธรรมดาและเป็นที่คาดหวังเท่านั้น แต่เป็นเหตุผลที่ว่าทำไมมนุษย์ถึงเปลี่ยนจากกลุ่มครอบครัวเล็ก ๆ นับพันเป็นประชากรทั่วโลก 6 พันล้านคน มันไม่สามารถใช้วิธีอื่นได้

มีน้อยมากจักรวาลเมื่อมันมาถึงลำดับวงศ์ตระกูลครอบครัวและเชื้อสาย เกือบทุกข้อสันนิษฐานที่เข้มงวดเกี่ยวกับบรรทัดฐานที่แนะนำว่าใครคือป้าหรือใครจะแต่งงานกับใครหรือว่าเด็กถูกต้องตามกฎหมายเพื่อจุดประสงค์ในการรับมรดกสามารถอารมณ์เสียได้โดยข้อยกเว้นบางแห่งในโลกหรือประวัติศาสตร์


9
ความคิดเห็นของคุณทำให้ฉันคิดว่ามีภรรยาหลายคน ซอฟต์แวร์ลำดับวงศ์ตระกูลที่มีเพียงรูปแบบการสืบพันธุ์แบบอาศัยเพศอาจต้องใช้ชื่อที่แนบมากับสเปิร์มและไข่ แต่คำจำกัดความที่กว้างขึ้นของโครงสร้างครอบครัวไม่ได้
Steve Kalemkiewicz

ซอฟต์แวร์ลำดับวงศ์ตระกูลมักจะอนุญาตให้คู่สมรสมากกว่าหนึ่งรายในโมเดล วิธีที่คุณแสดงโมเดลในมุมมองนั้นแตกต่างกันอย่างมากแม้ในหนึ่งโปรแกรมขึ้นอยู่กับ "โหมด" ที่มีให้
ทอดด์ฮอปกินสัน

20

ผลกระทบทางกฎหมายที่อาจเกิดขึ้นข้าง ๆ กันอย่างแน่นอนดูเหมือนว่าคุณจำเป็นต้องปฏิบัติต่อ 'โหนด' บนแผนภูมิต้นไม้ในฐานะบุคคลที่เป็นบรรพบุรุษมากกว่าที่จะสมมติว่าโหนดนั้นสามารถเป็นบุคคลเพียงคนเดียว

ให้โหนดของต้นไม้รวมถึงบุคคลและผู้สืบทอด - จากนั้นคุณสามารถมีโหนดอื่นที่ลึกกว่าต้นไม้ที่มีบุคคลเดียวกันกับผู้สืบทอดที่แตกต่างกัน


13

คำตอบสองสามข้อได้แสดงวิธีที่จะรักษาคำยืนยัน / ค่าคงที่ แต่ดูเหมือนจะเป็นการใช้คำยืนยัน / ค่าคงที่ในทางที่ผิด การยืนยันว่าต้องแน่ใจว่าสิ่งที่ควรเป็นจริงนั้นเป็นจริงและผู้รุกรานต้องแน่ใจว่าสิ่งที่ไม่ควรเปลี่ยนแปลงนั้นไม่เปลี่ยนแปลง

สิ่งที่คุณอ้างในที่นี้คือความสัมพันธ์ที่ไม่ร่วมประเวณีระหว่างพี่น้องไม่มีอยู่จริง เห็นได้ชัดว่าพวกเขาจะมีชีวิตอยู่เพื่อให้การยืนยันของคุณไม่ถูกต้อง คุณสามารถหลีกเลี่ยงการยืนยันนี้ แต่ข้อผิดพลาดที่แท้จริงอยู่ในการยืนยันตัวเอง ควรลบคำยืนยันออก


8

แผนภูมิต้นไม้ครอบครัวของคุณควรใช้ความสัมพันธ์โดยตรง วิธีนี้คุณจะไม่มีวงจร


5

ข้อมูลลำดับวงศ์ตระกูลนั้นมีลักษณะเป็นวงจรและไม่เหมาะกับกราฟแบบวนรอบดังนั้นหากคุณมีการยืนยันกับวงจรคุณควรลบออก

วิธีจัดการกับสิ่งนี้ในมุมมองโดยไม่สร้างมุมมองที่กำหนดเองคือการปฏิบัติต่อผู้ปกครองที่เป็นวงจรว่าเป็นผู้ปกครอง "ผี" กล่าวอีกนัยหนึ่งเมื่อบุคคลทั้งพ่อและปู่กับบุคคลเดียวกันจากนั้นปู่โหนดปรากฏตามปกติ แต่โหนดพ่อจะกลายเป็นโหนด "ผี" ที่มีป้ายง่าย ๆ เช่น ("ดูคุณปู่" ) และชี้ไปที่ปู่

ในการคำนวณคุณอาจต้องปรับปรุงตรรกะของคุณเพื่อจัดการกราฟแบบวงกลมเพื่อที่ว่าโหนดจะไม่ได้รับการเยี่ยมชมมากกว่าหนึ่งครั้งหากมีรอบ


4

สิ่งที่สำคัญที่สุดคือการavoid creating a problemดังนั้นฉันเชื่อว่าคุณควรใช้ความสัมพันธ์โดยตรงเพื่อหลีกเลี่ยงวงจร

ดังที่ @markmywords กล่าวไว้#include "fritzl.h"

recheck your data structureในที่สุดผมก็ต้องบอกว่า อาจมีบางอย่างผิดปกติที่นั่น (อาจเป็นรายการที่เชื่อมโยงแบบสองทิศทางแก้ปัญหาของคุณ)


4

ยืนยันไม่รอดความเป็นจริง

โดยทั่วไปแล้วการยืนยันไม่รอดจากการสัมผัสกับข้อมูลจริง เป็นส่วนหนึ่งของกระบวนการวิศวกรรมซอฟต์แวร์ในการตัดสินใจว่าข้อมูลใดที่คุณต้องการจัดการและอยู่นอกขอบเขต

กราฟครอบครัวแบบวงกลม

เกี่ยวกับครอบครัว "ต้นไม้" (อันที่จริงมันเป็นกราฟที่พัดเต็มรวมถึงรอบ) มีเกร็ดเล็กเกร็ดน้อยที่ดี:

ฉันแต่งงานกับหญิงม่ายที่มีลูกสาวโต พ่อของฉันที่มาเยี่ยมเราบ่อยครั้งหลงรักลูกสาวของฉันและแต่งงานกับเธอ เป็นผลให้พ่อของฉันกลายเป็นลูกชายของฉันและลูกสาวของฉันกลายเป็นแม่ของฉัน หลังจากนั้นไม่นานฉันก็ให้ลูกชายภรรยาของฉันซึ่งเป็นพี่ชายของพ่อของฉันและลุงของฉัน ภรรยาของพ่อของฉัน (ซึ่งเป็นลูกสาวของฉันและแม่ของฉัน) มีลูกชายด้วย เป็นผลให้ฉันได้รับพี่ชายและหลานชายในบุคคลเดียวกัน ภรรยาของฉันตอนนี้ยายของฉันเพราะเธอเป็นแม่ของฉัน ดังนั้นฉันเป็นสามีของภรรยาของฉันและในเวลาเดียวกันหลานชายของภรรยาของฉัน กล่าวอีกนัยหนึ่งฉันเป็นปู่ของฉันเอง

สิ่งต่าง ๆ น่าประหลาดใจยิ่งขึ้นเมื่อคุณนำตัวแทนหรือ "บิดาคลุมเครือ" มาพิจารณา

วิธีจัดการกับสิ่งนั้น

กำหนดรอบเป็นนอกขอบเขต

คุณสามารถตัดสินใจว่าซอฟต์แวร์ของคุณไม่ควรจัดการกับกรณีที่หายากเช่นนี้ หากเกิดกรณีเช่นนี้ขึ้นผู้ใช้ควรใช้ผลิตภัณฑ์อื่น สิ่งนี้ทำให้การจัดการกับกรณีที่พบบ่อยมีประสิทธิภาพมากขึ้นเนื่องจากคุณสามารถยืนยันได้มากขึ้นและเป็นโมเดลข้อมูลที่ง่ายขึ้น

ในกรณีนี้เพิ่มคุณสมบัติการนำเข้าและส่งออกที่ดีให้กับซอฟต์แวร์ของคุณเพื่อให้ผู้ใช้สามารถโยกย้ายไปยังผลิตภัณฑ์อื่นได้อย่างง่ายดายเมื่อจำเป็น

อนุญาตความสัมพันธ์ด้วยตนเอง

คุณสามารถอนุญาตให้ผู้ใช้เพิ่มความสัมพันธ์ด้วยตนเอง ความสัมพันธ์เหล่านี้ไม่ใช่ "พลเมืองชั้นหนึ่ง" เช่นซอฟต์แวร์ที่นำมาใช้อย่างที่เป็นอยู่ไม่ได้ตรวจสอบพวกเขาและไม่ได้จัดการกับพวกเขาในรูปแบบข้อมูลหลัก

ผู้ใช้สามารถจัดการกรณีที่หายากด้วยมือ แบบจำลองข้อมูลของคุณจะยังคงค่อนข้างง่ายและการยืนยันของคุณจะอยู่รอด

ระมัดระวังความสัมพันธ์ด้วยตนเอง มีสิ่งล่อใจที่จะทำให้สามารถกำหนดค่าได้อย่างสมบูรณ์และสร้างโมเดลข้อมูลที่กำหนดค่าได้อย่างสมบูรณ์ สิ่งนี้จะไม่ทำงาน: ซอฟต์แวร์ของคุณจะไม่ขยายคุณจะได้รับข้อผิดพลาดที่แปลกและในที่สุดอินเทอร์เฟซผู้ใช้จะไม่สามารถใช้งานได้ รูปแบบการต่อต้านนี้เรียกว่า"soft coding"และ"The WTF รายวัน"เต็มไปด้วยตัวอย่างสำหรับสิ่งนั้น

ทำให้แบบจำลองข้อมูลของคุณมีความยืดหยุ่นมากขึ้นข้ามการยืนยันยืนยันค่าคงที่

วิธีสุดท้ายคือการทำให้ข้อมูลของคุณมีความยืดหยุ่นมากขึ้น คุณจะต้องข้ามการยืนยันเกือบทั้งหมดและวางโมเดลข้อมูลของคุณบนกราฟที่ถูกเป่า ดังที่ตัวอย่างข้างต้นแสดงให้เห็นว่าเป็นไปได้ที่คุณจะเป็นปู่ของคุณเองได้อย่างง่ายดายดังนั้นคุณสามารถมีรอบได้

ในกรณีนี้คุณควรทดสอบซอฟต์แวร์อย่างกว้างขวาง คุณต้องข้ามการยืนยันเกือบทั้งหมดดังนั้นจึงมีโอกาสที่ดีสำหรับข้อบกพร่องเพิ่มเติม

ใช้เครื่องสร้างข้อมูลการทดสอบเพื่อตรวจสอบกรณีทดสอบที่ผิดปกติ มีห้องสมุดสำหรับการตรวจสอบอย่างรวดเร็วมีHaskell , ErlangหรือC สำหรับ Java / Scala มีScalaCheckและNyaya แนวคิดการทดสอบอย่างหนึ่งคือการจำลองประชากรสุ่มปล่อยให้มันเป็นการรวมกันแบบสุ่มจากนั้นให้ซอฟต์แวร์ของคุณนำเข้าก่อนแล้วจึงส่งออกผลลัพธ์ ความคาดหวังจะเป็นไปได้ว่าการเชื่อมต่อทั้งหมดในเอาท์พุทก็อยู่ในอินพุทและข้อรองด้วย

กรณีที่คุณสมบัติยังคงเหมือนเดิมเรียกว่าค่าคงที่ ในกรณีนี้ค่าคงที่คือชุดของ "ความสัมพันธ์แบบโรแมนติก" ระหว่างบุคคลในประชากรจำลอง พยายามหาค่าคงที่ให้ได้มากที่สุดและทดสอบด้วยข้อมูลที่สร้างแบบสุ่ม ค่าคงที่สามารถทำงานได้เช่น:

  • ลุงยังคงเป็นลุงแม้เมื่อคุณเพิ่ม "ความสัมพันธ์แบบโรแมนติก" มากขึ้น
  • เด็กทุกคนมีผู้ปกครอง
  • ประชากรที่มีสองชั่วอายุคนมีปู่ย่าตายายอย่างน้อยหนึ่งคน

หรืออาจเป็นเทคนิค:

  • ซอฟต์แวร์ของคุณจะไม่ผิดพลาดบนกราฟมากถึง 10,000 ล้านสมาชิก (ไม่ว่าจะเชื่อมโยงกันกี่ครั้ง)
  • ซอฟต์แวร์ของคุณปรับขนาดด้วย O (จำนวนโหนด) และ O (จำนวนขอบ ^ 2)
  • ซอฟต์แวร์ของคุณสามารถบันทึกและโหลดกราฟครอบครัวใหม่ได้สูงสุดถึง 10,000 ล้านสมาชิก

เมื่อทำการทดสอบแบบจำลองคุณจะพบกับมุมที่แปลกประหลาดมากมาย การแก้ไขจะใช้เวลานาน นอกจากนี้คุณจะสูญเสียการปรับแต่งมากมายซอฟต์แวร์ของคุณจะทำงานช้าลงมาก คุณต้องตัดสินใจว่ามันคุ้มค่าหรือไม่และหากอยู่ในขอบเขตของซอฟต์แวร์ของคุณ


3

แทนที่จะลบการยืนยันทั้งหมดคุณควรตรวจสอบสิ่งต่าง ๆ เช่นบุคคลที่เป็นผู้ปกครองของตนเองหรือสถานการณ์ที่เป็นไปไม่ได้อื่น ๆ และแสดงข้อผิดพลาด อาจออกคำเตือนหากไม่น่าเป็นไปได้ดังนั้นผู้ใช้ยังคงสามารถตรวจพบข้อผิดพลาดในการป้อนข้อมูลทั่วไปได้ แต่จะทำงานหากทุกอย่างถูกต้อง

ฉันจะเก็บข้อมูลในเวกเตอร์ด้วยจำนวนเต็มถาวรสำหรับแต่ละคนและจัดเก็บผู้ปกครองและเด็กในวัตถุบุคคลโดยที่ int ดังกล่าวเป็นดัชนีของเวกเตอร์ นี่จะค่อนข้างเร็วในการไประหว่างรุ่น (แต่ช้าสำหรับสิ่งต่าง ๆ เช่นการค้นหาชื่อ) วัตถุจะเป็นไปตามลำดับเมื่อพวกเขาถูกสร้างขึ้น


-3

ทำซ้ำพ่อ (หรือใช้ symlink / การอ้างอิง)

ตัวอย่างเช่นถ้าคุณใช้ฐานข้อมูลแบบลำดับชั้น:

$ #each person node has two nodes representing its parents.
$ mkdir Family
$ mkdir Family/Son
$ mkdir Family/Son/Daughter
$ mkdir Family/Son/Father
$ mkdir Family/Son/Daughter/Father
$ ln -s Family/Son/Daughter/Father Family/Son/Father
$ mkdir Family/Son/Daughter/Wife
$ tree Family
Family
└── Son
    ├── Daughter
       ├── Father
       └── Wife
    └── Father -> Family/Son/Daughter/Father

4 directories, 1 file

3
ln -sคำสั่งไม่ทำงานวิธีที่มิ ความละเอียดของลิงก์Family/Son/Fatherจะค้นหาFamily/Son/Daughter/Fatherจากใต้Family/Sonซึ่งลิงก์อยู่ไม่ใช่จาก.ที่คุณออกln -sคำสั่ง
musiphil

48
การโคลนนิ่งถูกห้ามโดยอนุสัญญาเจนีวา
MikeIsrael
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.