Цикли в програмному забезпеченні сімейного дерева


1594

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

Ці помилки є результатом моїх різних тверджень та інваріантів про оброблюваний сімейний графік (наприклад, після проходження циклу програма заявляє, що X не може бути і батьком, і дідом Y).

Як я можу вирішити ці помилки, не видаляючи всі твердження даних?



30
Якщо ви простежите своє сімейне дерево досить назад, ви будете стикатися з цією проблемою набагато частіше, ніж хотіли б. Відмова від представлення дерева може бути болісною, але в кінцевому підсумку буде більш правильною.
Томас

55
Не слід додавати твердження про малоймовірні речі, лише неможливі речі. Цикли - це очевидні речі, які неможливі в графі сімейного дерева ... ніхто не може бути його власним предком будь-яким методом. Ці інші твердження є просто хибними і їх слід усунути.
pgod

44
Це зовсім не дурне питання у світі розведення домашніх тварин. Дочка батькові, матері до сина, сестра братові, онуки бабусі і дідусі - це стандартна техніка, і домашні тварини також потребують програмного забезпечення для сімейного дерева. "Чистопородний" мій ¤% # &.
kaleissin

31
Одруження перших двоюрідних братів було дуже поширеним у вікторіанській Англії, особливо серед вищих класів (це був відмінний спосіб зберегти гроші в сім'ї). Наприклад, Чарльз Дарвін одружився зі своєю першою двоюрідною сестрою Еммою Ведґвуд. Будь-яке програмне забезпечення сімейного дерева має підтримувати подібні ситуації.
rtperson

Відповіді:


727

Здається, ви (та / або ваша компанія) маєте принципове нерозуміння того, яким має бути сімейне дерево.

Дозвольте уточнити, я також працюю в компанії, яка має (як один із своїх продуктів) сімейне дерево у своєму портфоліо, і ми боролися з подібними проблемами.

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

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

Ми змоделювали своє генеалогічне дерево до того, що відбувається в реальному світі: події (наприклад, народження, весілля, заручини, спілки, смерть, усиновлення тощо). Ми не встановлюємо жодних обмежень на них, за винятком логічно неможливих (наприклад, хтось не може бути власним батьком, стосунки потребують двох осіб тощо).

Відсутність валідацій дає нам більш "реальний світ", простіше та гнучкіше рішення.

Щодо цього конкретного випадку, я б запропонував вилучити твердження, оскільки вони не є загальними.

Для відображення питань (які виникнуть) я б запропонував намалювати той самий вузол стільки разів, скільки потрібно, натякаючи на дублювання, запалюючи всі копії щодо вибору однієї з них.


32
Це виглядає як правильний підхід, і його досить просто розширити, щоб виявити більш складні проблеми. Ви можете розробити набір взаємозв'язків "А сталося перед Б" між подіями. Наприклад, що людина народилася перед будь-якими іншими подіями, пов’язаними з ними. Це спрямований графік. Потім ви можете перевірити, чи графік не містить циклів. Дивіться це запитання в StackOverflow. Це повинно бути нормальним, поки не буде винайдено подорож у часі.
Пол Гаррісон

41
@ paul-harrison Якби там де тільки так просто. У старих записах (навіть нових) є невідповідності дати. Хрещення перед народженням, кілька записів про народження тощо ... Отже, в деякій мірі в офіційних записах є подорож у часі. Ми допускаємо ці суперечливі дані. Ми дозволяємо користувачам вказати, що додаток повинен вважати "запис" про народження у разі дублікатів. І ми вкажемо порушені строки, якщо їх знайдуть.
Bert Goethals

38
@ ben-voigt GEDCOM - це формат, створений Церквою Ісуса Христа святих останніх днів. У специфікації чітко зазначено, що шлюб (MARR) повинен бути між чоловіками та жінками. Для одностатевого шлюбу або інцесту слід використовувати позначку ASSO (СПОСОБИ), яка також використовується для позначення дружби або бути сусідами. Зрозуміло, що одностатевий шлюб є ​​відносинами другого класу в цій специфікації. Більш нейтральна специфіка не вимагає чоловічих жіночих відносин.
Bert Goethals

1
@ Bert Goethals: Ви плутаєте GEDCOM з певними програмами, які не підтримують одностатеві шлюби (PAF, Legacy). GEDCOM не виключає таких конструкцій, як "0 @ F1 @ FAM / 1 HUSB @ I1 @ / 1 HUSB @ I2 @", і таким чином підтримує одностатеві шлюби, якщо ваше програмне забезпечення захоче.
П'єр

1
@Pierre Дійсно можна обдурити систему. Це безпосередньо з документа 5.5.5: "MARR {MARRIAGE}: = Правовий, загальноприйнятий закон або звичайний захід створення сімейної одиниці чоловіка і жінки як чоловіка і дружини." ( homepages.rootsweb.ancestry.com/~pmcbride/gedcom/55gcappa.htm ) Як бачите, тут немає одних і тих же статевих шлюбів.
Берт Ґетхельс

563

Розслабте свої твердження.

Не змінюючи правила, які, ймовірно, дуже корисні 99,9% ваших клієнтів у помилках у введенні своїх даних.

Натомість змініть його на помилку "не можу додати відносини" на попередження з "додати все одно".


143
Якщо ви зіткнулися з дуже малоймовірною ситуацією, тобто такою, де користувач зазвичай робив би це лише помилково, корисно показати користувачеві попередження. Це хороший відгук. Але тоді давайте користувачеві йти вперед, якщо вони дійсно впевнені, що хочуть. Тож я вважаю, що це хороша відповідь, навіть якщо вона не потрапляє в гайки і болти як.
thomasrutter

15
Хороша відповідь! Мені просто цікаво, як подібне програмне забезпечення вирішить ситуацію "Я - власний дідусь" ( youtube.com/watch?v=eYlJH81dSiw )?
Заур Насібов

4
Це насправді не відповідь, тому що я думаю, що проблема виникає в тому, що насправді обходить дерево? Однак це гарна пропозиція.
bdwakefield

3
@bdwakefield: Питання було "Як вирішити ці помилки, не видаляючи всі твердження даних?" Я вважаю, що я відповів на це.
Ben Voigt

2
@Ben Це залежить від того, для чого ці твердження. Якщо вони запобігають виникненню нескінченних циклів або фатальних помилок, ви фактично пропонуєте зняти твердження. Якщо вони просто там, щоб попередити користувача про потенційну помилку, то ваша відповідь хороша.
rm999

224

Ось проблема родинних дерев: вони не дерева. Вони спрямовані на ациклічні графіки або DAG. Якщо я правильно зрозумію принципи біології відтворення людини, циклів не буде.

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

Мораль історії полягає в тому, щоб вибрати правильні структури даних.


7
Потрібно додаткове обмеження кожного вузла, який має 1 або 2 максимальних вузла, що вказують на нього для in vitro та статевого розмноження. Хоча це стосується реального життя, ви можете дозволити кілька штрихових ліній для невизначеного потомства з боку батька (завжди зрозуміло, хто така мати, але тільки ДНК-тестування може гарантувати, хто такий батько, і це рідко робиться навіть сьогодні), або навіть для обох це приймається до уваги.
manixrock

7
@manixrock - оскільки це питання стосується рідкісних випадків, я хотів би стверджувати, що не завжди зрозуміло, хто така мати. усиновлення, покинуті діти, сурогатні мами тощо можуть все ускладнити справи.
Пітер Рекор

9
Це не обов'язково ациклічно, чи не так? Людина-одружується-бабуся.
Ед Роппл

13
Людина, що виходить заміж за свою бабусю, не зробить себе дідусем і додасть циклу. Якщо у них є діти, це буде звичайний край графіка.
exDM69

11
Це насправді ДВА АДГА. Існує графік батьківства та графік правовідносин. Зазвичай те саме, але розходяться більше, ніж можна очікувати.
JSacksteder

115

Я думаю, що у вас є якась цінність, яка однозначно визначає людину, на якій ви можете базувати свої чеки.

Це хитро. Припускаючи, що ви хочете зберегти структуру деревом, я пропоную це:

Припустимо так: Aмає дітей із власною донькою.

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

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

Це зробить додаткову роботу для користувача, але я думаю, що ІТ було б відносно легко впроваджувати та підтримувати.

Виходячи з цього, ви можете працювати над синхронізацією коду Aта Bуникати невідповідностей.

Це рішення, безумовно, не ідеальне, але це перший підхід.


9
Ймовірно, такі "проксі" вузли справді підходять рішення. Однак я не маю уявлення, як їх можна помістити в інтерфейс користувача, не ображаючи користувача. Я можу вам сказати, що писати програмне забезпечення, яке має справу з реальними людьми (особливо вашими клієнтами), непросто.
Partick Höse

6
Це ніколи не закінчується - новий син Б буде його власним дядьком. Я вважаю за повне повернення коштів за програму!
Бо Персон

3
@Боля: А потім розуміє, що він теж власна мати, і набирає молодшого себе в агентство часу?
Null Set

2
Дублювання (та синхронізація) даних у межах однієї системи є поганою практикою. Це вказує на те, що рішення є оптимальним і його слід переглянути. Якщо необхідно створити додаткові (дублюючі) вузли, вкажіть його як проксі-сервер і делегуйте дані, що читають і записують, у вихідний вузол.
Bert Goethals

84

Ви повинні зосередитись на тому, що дійсно має значення для вашого програмного забезпечення . Чи варто час, витрачений на те, щоб він працював для одного споживача, ціною ліцензії? Ймовірно, ні.

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


3
Дуже правильно. Але також зважте інші потенційні проблеми з подібними неприємностями, які виникли інші.
Контракт професора Фолкена порушив

2
Звичайно. Аргументація така: якщо це рідкісний край у випадку некритичного додатку, вам не потрібно нічого виправляти чи реалізовувати. Якщо це дійсно шкодить вашим користувачам, в цьому є корисна робота.
christopheml

10
Напевно, у кожного є свій випадок інцесту десь у своєму роді. Тож ви потрапите на цю удару, якщо хтось копає сімейну історію (занадто) глибоко.
datenwolf

1
Створення генеалогічного дерева якоїсь дивної ситуації (inbreed роялті, Fritzl тощо) є дійсним використанням програмного забезпечення.
Bulwersator

1
Програмне забезпечення сімейного дерева, яке не дозволяє другим родичам одружуватися, марне. Майже у всіх сім'ях є принаймні один випадок цього. Тому я вважаю, що оригінальний приклад створений для ефекту.
Fuzzy76

79

Вам слід було створити сім’ю Атрейдів (сучасну, дюнну , або стародавню, Едіп Рекс ) як тестовий випадок. Ви не можете знайти помилок, використовуючи санітарні дані в якості тестового випадку.


2
На жаль, занадто багато людей спочатку думають про "нормальні" дані замість крайових випадків, які порушують їхні системи.
sjas

59

Це одна з причин, чому такі мови, як "Іти", не мають тверджень. Вони використовуються для обробки справ, про які ви, напевно, не замислювалися надто часто. Вам слід стверджувати лише неможливе, а не просто ймовірне . Виконання останнього - це те, що дає твердження про погану репутацію. Кожен раз, коли ви набираєте текст assert(, йдіть геть на десять хвилин і дійсно подумайте про це.

У вашій особливо тривожній справі, як і мислимо, так і страшно, що таке твердження було б неправдивим за рідкісних, але можливих обставин. Отже, обробіть це у своєму додатку, якщо тільки сказати "Це програмне забезпечення не було розроблене для обробки сценарію, який ви представили".

Стверджувати, що твій великий, великий, дідусь бути батьком як неможливий - це розумно зробити.

Якби я працював у тестувальній компанії, яку найняли для тестування вашого програмного забезпечення, я, звичайно, представив би такий сценарій. Чому? Кожен неповнолітній, але розумний "користувач" збирається зробити саме те саме і насолодитися отриманим звітом про помилки.


5
Погодьтеся з аргументом "коли використовувати твердження"; не розумію, як це стосується "деяких мов є твердження, Go - ні".
phooji

2
@Red Hue - іноді компілятори роблять неможливе ... можливим. Деякі версії gcc думають -10 == 10 у реалізації abs ().
Тім Пост

2
@ Червоний відтінок: Вся суть тверджень полягає в документуванні та тестуванні умов, які завжди повинні бути правдивими (або помилковими). Це допомагає уберегти вас (та інших) від того, щоб "виправляти" речі таким чином, щоб виникали ті неможливі випадки, оскільки тоді вони явно (а не тонко) ламають додаток. Якщо є вагома причина появи "неможливого" випадку, то ви занадто багато стверджували.
cHao

1
@cHao @Tim Post Я просто намагаюся зрозуміти, чому "Не маючи тверджень" - це добре, оскільки більшість з вас погоджуються, що твердження важливо мати.
Арлен

5
Мати твердження (або кодоподібний код) не має значення. Код на таких мовах, як Go, може і буде робити припущення щодо структури даних; він просто не може документувати та виконувати ці припущення із твердженнями. Підсумок: програма має помилку.
Tommy McGuire

41

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


37

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

Однак, схоже, ти стверджуєш, що між людиною та одним з її предків існує лише один шлях. Це гарантує відсутність циклів, але занадто суворе. Біологічно кажучи, нащадка - це спрямований ациклічний графік (DAG). Випадок, який у вас є, звичайно, вироджений випадок, але така річ трапляється постійно на більших деревах.

Наприклад, якщо ви подивитесь на 2 ^ n предків, які ви мали в поколінні n, якби не було перекриття, то у 1000 році нашої ери було б більше предків, ніж живих людей. Отже, має бути перекриття.

Тим не менш, ви також маєте тенденцію до отримання недійсних циклів, які є лише поганими даними. Якщо ви об’їжджаєте дерево, тоді слід вирішувати цикли. Це можна зробити в кожному окремому алгоритмі або при завантаженні. Я це робив на навантаженні.

Знайти справжні цикли на дереві можна кількома способами. Невірний спосіб - позначити кожного предка від певної особи, і при переході, якщо людина, до якої ви збираєтеся перейти до наступного, вже позначена, а потім перервіть посилання. Це розірве потенційно точні відносини. Правильний спосіб зробити це - починати від кожної людини і позначати кожного предка шляхом до цієї людини. Якщо новий шлях містить поточний шлях як підпуть, то це цикл, і його слід розбити. Ви можете зберігати шляхи як вектор <bool> (MFMF, MFFFMF тощо), що робить порівняння та зберігання дуже швидким.

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

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


Обережно щодо цих припущень; один чоловік і одна жінка з батьків не дається , коли люди пристосовуються або lesibans , які вважають себе в якості батьків, в найближчому майбутньому вони можуть навіть бути в змозі дійсно бути біологічно батьки, по крайней мере дівчат. З цього приводу, якщо ми застосовуємо доллі до людей, навіть припущення, що "людина має двох різних батьків", немає.
Аграджаг

1
@Agrajag, так, тому я вказав "біологічно кажучи" для виявлення циклу. Навіть у біологічному відношенні існує багато можливих питань, таких як сурогатні матері та штучне запліднення. Якщо ви також дозволяєте усиновлення та інші небіологічні методи визначення батьків, то можливе мати дійсний справжній цикл на дереві - наприклад, можливо, хтось приймає своїх бабусь і дідусів, коли вони старіють і вже не в змозі подбати про себе . Робити припущення про сімейне життя людей завжди складно. Але при написанні програмного забезпечення потрібно зробити деякі припущення ..
tfinniga

36

Ще одна насмішна серйозна відповідь на дурне запитання:

Справжня відповідь полягає у використанні відповідної структури даних. Людську генеалогію не можна повністю виразити за допомогою чистого дерева без циклів. Ви повинні використовувати якийсь графік. Крім того, поговоріть з антропологом, перш ніж продовжувати це робити, оскільки є багато інших місць, подібні помилки можуть бути зроблені, намагаючись моделювати генеалогію, навіть у найпростішому випадку "західного патріархального моногамного шлюбу".

Навіть якщо ми хочемо ігнорувати локально табуйовані стосунки, про які говорилося тут, існує безліч ідеально законних і абсолютно несподіваних способів введення циклів у сімейне дерево.

Наприклад: http://en.wikipedia.org/wiki/Cousin_marriage

В основному, подружжя подружжя є не лише поширеним і очікуваним, це є причиною того, що люди перейшли від тисяч малих сімейних груп до 6 мільярдів у всьому світі. Це не може працювати інакше.

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


9
Ваш коментар змусив мене подумати про багатоженство. Програмне забезпечення для генеалогії, яке моделює лише статеве розмноження, може вимагати, щоб ім’я було прикріплено до сперми та яйцеклітини, але більш широкі визначення сімейної структури не мають.
Стів Калемкевич

Програмне забезпечення генеалогії часто допускає більше ніж один з подружжя в моделі. Спосіб відображення моделі на зображенні різниться, навіть у межах однієї програми, залежно від "режиму", який було надано.
Тодд Хопкінсон

20

Потенційні правові наслідки вбік, очевидно, здається, що вам потрібно ставитися до «вузла» на сімейному дереві як до людини-попередника, а не припускати, що вузол може бути єдиною людиною.

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


13

Кілька відповідей показали способи збереження тверджень / інваріантів, але це виглядає як неправильне використання тверджень / інваріантів. Ствердження полягають у тому, щоб переконатися, що щось, що повинно бути правдою, є правдою, а інваріанти - переконатися, що щось, що не повинно змінитися, не зміниться.

Тут ви стверджуєте, що інцестуальних стосунків не існує. Ясно , що вони роблять існує, так що ваше твердження є недійсним. Ви можете обійти це твердження, але справжня помилка полягає в самому твердженні. Твердження слід усунути.



5

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

Спосіб вирішення цього питання в режимі перегляду без створення спеціального подання - це трактування циклічного батька як батька "привид". Іншими словами, коли людина є і батьком, і дідом одній і тій же особі, тоді дідовий вузол відображається нормально, але батьківський вузол відображається як вузол "привид", який має просту мітку типу ("див. Дідусь") ) і вказує на діда.

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


4

Найголовніше - avoid creating a problemтак, я вважаю, що вам слід скористатися прямим відношенням, щоб уникнути циклу.

Як сказав @markmywords, #include "fritzl.h".

Нарешті мушу сказати recheck your data structure. Можливо, там щось не так (можливо, двонаправлений список, що вирішує вашу проблему).


4

Твердження не переживають реальності

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

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

Щодо родинних "дерев" (насправді це повноцінні графіки, включаючи цикли), є приємний анекдот:

Я одружився з вдовою, яка мала дорослу дочку. Мій батько, який часто бував у нас, закохався в мою вітчима і одружився з нею. В результаті батько став моїм сином, а моя дочка стала моєю мамою. Через деякий час я дав дружині сина, який був братом мого батька, і дядька. Дружина мого батька (яка теж моя дочка і моя мама) отримала сина. В результаті я отримав брата та онука в одній людині. Моя дружина зараз моя бабуся, бо вона є мамою моєї матері. Отже, я чоловік своєї дружини, і одночасно пасинок моєї дружини. Іншими словами, я власний дідусь.

Все стає ще більш дивним, коли ти береш сурогати чи "нечітке батьківство".

Як з цим боротися

Визначте цикли як поза рамки

Ви можете вирішити, що ваше програмне забезпечення не має стосуватися таких рідкісних випадків. Якщо такий випадок трапляється, користувач повинен використовувати інший продукт. Це робить розгляд більш поширених випадків набагато більш надійним, оскільки ви можете зберегти більше тверджень і простішу модель даних.

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

Дозволити ручні відносини

Ви можете дозволити користувачеві додавати відносини вручну. Ці відносини не є "першокласними громадянами", тобто програмне забезпечення приймає їх такими, які є, не перевіряє їх і не обробляє їх у головній моделі даних.

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

Будьте обережні з ручними відносинами. Існує спокуса зробити їх повністю настроюваними, а отже, створити повністю настроювану модель даних. Це не буде працювати: Ваше програмне забезпечення не буде масштабуватися, ви отримаєте дивні помилки, і нарешті користувальницький інтерфейс стане непридатним. Цей антидіапазон називається "м'яким кодуванням" , і "Щоденний WTF" є рядом прикладів для цього.

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

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

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

Використовуйте генератор тестових даних для перевірки незвичних тестових випадків. Є швидкі бібліотеки перевірки на Haskell , Erlang або C . Для Java / Scala є ScalaCheck і ньяя . Однією з ідей тесту було б імітувати випадкову сукупність, нехай вона навмання перетинається, а потім нехай ваше програмне забезпечення спочатку імпортує, а потім експортує результат. Сподівання було б, що всі з'єднання у виході також є у вхідному та зворотному вірші.

Випадок, коли властивість залишається однаковою, називається інваріантом. У цьому випадку інваріант - це сукупність "романтичних відносин" між індивідами в модельованій сукупності. Спробуйте знайти якомога більше інваріантів і протестуйте їх за допомогою випадкових даних. Інваріанти можуть бути функціональними, наприклад:

  • дядько залишається дядьком, навіть коли ти додаєш ще "романтичні стосунки"
  • у кожної дитини є батько
  • населення з двома поколіннями має принаймні одного онука

Або вони можуть бути технічними:

  • Ваше програмне забезпечення не вийде з ладу на графіку до 10 мільярдів членів (незалежно від кількості взаємозв'язків)
  • Ваша програма масштабує з O (кількість вузлів) та O (число ребер ^ 2)
  • Ваше програмне забезпечення може зберегти та повторно завантажити кожен графік сім'ї до 10 мільярдів членів

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


3

Замість того, щоб видаляти всі твердження, вам слід все-таки перевірити, чи є така людина, як її власний батько чи інші неможливі ситуації, і помилка. Можливо, надішліть попередження, якщо це малоймовірно, тому користувач все ще може виявити поширені помилки введення, але воно буде працювати, якщо все правильно.

Я б зберігав дані у векторі з постійним цілим числом для кожної людини та зберігав би батькам і дітям особисті об’єкти, де зазначений int - індекс вектора. Це буде досить швидко проходити між поколіннями (але повільно для таких речей, як пошук імен). Об'єкти були б в порядку, коли вони були створені.


-3

Скопіюйте батька (або скористайтеся символьним посиланням / посиланням).

Наприклад, якщо ви використовуєте ієрархічну базу даних:

$ #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команду.
мусіфіл

48
клонування заборонено Женевськими конвенціями
MikeIsrael
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.