Циклы в программном обеспечении генеалогического древа

Я разработчик некоторого программного обеспечения для генеалогического древа (написанного на C ++ и Qt). У меня не было проблем, пока один из моих клиентов не отправил мне отчет об ошибке. Проблема в том, что у заказчика двое детей с собственной дочерью, и в результате он не может пользоваться моим ПО из-за ошибок.

Эти ошибки являются результатом моих различных утверждений и инвариантов относительно обрабатываемого семейного графа (например, после прохождения цикла программа заявляет, что X не может быть одновременно отцом и дедушкой Y).

Как я могу исправить эти ошибки, не удаляя все утверждения данных?


person Partick Höse    schedule 28.05.2011    source источник
comment
Если вы проследите свое генеалогическое древо достаточно далеко назад, вы будете сталкиваться с этой проблемой гораздо чаще, чем хотелось бы. Отказ от представления дерева может быть болезненным, но в конечном итоге будет более правильным.   -  person Thomas    schedule 01.06.2011
comment
Вы не должны добавлять утверждения о маловероятных вещах, только о невозможных вещах. Циклы - это очевидные вещи, которые невозможны в графе генеалогического дерева ... никто не может быть своим собственным предком каким-либо методом. Эти другие утверждения являются фиктивными и должны быть удалены.   -  person pgod    schedule 01.06.2011
comment
@pgod вместо того, чтобы терпеть неудачу в этих утверждениях, я думаю, полезно сообщать пользователю о маловероятных вещах, чтобы сообщить им, что они могли совершить ошибку, но в любом случае предоставить простой и не снисходительный метод.   -  person thomasrutter    schedule 01.06.2011
comment
Это вовсе не глупый вопрос в мире разведения домашних животных. Дочь отцу, мать сыну, сестра брату, внуки бабушкам и дедушкам - стандартная методика здесь, и заводчикам домашних животных также необходимо программное обеспечение для генеалогического древа. Чистокровный мой ¤% # &.   -  person kaleissin    schedule 01.06.2011
comment
Этот вопрос - отличная иллюстрация предположений, которые делают программисты при создании кода. Утверждениям нет места в производственном коде для ситуаций, которые могут произойти.   -  person Johnsyweb    schedule 01.06.2011
comment
Вы, ребята, серьезно пытаетесь закрыть это как субъективное и спорное? Вопрос для меня совершенно ясен, он требует решения циклов в дереве / графе.   -  person Xeo    schedule 01.06.2011
comment
Получаете ли вы ту же ошибку цикла, если двоюродные братья женятся, например, ребенок двоюродных братьев, вышедших замуж, также будет ребенком родителя, но также двоюродным братом родителя. Это обычный сценарий.   -  person Rebecca Chernoff    schedule 01.06.2011
comment
В викторианской Англии жениться на двоюродных братьях и сестрах было очень обычным делом, особенно среди высших слоев общества (это был отличный способ сохранить деньги в семье). Чарльз Дарвин, например, женился на своей двоюродной сестре Эмме Веджвуд. Любая программа для создания генеалогического древа должна поддерживать такие ситуации.   -  person rtperson    schedule 01.06.2011
comment
К вашему сведению, здесь ссылка на Reddit   -  person bgw    schedule 01.06.2011
comment
Дело в том, что это больше не технически дерево в математическом смысле. Как только вы вводите (кровосмесительные) циклы, он становится полноценным графиком. Так что скажите покупателю, чтобы он купил программу семейного графа, специально предназначенную для кровосмесительных проституток. :-)   -  person Noldorin    schedule 12.01.2012
comment
Один из тех редких случаев, когда отчет о сбое должен поступать в полицию, а не в разработчик.   -  person onosendai    schedule 01.12.2012
comment
@pgod: Если человек женится на матери человека, который женится на его матери, то он его собственный дедушка. Быть своим собственным предком генетически невозможно, но в социальном плане это не так. И большинство программ для генеалогического древа отслеживают и то, и другое.   -  person Mooing Duck    schedule 28.02.2013
comment
07.02.2013 я сделал предложение. Может, еще кому-нибудь поможет. При необходимости можно пойти на компромисс со сложными ограничениями GEDCOM, указав человека, который включает в себя группу людей, которые имеют неподдерживаемые отношения. Чтобы проиллюстрировать это, я назвал свой пример Daddy-Daughter Inc. Я открыто признаю, что это неприятно для людей и не позволяет зафиксировать некоторые факты в машиночитаемой форме. Технически, разве это не устраняет локальную проблему в GEDCOM-представлении семьи? Ну что ж. Без комментариев он был понижен до -3, поэтому я удалил его из ответов.   -  person minopret    schedule 22.12.2013
comment
Вот почему при сборе требований хорошо оспаривать утверждения. Х не бывает. Хорошо, но означает ли это, что X не обычно происходит, что X никогда не происходит или что X не может случиться?   -  person Dave Cousineau    schedule 13.10.2014
comment
Ни одно генеалогическое древо (за исключением художественной литературы о путешествиях во времени) не имеет циклов, но проблема здесь в том, что ваша программа не поддерживает ориентированные ациклические графы, в которых один узел может служить более чем одним типом предков для другого. Такие графики могут быть нежелательными с моральной, социальной или юридической точек зрения, но они не являются биологически невозможными.   -  person chepner    schedule 18.11.2014


Ответы (18)


Похоже, у вас (и / или вашей компании) есть фундаментальное непонимание того, каким должно быть генеалогическое древо.

Позвольте мне уточнить, я также работаю в компании, которая имеет (в качестве одного из ее продуктов) семейное древо в своем портфеле, и мы боролись с аналогичными проблемами.

Проблема в нашем случае, и я предполагаю, что ваш случай также исходит из формата GEDCOM, который крайне самоуверен в том, какой должна быть семья. Однако этот формат содержит некоторые серьезные заблуждения о том, как на самом деле выглядит семейное древо.

У GEDCOM много проблем, таких как несовместимость с однополыми отношениями, инцест и т. Д. Что в реальной жизни случается чаще, чем вы можете себе представить (особенно если вернуться во времени в 1700-1800).

Мы смоделировали наше генеалогическое древо на то, что происходит в реальном мире: события (например, рождения, свадьбы, помолвки, союзы, смерти, усыновления и т. Д.). Мы не налагаем на них никаких ограничений, кроме логически невозможных (например, нельзя быть родителем самому себе, родственникам нужны два человека и т. Д.)

Отсутствие валидации дает нам более «реальное», более простое и гибкое решение.

Что касается этого конкретного случая, я бы предложил удалить утверждения, поскольку они не являются универсальными.

Для отображения проблем (которые возникнут) я бы предложил рисовать один и тот же узел столько раз, сколько необходимо, намекая на дублирование, подсвечивая все копии при выборе одного из них.

person Bert Goethals    schedule 01.06.2011
comment
Это выглядит как правильный подход, и его достаточно легко расширить для обнаружения более сложных проблем. Вы можете определить набор отношений А, произошедших до Б., между событиями. Например, что человек родился до каких-либо других событий с его участием. Это ориентированный граф. Затем вы можете проверить, что график не содержит циклов. См. этот вопрос в StackOverflow. Это должно быть нормально пока не будет изобретено путешествие во времени. - person Paul Harrison; 01.06.2011
comment
@ paul-harrison Если бы это было так просто. В старых записях (даже в новых) есть несоответствия дат. Крещение до рождения, записи о множественных рождениях и т. Д. Итак, в официальных документах есть сведения о путешествиях во времени. Мы допускаем эти противоречивые данные. Мы позволяем пользователям указывать, что приложение должно учитывать в записи о рождении в случае дублирования. И мы укажем нарушенные сроки, если они будут найдены. - person Bert Goethals; 01.06.2011
comment
@ ben-voigt GEDCOM - это формат, созданный Церковью Иисуса Христа Святых последних дней. В спецификации четко указано, что брак (БРАК) заключается между мужчиной и женщиной. Для однополых браков или инцеста следует использовать тег ASSO (ASSOCIATES), который также используется для обозначения дружбы или сосуществования. Ясно, что однополые браки - это отношения второго сорта в рамках этой спецификации. Более нейтральная спецификация не требует отношений между мужчиной и женщиной. - person Bert Goethals; 03.06.2011
comment
@Bert Goethals: Вы путаете GEDCOM с некоторыми программами, которые не поддерживают однополые браки (PAF, Legacy). GEDCOM не препятствует использованию таких конструкций, как 0 @ F1 @ FAM / 1 HUSB @ I1 @ / 1 HUSB @ I2 @, и, таким образом, поддерживает однополые браки, если ваше программное обеспечение того пожелает. - person Pierre; 17.10.2014
comment
@Pierre Вы действительно можете обмануть систему. Это прямо из документов 5.5.1: MARR {MARRIAGE}: = Юридическое, гражданское или обычное событие создания семейной ячейки мужчины и женщины как мужа и жены. (homepages.rootsweb.ancestry.com/~pmcbride/gedcom/55gcappa.htm) Как видите, однополых браков здесь нет. - person Bert Goethals; 29.10.2014
comment
@Bert Goethals: Вот тест, который вы можете легко выполнить самостоятельно: [1] Создайте однополый брак в файле Family Tree Maker; [2] экспорт в GEDCOM; [3] Импортируйте файл GEDCOM в RootsMagic. Однополые браки сохраняются (например, оба партнера по-прежнему мужчины). Как это случилось? Не путайте, что такое спец. рекомендует, а не то, что реально возможно. - person Pierre; 30.10.2014
comment
@TylerH По крайней мере, я имел в виду. Также любое отношение может быть выражено как несколько пар. Например: секс втроем можно выразить как 2 отношения на человека. - person Bert Goethals; 11.06.2015
comment
@Pierre Мой пост про Спекулянт; не о том, чего пытаются добиться другие приложения, нарушая спецификации. Спецификация указывает, а не рекомендует. Тот факт, что разработчики нарушают спецификацию, указывает на то, что спецификация действительно ошибочна. - person Bert Goethals; 11.06.2015

Расслабьте свои утверждения.

Не путем изменения правил, которые, скорее всего, очень полезны для 99,9% ваших клиентов при обнаружении ошибок при вводе их данных.

Вместо этого замените ошибку «не могу добавить связь» на предупреждение с помощью «все равно добавить».

person Ben Voigt    schedule 28.05.2011
comment
При обнаружении очень маловероятной ситуации, то есть ситуации, когда пользователь обычно делает это только по ошибке, рекомендуется показать пользователю предупреждение. Это хороший отзыв. Но затем позвольте пользователю продолжить, если он действительно уверен, что хочет. Так что я думаю, что это хороший ответ, даже если не вдаваться в подробности того, как. - person thomasrutter; 01.06.2011
comment
Хороший ответ! Мне просто интересно, как такое программное обеспечение справится. Я - мой собственный дедушка (youtube.com/watch ? v = eYlJH81dSiw) ситуация? - person Zaur Nasibov; 01.06.2011
comment
На самом деле это не ответ, потому что я думаю, что проблема связана с фактическим обходом дерева? Однако это хорошее предложение. - person bdwakefield; 01.06.2011
comment
@bdwakefield: вопрос был в том, как устранить эти ошибки, не удаляя все утверждения данных? Кажется, я ответил на это. - person Ben Voigt; 01.06.2011
comment
@Ben Это зависит от того, для чего нужны утверждения. Если они предотвращают появление бесконечных циклов или фатальных ошибок, то вы фактически предлагаете удалить утверждения. Если они нужны только для того, чтобы предупредить пользователя о потенциальной ошибке, тогда ваш ответ будет хорошим. - person rm999; 01.06.2011
comment
@ rm999: вопрос довольно ясен, что утверждения применяются после обхода структуры данных. - person Ben Voigt; 01.06.2011
comment
@ Бен Я думаю, что мы по-другому читаем вопрос. Я интерпретирую цикл как цикл на графике (что означает во время обхода). Это имеет смысл в контексте вопроса: OP предполагает древовидную структуру, а ребенок, имеющий одного и того же отца и дедушку, представляет собой цикл, а, следовательно, не дерево. Многие алгоритмы обхода дерева не работают на графе с циклами, поэтому, если я правильно понимаю вопрос, bdwakefield имеет вполне законную точку зрения. - person rm999; 01.06.2011

Проблема с генеалогическими деревьями: они не деревья. Они представляют собой ориентированные ациклические графы или DAG. Если я правильно понимаю принципы биологии воспроизводства человека, циклов не будет.

Насколько мне известно, даже христиане принимают браки (и, следовательно, детей) между двоюродными братьями и сестрами, что превратит генеалогическое древо в семейный DAG.

Мораль этой истории такова: выбирайте правильные структуры данных.

person exDM69    schedule 01.06.2011
comment
Это потребует дальнейшего ограничения каждого узла, имеющего 1 или 2 максимальных узла, указывающих на него для in vitro и полового размножения. Хотя, чтобы быть более верным в реальной жизни, вы можете разрешить несколько пунктирных линий для неопределенного происхождения по отцовской линии (всегда ясно, кто мать, но только тестирование ДНК может гарантировать, кто отец, а это редко делается даже сегодня), или даже для обоих учитывается усыновление. - person manixrock; 01.06.2011
comment
@manixrock - поскольку это вопрос о редких случаях, я хочу заявить, что не всегда понятно, кто мать. усыновление, брошенные дети, суррогатные мамы и т. д. могут все усложнить. - person Peter Recore; 01.06.2011
comment
Это не обязательно ациклично, не так ли? Мужчина-женится-бабушка. - person Ed Ropple; 03.06.2011
comment
Мужчина, женится на бабушке, не станет сам себе дедушкой и добавит цикл. Если у них есть дети, это будет нециклическое ребро регулярного графа. - person exDM69; 07.06.2011
comment
На самом деле это ДВА ADG. Есть граф отцовства и граф правоотношений. Обычно то же самое, но расходится больше, чем можно было бы ожидать. - person JSacksteder; 05.10.2011
comment
Вообще говоря, циклы будут. Только не циклы родительского типа отношений. В отношениях в целом, например, в браке, вполне могут быть циклы, особенно если учесть, что эти отношения со временем меняются. - person Agrajag; 13.03.2012
comment
Предполагая совершенное знание и биологию, в биологической родословной не будет никаких циклов, но в реальном мире генеалогия полна возможно-звеньев. Manxrock выше, например, утверждает, что всегда ясно, кто мать. Что не так в реальном мире. Да, сегодня ДНК-тестирование может ответить на этот вопрос, но как вы собираетесь получить ДНК-тестирование вашего родственника из 5 поколений? - person Agrajag; 13.04.2012

Я предполагаю, что у вас есть некоторая ценность, которая однозначно идентифицирует человека, на котором вы можете основывать свои чеки.

Это непростой вопрос. Предполагая, что вы хотите сохранить структуру в виде дерева, я предлагаю следующее:

Предположим следующее: у A есть дети от собственной дочери.

A добавляет себя в программу как A и как B. Оказавшись в роли отца, назовем его бойфрендом.

Добавьте функцию is_same_for_out(), которая сообщает части вашей программы, генерирующей вывод, что все ссылки, идущие на B внутри, должны переходить на A при представлении данных.

Это потребует от пользователя дополнительной работы, но я полагаю, что ИТ будет относительно легко реализовать и поддерживать.

Исходя из этого, вы можете работать над синхронизацией кода A и B, чтобы избежать несоответствий.

Это решение, безусловно, не идеально, но это первый подход.

person Eduard Thamm    schedule 28.05.2011
comment
Наверное, такие прокси-узлы действительно подходят. Однако я понятия не имею, как их можно добавить в пользовательский интерфейс, чтобы не обидеть пользователя. Я могу сказать вам, что писать программы, которые работают с реальными людьми (особенно с вашими клиентами), непросто. - person Partick Höse; 28.05.2011
comment
Это никогда не кончится - новый сын Би будет его собственным дядей. Я бы рассмотрел полный возврат средств за программу! - person Bo Persson; 28.05.2011
comment
@Will A: А потом понимает, что он тоже его собственная мать, и нанимает себя в молодое время в агентство времени? - person Null Set; 28.05.2011
comment
Дублирование (и синхронизация) данных в одной системе - плохая практика. Это указывает на то, что решение не оптимально и его следует пересмотреть. Если потребуется создание дополнительных (дублирующих) узлов, укажите его как прокси и делегируйте чтение и запись данных исходному узлу. - person Bert Goethals; 01.06.2011

Вам следует сосредоточиться на том, что действительно имеет ценность для вашего программного обеспечения. Стоит ли время, потраченное на то, чтобы заставить его работать для ОДНОГО потребителя, цены лицензии? Скорее всего, нет.

Я советую вам извиниться перед этим клиентом, сказать ему, что его ситуация выходит за рамки вашего программного обеспечения, и вернуть ему деньги.

person christopheml    schedule 01.06.2011
comment
Совершенно верно. Но также взвесьте другие потенциальные проблемы с аналогичными проблемами, которые подняли другие. - person Prof. Falken; 01.06.2011
comment
Конечно. Причина такова: если это редкий крайний случай для некритического приложения, вам не нужно ничего исправлять или внедрять. Если это действительно вредит вашим пользователям, стоит над этим поработать. - person christopheml; 01.06.2011
comment
Наверное, у каждого есть какой-нибудь случай инцеста где-то в его / ее предках. Так что вы попадете в эту шишку, если (слишком) углубитесь в семейную историю. - person datenwolf; 13.07.2011
comment
Создание генеалогического дерева какой-то странной ситуации (инбридинг, Fritzl и т. Д.) Является допустимым использованием программного обеспечения. - person Bulwersator; 07.06.2013
comment
Программа для генеалогического древа, которая не позволяет троюродным братьям жениться, бесполезна. Практически во всех семьях есть хотя бы один случай этого. Вот почему я думаю, что исходный пример создан для эффекта. - person Fuzzy76; 26.01.2015

Вы должны были настроить семейство Atreides (современное, Дюна или древний, Царь Эдип) в качестве тестового примера. Вы не найдете ошибок, используя очищенные данные в качестве тестового примера.

person user779752    schedule 01.06.2011
comment
К сожалению, слишком многие люди сначала думают о «нормальных» данных, а не о крайних случаях, которые ломают их системы. - person sjas; 24.12.2012

Это одна из причин, почему в таких языках, как Go, нет утверждений. Они используются для обработки дел, о которых вы, вероятно, слишком часто не задумывались. Вы должны утверждать только невозможное, а не просто невероятное. Последнее - вот что дает утверждениям плохую репутацию. Каждый раз, когда вы набираете assert(, отойдите на десять минут и по-настоящему подумайте об этом.

В вашем особенно тревожном случае и мыслимо, и ужасно, что такое утверждение было бы ложным при редких, но возможных обстоятельствах. Следовательно, обработайте это в своем приложении, хотя бы для того, чтобы сказать: «Это программное обеспечение не было разработано для обработки сценария, который вы представили».

Утверждать, что ваш прапрадедушка быть вашим отцом невозможно, - разумный поступок.

Если бы я работал в компании по тестированию, которую наняли для тестирования вашего программного обеспечения, я бы, конечно, представил этот сценарий. Почему? Каждый юный, но умный «пользователь» будет делать то же самое и получать удовольствие от итогового «отчета об ошибке».

person Tim Post♦    schedule 01.06.2011
comment
Согласитесь с аргументом «когда использовать утверждения»; не понимаю, как это соотносится с «в некоторых языках есть утверждения, а в Go - нет». - person phooji; 01.06.2011
comment
@Tim Post Если вы знаете, что это невозможно, то зачем утверждать это? - person Arlen; 01.06.2011
comment
@Red Hue - иногда компиляторы делают невозможное ... возможным. Некоторые версии gcc думают -10 == 10 в реализации abs (). - person Tim Post♦; 01.06.2011
comment
@Red Hue: весь смысл утверждений состоит в том, чтобы задокументировать и проверить условия, которые всегда должны быть истинными (или ложными). Это помогает удерживать вас (и других) от исправления вещей таким образом, чтобы возникали эти невозможные случаи, поскольку тогда они явно (а не незаметно) нарушили бы работу приложения. Если есть веская причина для появления невозможного дела, значит, вы слишком много заявили. - person cHao; 01.06.2011
comment
@cHao @Tim Post Я просто пытаюсь понять, почему в Go нет утверждений - это хорошо, поскольку большинство из вас согласны с тем, что утверждения важны. - person Arlen; 01.06.2011
comment
@Red Hue: Я полагаю, что эта точка зрения основана на таких случаях, как исходный вопрос, где утверждения немного злоупотребляют. Утверждение слишком много (или слишком мало) встречается чаще, чем многие люди могут представить, потому что люди редко учатся правильно использовать утверждения. Это также вопрос времени разработки, который в любом случае часто не будет тестироваться в производственной среде, поэтому некоторые придут к выводу, что лучший способ справиться с этим - полностью избавиться от утверждений. Я не согласен, но мне симпатичны причины, лежащие в основе этого. - person cHao; 01.06.2011
comment
Если в языке есть утверждения или нет, это вряд ли сильно повлияет на то, будут ли разработчики использовать шаблон утверждения в своем коде. Многие, я уверен, даже делают это, не зная, что это называется утверждением ... - person Prof. Falken; 01.06.2011
comment
Наличие утверждений (или кода, подобного утверждениям) не имеет значения. Код на таких языках, как Go, может делать и будет делать предположения о структуре данных; он просто не может задокументировать и закрепить эти предположения с помощью утверждений. Итог: в приложении есть ошибка. - person Tommy McGuire; 02.06.2011
comment
Этот вопрос не имеет ничего общего с особенностями языка. - person gvd; 04.03.2012

Я ненавижу комментировать такую ​​запутанную ситуацию, но самый простой способ не переделывать все ваши инварианты - это создать фантомную вершину в вашем графе, которая действует как прокси-сервер для кровосмесительного отца.

person Sean    schedule 28.05.2011

Итак, я поработал над программой для создания генеалогического древа. Я думаю, что проблема, которую вы пытаетесь решить, заключается в том, что вам нужно иметь возможность ходить по дереву, не заходя в бесконечные циклы - другими словами, дерево должно быть ациклическим.

Однако похоже, что вы утверждаете, что между человеком и одним из его предков есть только один путь. Это гарантирует отсутствие циклов, но это слишком строго. С биологической точки зрения, потомство - это направленный ациклический граф (DAG). Случай, который у вас есть, безусловно, является дегенеративным случаем, но такие вещи постоянно происходят с большими деревьями.

Например, если вы посмотрите на 2 ^ n предков, которые у вас есть в поколении n, если бы не было совпадений, то у вас было бы больше предков в 1000 году нашей эры, чем было живых людей. Итак, должно быть совпадение.

Однако вы также можете получить недействительные циклы, просто неверные данные. Если вы путешествуете по дереву, нужно иметь дело с циклами. Вы можете сделать это в каждом отдельном алгоритме или под нагрузкой. Я сделал это под нагрузкой.

Найти истинные циклы в дереве можно несколькими способами. Неправильный способ - пометить каждого предка от данного человека, и при переходе, если человек, к которому вы собираетесь перейти, уже отмечен, то разорвите ссылку. Это разорвет потенциально точные отношения. Правильный способ сделать это - начать с каждого человека и обозначить каждого предка путем к этому человеку. Если новый путь содержит текущий путь как подпуть, то это цикл, и его следует прервать. Вы можете сохранять пути как векторные ‹bool> (MFMF, MFFFMF и т. Д.), Что делает сравнение и сохранение очень быстрым.

Есть несколько других способов обнаружения циклов, таких как отправка двух итераторов и проверка, сталкиваются ли они когда-либо с тестом подмножества, но в итоге я использовал метод локального хранения.

Также обратите внимание, что вам не нужно фактически разрывать ссылку, вы можете просто изменить ее с обычной ссылки на «слабую», которая не используется некоторыми вашими алгоритмами. Вы также должны быть внимательны при выборе ссылки, которую следует отметить как слабую; иногда вы можете выяснить, где следует разорвать цикл, взглянув на информацию о дате рождения, но часто вы ничего не можете понять, потому что так много данных отсутствует.

person tfinniga    schedule 01.06.2011
comment
Будьте осторожны с этими предположениями; один родитель мужского пола и одна женщина не являются данностью, когда люди адаптируются, или лесибаны, считающие себя родителями, в ближайшем будущем они могут даже действительно быть биологически родителями, по крайней мере, для девочек. В этом отношении, если мы применим тележку к людям, даже предположение, что у человека есть два разных родителя, не будет. - person Agrajag; 13.03.2012
comment
@Agrajag, да, поэтому я биологически указывал на определение цикла. Даже с биологической точки зрения существует множество возможных проблем, таких как суррогатные матери и искусственное оплодотворение. Если вы также разрешаете усыновления и другие небиологические методы для определения родителей, тогда можно иметь действительный истинный цикл на дереве - например, может быть, кто-то усыновляет своих бабушек и дедушек, когда они стареют и больше не могут заботиться о себе . Делать предположения о семейной жизни людей всегда сложно. Но при написании программного обеспечения нужно делать некоторые предположения .. - person tfinniga; 04.04.2012

Еще один издевательский серьезный ответ на глупый вопрос:

Реальный ответ - используйте подходящую структуру данных. Человеческая генеалогия не может быть полностью выражена с помощью чистого дерева без циклов. Вы должны использовать какой-то график. Кроме того, посоветуйтесь с антропологом, прежде чем идти дальше, потому что есть множество других мест, где подобные ошибки могут быть сделаны при моделировании генеалогии, даже в самом простом случае «западного патриархального моногамного брака».

Даже если мы хотим игнорировать местные табуированные отношения, как здесь обсуждается, существует множество совершенно законных и совершенно неожиданных способов ввести циклы в генеалогическое древо.

Например: http://en.wikipedia.org/wiki/Cousin_marriage.

По сути, двоюродный брак - это не только обычное дело и ожидаемое явление, это причина того, что люди перешли из тысяч небольших семейных групп в мировое население в 6 миллиардов человек. По-другому работать не может.

Когда дело доходит до генеалогии, семьи и происхождения, действительно очень мало универсалий. Практически любое строгое предположение о нормах, предполагающих, кем может быть тетя или кто за кого может выйти замуж, или как дети узакониваются с целью наследования, может быть нарушено каким-либо исключением где-нибудь в мире или истории.

person clvrmnky    schedule 01.06.2011
comment
Ваш комментарий напомнил мне о полигамии. Программное обеспечение для генеалогии, моделирующее только половое размножение, может требовать присвоения имени сперматозоиду и яйцеклетке, но более широкие определения структуры семьи этого не делают. - person Steve Kalemkiewicz; 03.06.2011
comment
Программное обеспечение для генеалогии часто позволяет использовать в модели более одного супруга. То, как вы отображаете модель в представлении, сильно различается даже в пределах одной программы, в зависимости от предоставленного режима. - person Todd Hopkinson; 31.03.2012

Помимо потенциальных юридических последствий, определенно кажется, что вам нужно рассматривать «узел» в генеалогическом дереве как человека-предшественника, а не предполагать, что этот узел может быть единственным человеком.

Сделайте так, чтобы узел дерева включал человека, а также его преемников - и тогда у вас может быть еще один узел глубже по дереву, который включает одного и того же человека с разными преемниками.

person Will A    schedule 28.05.2011

В нескольких ответах показаны способы сохранения утверждений / инвариантов, но это похоже на неправильное использование утверждений / инвариантов. Утверждения должны убедиться, что то, что должно быть истинным, истинно, а инварианты - убедиться, что то, что не должно меняться, не меняется.

Вы утверждаете, что кровосмесительных отношений не существует. Очевидно, что они действительно существуют, поэтому ваше утверждение неверно. Вы можете обойти это утверждение, но настоящая ошибка заключается в самом утверждении. Утверждение следует удалить.

person kerkeslager    schedule 01.06.2011

В вашем генеалогическом древе должны использоваться направленные отношения. Таким образом, у вас не будет цикла.

person Patrick Cornelissen    schedule 01.06.2011

Генеалогические данные цикличны и не укладываются в ациклический граф, поэтому, если у вас есть утверждения против циклов, вы должны их удалить.

Способ справиться с этим в представлении без создания настраиваемого представления - рассматривать циклический родительский элемент как «призрачный» родительский элемент. Другими словами, когда человек является и отцом, и дедушкой для одного и того же человека, тогда дедовский узел отображается нормально, но отцовский узел отображается как «призрачный» узел, имеющий простую метку вроде («см. Дедушку» ) и указывает на дедушку.

Для выполнения вычислений вам может потребоваться улучшить свою логику для обработки циклических графов, чтобы узел не посещался более одного раза, если есть цикл.

person Tyler Durden    schedule 12.12.2012

Самое важное - это avoid creating a problem, поэтому я считаю, что вы должны использовать прямое отношение, чтобы избежать цикла.

Как сказал @markmywords, #include "fritzl.h".

Наконец, я должен сказать recheck your data structure. Возможно, там что-то не так (возможно, двунаправленный связанный список решит вашу проблему).

person Nasser Hadjloo    schedule 06.06.2011

Утверждения не выживают в реальности

Обычно утверждения не выдерживают контакта с данными реального мира. Это часть процесса разработки программного обеспечения, чтобы решить, с какими данными вы хотите иметь дело, а какие выходят за рамки.

Циклические семейные графы

Что касается родословных "деревьев" (по сути, это полноценные графы, включая циклы), есть интересный анекдот:

Я женился на вдове, у которой была взрослая дочь. Мой отец, который часто навещал нас, влюбился в мою падчерицу и женился на ней. В результате отец стал моим сыном, а дочь - мамой. Некоторое время спустя я подарил жене сына, который приходился брату моему отцу и дяде. У жены моего отца (которая также является моей дочерью и моей матерью) родился сын. В результате у меня появились брат и внук в одном лице. Моя жена теперь моя бабушка, потому что она мама моей матери. Итак, я муж своей жены и одновременно сводный внук моей жены. Другими словами, я сам себе дедушка.

Все становится еще более странным, если принять во внимание суррогаты или «нечеткое отцовство».

Как с этим справиться

Определить циклы как выходящие за рамки

Вы можете решить, что ваше программное обеспечение не должно иметь дело с такими редкими случаями. В таком случае пользователь должен использовать другой продукт. Это делает работу с более распространенными случаями намного более надежной, потому что вы можете сохранить больше утверждений и более простую модель данных.

В этом случае добавьте в свое программное обеспечение несколько хороших функций импорта и экспорта, чтобы при необходимости пользователь мог легко перейти на другой продукт.

Разрешить ручные отношения

Вы можете разрешить пользователю добавлять вручную отношения. Эти отношения не являются «гражданами первого класса», т.е. программа принимает их как есть, не проверяет и не обрабатывает в основной модели данных.

Затем пользователь может обрабатывать редкие случаи вручную. Ваша модель данных останется довольно простой, а ваши утверждения останутся в силе.

Будьте осторожны с ручными отношениями. Есть соблазн сделать их полностью настраиваемыми и, следовательно, создать полностью настраиваемую модель данных. Это не сработает: ваше программное обеспечение не будет масштабироваться, вы будете получать странные ошибки, и, наконец, пользовательский интерфейс станет непригодным для использования. Этот анти-шаблон называется "мягким кодированием" и " Ежедневный WTF " полон примеров для этого.

Сделайте свою модель данных более гибкой, пропустите утверждения, тестируйте инварианты

Последнее средство - сделать вашу модель данных более гибкой. Вам придется пропустить почти все утверждения и построить модель данных на полном графике. Как показывает приведенный выше пример, вы легко можете быть собственным дедушкой, так что у вас даже могут быть циклы.

В этом случае вам следует тщательно протестировать свое программное обеспечение. Вам пришлось пропустить почти все утверждения, так что велика вероятность появления дополнительных ошибок.

Используйте генератор тестовых данных для проверки необычных тестовых случаев. Существуют библиотеки быстрой проверки для Haskell, Erlang или C. Для Java / Scala существуют ScalaCheck и Ньяя. Одна из идей тестирования - смоделировать случайную популяцию, позволить ей случайным образом скрещиваться, а затем позволить вашему программному обеспечению сначала импортировать, а затем экспортировать результат. Ожидается, что все соединения на выходе также будут на входе и наоборот.

Случай, когда свойство остается неизменным, называется инвариантом. В этом случае инвариантом является набор «романтических отношений» между особями моделируемой популяции. Постарайтесь найти как можно больше инвариантов и протестировать их на случайно сгенерированных данных. Инварианты могут быть функциональными, например:

  • дядя остается дядей, даже если добавить еще «романтических отношений»
  • у каждого ребенка есть родитель
  • у населения с двумя поколениями есть хотя бы один дедушка

Или они могут быть техническими:

  • Ваше программное обеспечение не выйдет из строя на графике до 10 миллиардов участников (независимо от количества соединений)
  • Ваше программное обеспечение масштабируется с помощью O (количество узлов) и O (количество ребер ^ 2)
  • Ваше программное обеспечение может сохранять и повторно загружать каждую семейную диаграмму до 10 миллиардов членов.

Запустив смоделированные тесты, вы обнаружите множество странных угловых случаев. На их исправление уйдет много времени. Также вы потеряете много оптимизаций, ваше программное обеспечение будет работать намного медленнее. Вы должны решить, стоит ли оно того и входит ли это в сферу применения вашего программного обеспечения.

person stefan.schwetschke    schedule 26.01.2015

Вместо того, чтобы удалять все утверждения, вы все равно должны проверять такие вещи, как то, что человек является его / ее собственным родителем, или другие невозможные ситуации и выдавать ошибку. Может быть, выдать предупреждение, если это маловероятно, чтобы пользователь по-прежнему мог обнаруживать распространенные ошибки ввода, но он будет работать, если все правильно.

Я бы сохранил данные в векторе с постоянным целым числом для каждого человека и сохранил бы родителей и детей в объектах person, где указанный int является индексом вектора. Это было бы довольно быстро, чтобы переходить от поколения к поколению (но медленно для таких вещей, как поиск по имени). Объекты будут располагаться в том порядке, в котором они были созданы.

person ctype.h    schedule 02.12.2011

Дублируйте отца (или используйте символическую ссылку / ссылку).

Например, если вы используете иерархическую базу данных:

$ #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
person numeric    schedule 13.01.2012
comment
Команда ln -s так не работает; разрешение ссылки Family/Son/Father будет искать Family/Son/Daughter/Father из-под Family/Son, где находится ссылка, а не из ., где вы ввели команду ln -s. - person musiphil; 14.01.2012
comment
клонирование запрещено женевскими конвенциями - person MikeIsrael; 08.11.2012