Cicli nel software dell'albero genealogico


1594

Sono lo sviluppatore di alcuni software per alberi genealogici (scritti in C ++ e Qt). Non ho avuto problemi fino a quando uno dei miei clienti non mi ha inviato una segnalazione di bug. Il problema è che il cliente ha due figli con la propria figlia e, di conseguenza, non può utilizzare il mio software a causa di errori.

Questi errori sono il risultato delle mie varie asserzioni e invarianti sull'elaborazione del grafico familiare (ad esempio, dopo aver camminato su un ciclo, il programma afferma che X non può essere sia padre che nonno di Y).

Come posso risolvere quegli errori senza rimuovere tutte le asserzioni sui dati?



30
Se segui il tuo albero genealogico abbastanza indietro, colpirai questo problema molto più spesso di quanto vorresti. Abbandonare la rappresentazione ad albero può essere doloroso ma alla fine sarebbe più corretto.
Thomas,

55
Non dovresti aggiungere affermazioni per cose improbabili, solo cose impossibili. I cicli sono le cose ovvie che non sono possibili in un grafico dell'albero genealogico ... nessuno può essere il suo antenato con qualsiasi metodo. Queste altre affermazioni sono solo false e dovrebbero essere rimosse.
pag

44
Questa non è affatto una domanda sciocca nel mondo dell'allevamento di animali domestici. Figlia in padre, madre in figlio, sorella in fratello, nipoti in nonni sono la tecnica standard e anche gli allevatori di animali domestici hanno bisogno di software per alberi genealogici. "Pura razza" my ¤% # &.
Kaleissin,

31
Sposare i cugini di primo grado era molto comune nell'Inghilterra vittoriana, specialmente tra le classi alte (era un modo eccellente per mantenere i soldi all'interno della famiglia). Charles Darwin, ad esempio, ha sposato sua cugina di primo grado, Emma Wedgwood. Qualsiasi software dell'albero genealogico deve supportare situazioni come questa.
rtperson,

Risposte:


727

Sembra che tu (e / o la tua azienda) abbiate un fraintendimento fondamentale di ciò che dovrebbe essere un albero genealogico.

Vorrei chiarire che lavoro anche per un'azienda che ha (come uno dei suoi prodotti) un albero genealogico nel suo portafoglio e abbiamo avuto problemi simili.

Il problema, nel nostro caso, e presumo anche il tuo caso, deriva dal formato GEDCOM che è estremamente supponente su ciò che dovrebbe essere una famiglia. Tuttavia, questo formato contiene alcune idee sbagliate su come appare realmente un albero genealogico.

GEDCOM ha molti problemi, come l'incompatibilità con le relazioni dello stesso sesso, l'incesto, ecc. Che nella vita reale accade più spesso di quanto si possa immaginare (soprattutto quando si torna indietro nel tempo al 1700-1800).

Abbiamo modellato il nostro albero genealogico su ciò che accade nel mondo reale: eventi (ad esempio nascite, matrimoni, fidanzamento, sindacati, morti, adozioni, ecc.). Non imponiamo alcuna limitazione su questi, tranne quelli logicamente impossibili (ad esempio, non si può essere il proprio genitore, le relazioni hanno bisogno di due individui, ecc ...)

La mancanza di convalide ci offre una soluzione più "reale", più semplice e più flessibile.

Per quanto riguarda questo caso specifico, suggerirei di rimuovere le asserzioni in quanto non valide universalmente.

Per visualizzare i problemi (che sorgeranno), suggerirei di disegnare lo stesso nodo tutte le volte che è necessario, suggerendo la duplicazione illuminando tutte le copie selezionando uno di essi.


32
Sembra l'approccio giusto ed è abbastanza facile da estendere per rilevare problemi più complessi. È possibile elaborare una serie di relazioni "A accaduto prima di B" tra gli eventi. Ad esempio, che una persona è nata prima di qualsiasi altro evento che la coinvolge. Questo è un grafico diretto. È quindi possibile verificare che il grafico non contenga cicli. Vedi questa domanda su StackOverflow. Questo dovrebbe andare bene fino a quando non viene inventato il viaggio nel tempo.
Paul Harrison,

41
@ paul-harrison Se fosse solo così semplice. Nei record più vecchi (anche nuovi) ci sono incoerenze nella data. Battesimo prima della nascita, più documenti di nascita ecc ... Quindi, in una certa misura, nei documenti ufficiali, c'è il viaggio nel tempo. Consentiamo questi dati incoerenti. Consentiamo agli utenti di indicare ciò che l'applicazione dovrebbe considerare "il" record di nascita in caso di duplicati. E indicheremo le linee temporali spezzate se trovate.
Bert Goethals,

38
@ ben-voigt GEDCOM è un formato creato dalla Chiesa di Gesù Cristo dei Santi degli Ultimi Giorni. Le specifiche indicano chiaramente che il matrimonio (MARR) deve essere tra uomini e donne. Per il matrimonio o l'incesto dello stesso sesso è necessario utilizzare il tag ASSO (ASSOCIATES), utilizzato anche per indicare amicizia o vicinanza. È chiaro che il matrimonio omosessuale è una relazione di seconda classe all'interno di questa specifica. Una specifica più neutrale non richiederebbe relazioni tra uomini e donne.
Bert Goethals,

1
@Bert Goethals: Stai confondendo GEDCOM con alcuni programmi che non supportano il matrimonio omosessuale (PAF, Legacy). GEDCOM non preclude costrutti come "0 @ F1 @ FAM / 1 HUSB @ I1 @ / 1 HUSB @ I2 @", e quindi supporta matrimoni omosessuali se il software lo sceglie.
Pierre,

1
@Pierre Puoi davvero imbrogliare il sistema. Questo è direttamente dai documenti 5.5.1: "MARR {MATRIMONIO}: = un evento legale, di diritto comune o consuetudinario di creare un nucleo familiare di un uomo e una donna come marito e moglie". ( homepages.rootsweb.ancestry.com/~pmcbride/gedcom/55gcappa.htm ) Come puoi vedere, nessun matrimonio tra persone dello stesso sesso qui.
Bert Goethals,

563

Rilassa le tue affermazioni.

Non modificando le regole, che sono probabilmente molto utili al 99,9% dei tuoi clienti nel rilevare errori nell'inserimento dei loro dati.

Invece, cambiarlo da un errore "impossibile aggiungere una relazione" a un avviso con un "aggiungi comunque".


143
Quando si verifica una situazione molto improbabile , vale a dire quella in cui un utente di solito lo farebbe solo per errore, è una buona idea mostrare all'utente un avviso. Questo è un buon feedback. Ma poi lascia che l'utente vada avanti se è davvero sicuro di volerlo fare. Quindi penso che questa sia una buona risposta, anche se non entra nel vivo di come.
thomasrutter,

15
Buona risposta! Mi chiedo solo come questo tipo di software gestirà la situazione "Io sono mio nonno" ( youtube.com/watch?v=eYlJH81dSiw )?
Zaur Nasibov,

4
Questa non è davvero una risposta, perché penso che il problema provenga effettivamente dall'attraversare l'albero? Tuttavia, è un buon suggerimento.
bdwakefield,

3
@bdwakefield: la domanda era "Come posso risolvere questi errori, senza rimuovere tutte le asserzioni sui dati?" Credo di aver risposto.
Ben Voigt,

2
@Ben Dipende da a cosa servono le asserzioni. Se impediscono che si verifichino loop infiniti o errori fatali, allora stai effettivamente suggerendo di rimuovere le asserzioni. Se sono lì solo per avvisare un utente di un potenziale errore, allora la tua risposta è buona.
rm999

224

Ecco il problema con gli alberi genealogici: non sono alberi. Sono grafici aciclici diretti o DAG. Se capisco correttamente i principi della biologia della riproduzione umana, non ci saranno cicli.

Per quanto ne so, anche i cristiani accettano i matrimoni (e quindi i bambini) tra cugini, che trasformeranno l'albero genealogico in un DAG di famiglia.

La morale della storia è: scegliere le giuste strutture di dati.


7
Avrebbe bisogno di un'ulteriore limitazione di ogni nodo con 1 o 2 nodi massimi che lo puntano per la riproduzione in vitro e sessuale. Anche se per essere più fedeli alla vita reale, potresti consentire più linee tratteggiate per discendenza incerta da parte del padre (è sempre chiaro chi sia la madre, ma solo i test del DNA possono assicurare chi è il padre, e raramente viene fatto anche oggi), o anche per entrambi è presa in considerazione l'adozione.
Manixrock,

7
@manixrock - poiché questa domanda riguarda casi rari, vorrei affermare che non è sempre chiaro chi sia la madre. adozioni, bambini abbandonati, mamme surrogate, ecc. possono complicare le cose.
Peter Recore,

9
Non è necessariamente aciclico, vero? Man-sposa-nonna.
Ed Ropple,

13
L'uomo che sposa sua nonna non si farà suo nonno e aggiunge un ciclo. Se hanno figli, sarà un bordo grafico regolare non ciclistico.
exDM69,

11
In realtà sono DUE ADG. C'è il grafico della parentela e il grafico delle relazioni legali. Di solito lo stesso, ma divergente più di quanto ci si potrebbe aspettare.
JSacksteder

115

Immagino che tu abbia un valore che identifica in modo univoco una persona su cui puoi basare i tuoi assegni.

Questo è difficile. Supponendo che tu voglia mantenere la struttura come un albero, ti suggerisco questo:

Supponi questo: Aha figli con sua figlia.

Asi aggiunge al programma come Ae come B. Una volta nel ruolo di padre, chiamiamolo ragazzo.

Aggiungi una is_same_for_out()funzione che dice all'output che genera parte del tuo programma che tutti i link che vanno Binternamente dovrebbero andare alla Apresentazione dei dati.

Ciò renderà un lavoro extra per l'utente, ma immagino che l'IT sarebbe relativamente facile da implementare e mantenere.

Partendo da questo, potresti lavorare sulla sincronizzazione del codice AeB evitare incoerenze.

Questa soluzione non è sicuramente perfetta, ma è un primo approccio.


9
Probabilmente tali nodi "proxy" sono davvero una soluzione adatta. Tuttavia, non ho idea di come possano essere inseriti nell'interfaccia utente senza offendere l'utente. Posso dirti che scrivere software che si occupa di persone reali (specialmente i tuoi clienti) non è facile.
Partick Höse,

6
Non finisce mai: il nuovo figlio di B sarà suo zio. Vorrei prendere in considerazione un rimborso completo per il programma!
Bo Persson,

3
@Will A: E poi si rende conto di essere anche sua madre e recluta il suo io più giovane nell'agenzia del tempo?
Null Set

2
La duplicazione (e la sincronizzazione) di dati all'interno di un sistema è una cattiva pratica. Indica che la soluzione non è ottimale e deve essere riconsiderata. Se fosse necessaria la creazione di nodi extra (duplicati), indicarlo come proxy e delegare le letture e le scritture dei dati al nodo originale.
Bert Goethals,

84

Dovresti concentrarti su ciò che rende davvero prezioso il tuo software . Il tempo impiegato per farlo funzionare per UN consumatore vale il prezzo della licenza? Probabilmente no.

Ti consiglio di scusarti con questo cliente, dirgli che la sua situazione non rientra nel campo di applicazione del tuo software e di concedergli un rimborso.


3
Verissimo. Ma pesa anche altri potenziali problemi con problemi simili che altri hanno sollevato.
contratto del Prof. Falken ha violato l'

2
Ovviamente. Il ragionamento è: se si tratta di un raro caso limite su un'applicazione non critica, non è necessario correggere o implementare nulla. Se sta davvero danneggiando i tuoi utenti, è utile lavorarci su.
christopheml,

10
Probabilmente tutti hanno qualche caso di incesto da qualche parte nella propria discendenza. Quindi colpirai quel dosso se uno scava la storia della famiglia (troppo) in profondità.
datenwolf,

1
Fare un albero genealogico di qualche strana situazione (regalità consanguinee, Fritzl ecc.) È un valido uso del software.
Bulwersator

1
Un software di albero genealogico che non permetterà di sposare i cugini di secondo grado è inutile. Quasi tutte le famiglie hanno almeno un caso di questo. Questo è il motivo per cui penso che l'esempio originale sia inventato per effetto.
Fuzzy76,

79

Avresti dovuto creare la famiglia Atreides (moderna, Dune o antica, Edipo Rex ) come caso di prova. Non trovi bug usando i dati sanificati come test case.


2
Purtroppo, troppe persone prima pensano ai dati "ok" invece che ai casi limite che rompono i loro sistemi.
sjas,

59

Questo è uno dei motivi per cui lingue come "Go" non hanno affermazioni. Sono usati per gestire casi a cui probabilmente non hai pensato, troppo spesso. Dovresti solo affermare l'impossibile, non semplicemente l'improbabile . Fare quest'ultimo è ciò che dà alle asserzioni una cattiva reputazione. Ogni volta che digiti assert(, vai via per dieci minuti e davvero pensaci .

Nel tuo caso particolarmente inquietante, è sia immaginabile che spaventoso che una simile affermazione sia falsa in circostanze rare ma possibili. Quindi, gestiscilo nella tua app, anche solo per dire "Questo software non è stato progettato per gestire lo scenario che hai presentato".

Affermare che il tuo grande, grande, bisnonno essere tuo padre come impossibile è una cosa ragionevole da fare.

Se avessi lavorato per una società di test che era stata assunta per testare il tuo software, ovviamente avrei presentato quello scenario. Perché? Ogni "utente" giovanile ma intelligente farà esattamente la stessa cosa e apprezzerà il "bug report" che ne deriva.


5
Concordare con l'argomento "quando usare le asserzioni"; non vedo come si rapporta a "alcune lingue hanno asserzioni, Go no".
phooji,

2
@Red Hue - a volte i compilatori rendono l'impossibile ... possibile. Alcune versioni di gcc pensano -10 == 10 nell'implementazione di abs ().
Tim Post

2
@Red Hue: il punto centrale delle asserzioni è documentare e testare condizioni che dovrebbero essere sempre vere (o false). Aiuta a impedire a te (e agli altri) di "risolvere" le cose in modo tale che sorgano casi impossibili, in quanto in tal modo romperebbero esplicitamente (piuttosto che sottilmente) l'app. Se c'è un motivo valido per la comparsa di un caso "impossibile", allora hai affermato troppo.
cHao,

1
@cHao @Tim Post Sto solo cercando di capire perché Go non ha asserzioni è una buona cosa dal momento che molti di voi concordano sul fatto che l'affermazione è importante avere.
Arlen,

5
Avere asserzioni (o codice simile a un'asserzione) è irrilevante. Il codice in lingue come Go può e farà ipotesi sulla struttura dei dati; semplicemente non può documentare e applicare tali ipotesi con affermazioni. In conclusione: l'applicazione ha un bug.
Tommy McGuire,

41

Odio commentare una situazione così sbagliata, ma il modo più semplice per non riaccendere tutti i tuoi invarianti è creare un vertice fantasma nel tuo grafico che funga da proxy per il padre incestuoso.


37

Quindi, ho fatto qualche lavoro sul software dell'albero genealogico. Penso che il problema che stai cercando di risolvere sia che devi essere in grado di camminare sull'albero senza entrare in loop infiniti - in altre parole, l'albero deve essere aciclico.

Tuttavia, sembra che tu stia affermando che esiste solo un percorso tra una persona e uno dei suoi antenati. Ciò garantirà che non ci siano cicli, ma è troppo rigoroso. Biologicamente parlando, la discendenza è un grafico aciclico diretto (DAG). Il caso che hai è certamente un caso degenerato, ma quel tipo di cose succede sempre sugli alberi più grandi.

Ad esempio, se guardi i 2 ^ n antenati che hai alla generazione n, se non ci fossero sovrapposizioni, avresti avuto più antenati nel 1000 d.C. di quante persone vivessero. Quindi, ci deve essere una sovrapposizione.

Tuttavia, si tende anche a ottenere cicli non validi, solo dati errati. Se stai attraversando l'albero, allora i cicli devono essere affrontati. Puoi farlo in ogni singolo algoritmo o sotto carico. L'ho fatto a carico.

La ricerca di cicli reali in un albero può essere eseguita in diversi modi. Il modo sbagliato è di contrassegnare ogni antenato di un determinato individuo e, quando si attraversa, se la persona che si sta per passare al prossimo è già contrassegnata, quindi tagliare il collegamento. Ciò interromperà relazioni potenzialmente accurate. Il modo corretto per farlo è partire da ogni individuo e contrassegnare ogni antenato con il percorso verso quell'individuo. Se il nuovo percorso contiene il percorso corrente come sottotraccia, allora è un ciclo e deve essere interrotto. È possibile memorizzare i percorsi come <bool> vettoriale (MFMF, MFFFMF, ecc.) Che rende il confronto e l'archiviazione molto rapidi.

Esistono alcuni altri modi per rilevare i cicli, come l'invio di due iteratori e la possibilità di scontrarsi con il test del sottoinsieme, ma alla fine ho usato il metodo di archiviazione locale.

Si noti inoltre che non è necessario recidere effettivamente il collegamento, è possibile modificarlo da un normale collegamento a un collegamento "debole", che non è seguito da alcuni dei tuoi algoritmi. Dovrai anche fare attenzione quando scegli quale link contrassegnare come debole; a volte puoi capire dove dovrebbe essere interrotto il ciclo guardando le informazioni sulla data di nascita, ma spesso non riesci a capire nulla perché mancano così tanti dati.


Attento a questi presupposti; un maschio e una femmina non sono un dato scontato quando le persone si adattano, o le lesbiche che si considerano genitori, in un prossimo futuro potrebbero persino essere in grado di essere biologicamente i genitori, almeno delle ragazze. Del resto, se applichiamo il carrello agli umani, anche l'assunto "una persona ha due genitori distinti" è fuori.
Agrajag,

1
@Agrajag, sì, è per questo che ho specificato "biologicamente parlando" per il rilevamento del ciclo. Anche biologicamente, ci sono molte possibili questioni, come le madri surrogate e l'inseminazione artificiale. Se permetti anche adozioni e altri metodi non biologici per definire i genitori, allora è possibile avere un vero ciclo valido in un albero - ad esempio, forse qualcuno adotta il nonno quando invecchia e non è più in grado di prendersi cura di se stesso . Fare ipotesi sulla vita familiare delle persone è sempre complicato. Ma quando si scrive un software è necessario formulare alcune ipotesi ...
tfinniga,

36

Un'altra finta risposta seria per una domanda stupida:

La vera risposta è utilizzare una struttura dati appropriata. La genealogia umana non può essere pienamente espressa usando un albero puro senza cicli. Dovresti usare una sorta di grafico. Inoltre, parla con un antropologo prima di andare oltre, perché ci sono molti altri posti in cui si potrebbero fare errori simili cercando di modellare la genealogia, anche nel caso più semplice del "matrimonio monogamico patriarcale occidentale".

Anche se vogliamo ignorare le relazioni tabù a livello locale come discusso qui, ci sono molti modi perfettamente legali e completamente inaspettati per introdurre cicli in un albero genealogico.

Ad esempio: http://en.wikipedia.org/wiki/Cousin_marriage

Fondamentalmente, il matrimonio con la cugina non è solo comune e previsto, è la ragione per cui gli esseri umani sono passati da migliaia di piccoli gruppi familiari a una popolazione mondiale di 6 miliardi. Non può funzionare diversamente.

Ci sono davvero pochi universali quando si tratta di genealogia, famiglia e lignaggio. Quasi ogni severa ipotesi sulle norme che suggeriscono chi può essere una zia, o chi può sposare chi, o come i bambini sono legittimati ai fini dell'eredità, può essere sconvolta da qualche eccezione in qualche parte del mondo o della storia.


9
Il tuo commento mi ha fatto pensare alla poligamia. Il software di genealogia che modella solo la riproduzione sessuale può richiedere un nome attribuito allo sperma e all'uovo, ma no definizioni più ampie di struttura familiare.
Steve Kalemkiewicz,

Il software di genealogia consentirà spesso più di un coniuge nel modello. La modalità di visualizzazione del modello nella vista varia ampiamente, anche all'interno di un programma, a seconda della "modalità" fornita.
Todd Hopkinson,

20

A parte le potenziali implicazioni legali, sembra certamente che tu debba trattare un "nodo" su un albero genealogico come una persona predecessore piuttosto che supporre che il nodo possa essere la sola persona.

Chiedi al nodo dell'albero di includere una persona e i successori, quindi puoi avere un altro nodo più in profondità nell'albero che include la stessa persona con successori diversi.


13

Alcune risposte hanno mostrato modi per mantenere le asserzioni / invarianti, ma questo sembra un uso improprio di asserzioni / invarianti. Le asserzioni devono assicurarsi che qualcosa che dovrebbe essere vero sia vero, e gli invarianti devono assicurarsi che qualcosa che non dovrebbe cambiare non cambi.

Quello che stai affermando qui è che non esistono relazioni incestuose. Chiaramente fanno esistere, così la sua affermazione non è valida. Puoi aggirare questa affermazione, ma il vero bug sta nell'affermazione stessa. L'asserzione dovrebbe essere rimossa.


8

Il tuo albero genealogico dovrebbe usare le relazioni dirette. In questo modo non avrai un ciclo.


5

I dati genealogici sono ciclici e non rientrano in un grafico aciclico, quindi se si hanno asserzioni contro i cicli, è necessario rimuoverli.

Il modo di gestirlo in una vista senza creare una vista personalizzata è di trattare il genitore ciclico come genitore "fantasma". In altre parole, quando una persona è sia padre che nonno della stessa persona, allora il nodo del nonno viene mostrato normalmente, ma il nodo padre viene visualizzato come nodo "fantasma" che ha una semplice etichetta come ("vedi nonno" ) e indica il nonno.

Per eseguire i calcoli potrebbe essere necessario migliorare la logica per gestire i grafici ciclici in modo che un nodo non venga visitato più di una volta se esiste un ciclo.


4

La cosa più importante è avoid creating a problem, quindi credo che dovresti usare una relazione diretta per evitare di avere un ciclo.

Come diceva @markmywords, #include "fritzl.h".

Finalmente devo dire recheck your data structure. Forse qualcosa non va laggiù (forse un elenco collegato bidirezionale risolve il tuo problema).


4

Le asserzioni non sopravvivono alla realtà

Di solito le affermazioni non sopravvivono al contatto con i dati del mondo reale. Fa parte del processo di ingegneria del software decidere, con quali dati si desidera trattare e quali non rientrano nell'ambito.

Grafici familiari ciclici

Per quanto riguarda gli "alberi" familiari (in realtà sono grafici completi, inclusi i cicli), c'è un bel aneddoto:

Ho sposato una vedova che aveva una figlia adulta. Mio padre, che ci visitava spesso, si innamorò della mia figliastra e la sposò. Di conseguenza, mio ​​padre divenne mio figlio e mia figlia divenne mia madre. Qualche tempo dopo, ho dato a mia moglie un figlio, che era il fratello di mio padre, e mio zio. La moglie di mio padre (che è anche mia figlia e mia madre) ha un figlio. Di conseguenza, ho avuto un fratello e un nipote nella stessa persona. Mia moglie ora è mia nonna, perché è la madre di mia madre. Quindi sono il marito di mia moglie e allo stesso tempo il nipote di mia moglie. In altre parole, sono mio nonno.

Le cose diventano ancora più strane quando prendi i surrogati o "paternità sfocata".

Come affrontarlo

Definire i cicli come fuori campo

Potresti decidere che il tuo software non dovrebbe affrontare casi così rari. In tal caso, l'utente dovrebbe utilizzare un prodotto diverso. Ciò rende la gestione dei casi più comuni molto più solida, poiché è possibile mantenere più asserzioni e un modello di dati più semplice.

In questo caso, aggiungi alcune buone funzionalità di importazione ed esportazione al tuo software, in modo che l'utente possa migrare facilmente su un prodotto diverso quando necessario.

Consenti relazioni manuali

È possibile consentire all'utente di aggiungere relazioni manuali. Queste relazioni non sono "cittadini di prima classe", ovvero il software li prende così come sono, non li controlla e non li gestisce nel modello di dati principale.

L'utente può quindi gestire casi rari a mano. Il tuo modello di dati rimarrà abbastanza semplice e le tue affermazioni sopravviveranno.

Fai attenzione alle relazioni manuali. C'è la tentazione di renderli completamente configurabili e quindi creare un modello di dati completamente configurabile. Questo non funzionerà: il tuo software non si ridimensionerà, otterrai strani bug e infine l'interfaccia utente diventerà inutilizzabile. Questo anti-pattern è chiamato "soft coding" , e "Il WTF quotidiano" è pieno di esempi per questo.

Rendi il tuo modello di dati più flessibile, salta asserzioni, verifica invarianti

L'ultima risorsa sarebbe rendere il tuo modello di dati più flessibile. Dovresti saltare quasi tutte le asserzioni e basare il tuo modello di dati su un grafico completo. Come mostra l'esempio sopra, è facilmente possibile essere tuo nonno, quindi puoi anche avere dei cicli.

In questo caso, è necessario testare ampiamente il software. Hai dovuto saltare quasi tutte le asserzioni, quindi ci sono buone possibilità di ulteriori bug.

Utilizzare un generatore di dati di test per verificare casi di test insoliti. Ci sono biblioteche di controllo rapido per Haskell , Erlang o C . Per Java / Scala ci sono ScalaCheck e Nyaya . Un'idea di prova sarebbe quella di simulare una popolazione casuale, lasciarla incrociare a caso, quindi prima importare il software e quindi esportare il risultato. L'aspettativa sarebbe che tutte le connessioni nell'output siano anche nell'input e viceversa.

Un caso in cui una proprietà rimane invariata viene chiamato invariante. In questo caso, l'invariante è l'insieme di "relazioni romantiche" tra gli individui nella popolazione simulata. Prova a trovare il maggior numero possibile di invarianti e testali con dati generati casualmente. Gli invarianti possono essere funzionali, ad esempio:

  • uno zio rimane zio, anche quando aggiungi più "relazioni romantiche"
  • ogni bambino ha un genitore
  • una popolazione con due generazioni ha almeno un nonno

Oppure possono essere tecnici:

  • Il tuo software non andrà in crash su un grafico fino a 10 miliardi di membri (indipendentemente da quante interconnessioni)
  • Il software si ridimensiona con O (numero di nodi) e O (numero di bordi ^ 2)
  • Il tuo software può salvare e ricaricare ogni grafico familiare fino a 10 miliardi di membri

Eseguendo i test simulati, troverai molti casi angolari strani. La loro riparazione richiederà molto tempo. Inoltre perderai molte ottimizzazioni, il tuo software funzionerà molto più lentamente. Devi decidere se ne vale la pena e se questo rientra nell'ambito del tuo software.


3

Invece di rimuovere tutte le asserzioni, dovresti comunque controllare cose come una persona che è il suo genitore o altre situazioni impossibili e presentare un errore. Forse emettere un avviso se è improbabile in modo che l'utente possa ancora rilevare errori di input comuni, ma funzionerà se tutto è corretto.

Vorrei memorizzare i dati in un vettore con un numero intero permanente per ogni persona e memorizzare i genitori e i figli in oggetti di persona in cui il suddetto int è l'indice del vettore. Sarebbe abbastanza veloce per passare da una generazione all'altra (ma lento per cose come la ricerca dei nomi). Gli oggetti sarebbero in ordine di quando sono stati creati.


-3

Duplica il padre (o usa il link simbolico / riferimento).

Ad esempio, se si utilizza un database gerarchico:

$ #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
Il ln -scomando non funziona in questo modo; la risoluzione del collegamento Family/Son/Fathercercherà Family/Son/Daughter/Fatherda sotto Family/Son, dove risiede il collegamento, non da .dove è stato emesso il ln -scomando.
musiphil,

48
la clonazione è vietata dalle convenzioni di
Ginevra
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.