Ciclos no software de árvore genealógica

1594

Sou desenvolvedor de algum software de árvore genealógica (escrito em C ++ e Qt). Não tive problemas até que um dos meus clientes me enviou um relatório de erro. O problema é que o cliente tem dois filhos com sua própria filha e, como resultado, ele não pode usar o meu software devido a erros.

Esses erros são o resultado de minhas várias afirmações e invariantes sobre o gráfico da família sendo processado (por exemplo, depois de andar um ciclo, o programa afirma que X não pode ser pai e avô de Y).

Como posso resolver esses erros sem remover todas as asserções de dados?

Partick Höse
fonte
30
Se você rastrear sua árvore genealógica para trás o suficiente, você encontrará esse problema com mais frequência do que gostaria. Abandonar a representação da árvore pode ser doloroso, mas acabaria sendo mais correto.
Thomas
55
Você não deve adicionar asserções para coisas improváveis, apenas impossíveis. Ciclos são coisas óbvias que não são possíveis em um gráfico de árvore genealógica ... ninguém pode ser seu próprio ancestral através de qualquer método. Essas outras afirmações são apenas falsas e devem ser removidas.
Pgod
44
Esta não é uma pergunta boba no mundo da criação de animais de estimação. Filha para pai, mãe para filho, irmã para irmão, netos para avós é uma técnica padrão lá, e criadores de animais de estimação também precisam de software para árvores genealógicas. "Raça pura" meus ¤% # &.
precisa saber é o seguinte
31
Casar com primos em primeiro grau era muito comum na Inglaterra vitoriana, especialmente entre as classes altas (era uma excelente maneira de guardar dinheiro dentro da família). Charles Darwin, por exemplo, casou-se com sua prima em primeiro lugar, Emma Wedgwood. Qualquer software de árvore genealógica precisa suportar situações como essa.
usar o seguinte comando

Respostas:

727

Parece que você (e / ou sua empresa) tem um mal-entendido fundamental sobre o que uma árvore genealógica deveria ser.

Deixe-me esclarecer, também trabalho para uma empresa que possui (como um de seus produtos) uma árvore genealógica em seu portfólio e estamos enfrentando problemas semelhantes.

O problema, no nosso caso, e presumo que você também seja, vem do formato GEDCOM , que é extremamente opinativo sobre o que uma família deve ser. No entanto, esse formato contém alguns equívocos severos sobre como uma árvore genealógica realmente se parece.

O GEDCOM tem muitos problemas, como incompatibilidade com relações do mesmo sexo, incesto, etc ... O que na vida real acontece com mais frequência do que você imagina (especialmente quando voltamos no tempo para 1700-1800).

Modelamos nossa árvore genealógica para o que acontece no mundo real: eventos (por exemplo, nascimentos, casamentos, noivado, sindicatos, mortes, adoções, etc.). Não impomos nenhuma restrição a isso, exceto as logicamente impossíveis (por exemplo, não se pode ser o pai ou a mãe, as relações precisam de dois indivíduos, etc.)

A falta de validações nos dá uma solução mais "real", mais simples e mais flexível.

Quanto a este caso específico, sugiro remover as afirmações, pois elas não se sustentam universalmente.

Para exibir problemas (que surgirão), sugiro desenhar o mesmo nó quantas vezes for necessário, sugerindo a duplicação iluminando todas as cópias ao selecionar uma delas.

Bert Goethals
fonte
32
Essa parece a abordagem correta e é fácil de estender para detectar problemas mais complexos. Você pode elaborar um conjunto de relacionamentos "A aconteceu antes de B" entre eventos. Por exemplo, que uma pessoa nasceu antes de qualquer outro evento que a envolva. Este é um gráfico direcionado. Você pode então verificar se o gráfico não contém ciclos. Veja esta pergunta no StackOverflow. Isso deve ficar bom até que a viagem no tempo seja inventada.
Paul Harrison
41
@ Paul-Harrison Se apenas onde isso simples. Nos registros mais antigos (mesmo os novos), existem inconsistências de data. Batismo antes do nascimento, vários registros de nascimento etc ... Então, até certo ponto, nos registros oficiais, há viagens no tempo. Permitimos esses dados inconsistentes. Permitimos que os usuários indiquem o que o aplicativo deve considerar "o" registro de nascimento em caso de duplicatas. E indicaremos linhas do tempo quebradas, se encontradas.
Bert Goethals
38
@ ben-voigt GEDCOM é um formato criado pela Igreja de Jesus Cristo dos Santos dos Últimos Dias. A especificação afirma claramente que o casamento (MARR) deve ser entre homens e mulheres. Para casamento ou incesto entre pessoas do mesmo sexo, deve ser usada a etiqueta ASSO (ASSOCIATES), também usada para indicar amizade ou ser vizinha. É claro que o casamento entre pessoas do mesmo sexo é uma relação de segunda classe dentro dessa especificação. Uma especificação mais neutra não exigiria relações masculinas femininas.
Bert Goethals
1
@Bert Goethals: Você está confundindo o GEDCOM com certos programas que não suportam o casamento entre pessoas do mesmo sexo (PAF, Legacy). O GEDCOM não exclui construções como "0 @ F1 @ FAM / 1 HUSB @ I1 @ / 1 HUSB @ I2 @" e, portanto, suporta casamentos entre pessoas do mesmo sexo, se o software preferir.
Pierre
1
@ Pierre Você pode enganar o sistema de fato. Isto é diretamente dos documentos 5.5.1: "MARR {CASAMENTO}: = Um evento legal, de direito comum ou costumeiro de criar uma unidade familiar de um homem e uma mulher como marido e mulher". ( homepages.rootsweb.ancestry.com/~pmcbride/gedcom/55gcappa.htm ) Como você pode ver, não há casamento entre pessoas do mesmo sexo aqui.
Bert Goethals 29/10
563

Relaxe suas afirmações.

Não alterando as regras, que provavelmente são muito úteis para 99,9% de seus clientes na detecção de erros na inserção de dados.

Em vez disso, altere-o de um erro "não é possível adicionar relacionamento" para um aviso com um "adicionar mesmo assim".

Ben Voigt
fonte
143
Ao encontrar uma situação muito improvável , ou seja, aquela em que um usuário normalmente faria apenas por engano, é uma boa ideia mostrar um aviso ao usuário. Esse é um bom feedback. Mas, em seguida, permitir que o usuário vá em frente, se eles são realmente certeza de que eles querem. Então eu acho que essa é uma boa resposta, mesmo que não entre nos detalhes de como.
thomasrutter
15
Boa resposta! Eu me pergunto, como esse tipo de software lidará com a situação "Eu sou meu próprio avô" ( youtube.com/watch?v=eYlJH81dSiw )?
Zaur Nasibov 01/06
4
Esta não é realmente uma resposta, porque acho que o problema vem de atravessar a árvore? No entanto, é uma boa sugestão.
precisa saber é o seguinte
3
@bdwakefield: A pergunta era "Como soluciono esses erros, sem remover todas as asserções de dados?" Eu acredito que já respondi isso.
Ben Voigt
2
@ Ben Depende para que servem as afirmações. Se eles impedirem que loops infinitos ou erros fatais aconteçam, você está sugerindo efetivamente a remoção das asserções. Se eles estão lá apenas para alertar um usuário sobre um erro em potencial, então sua resposta é boa.
#
224

Aqui está o problema com as árvores genealógicas: elas não são árvores. Eles são gráficos acíclicos direcionados ou DAGs. Se eu entender os princípios da biologia da reprodução humana corretamente, não haverá ciclos.

Até onde eu sei, até os cristãos aceitam casamentos (e, portanto, filhos) entre primos, o que transformará a árvore genealógica em um DAG da família.

A moral da história é: escolha as estruturas de dados corretas.

exDM69
fonte
7
Seria necessária uma restrição adicional de cada nó com 1 ou 2 nós máximos apontando para ele para reprodução in vitro e sexual. Embora seja mais fiel à vida real, você pode permitir várias linhas tracejadas para descendência incerta do lado do pai (é sempre claro quem é a mãe, mas apenas testes de DNA podem garantir quem é o pai, e isso raramente é feito até hoje), ou mesmo para ambos, a adoção é levada em consideração.
precisa saber é o seguinte
7
@manixrock - já que esta pergunta é sobre casos raros, eu gostaria de afirmar que nem sempre é claro quem é a mãe. adoções, bebês abandonados, mães de aluguel, etc, tudo isso pode complicar as coisas.
Peter Recore
9
Não é necessariamente acíclico, é? O homem casa com a avó.
Ed Ropple
13
O homem que se casa com a avó não se tornará seu próprio avô e acrescentará um ciclo. Se eles tiverem filhos, será uma aresta de gráfico regular que não seja de bicicleta.
ExDM69
11
Na verdade, são DOIS ADGs. Há o gráfico de ascendência e o gráfico de relacionamento legal. Geralmente o mesmo, mas divergente mais do que se poderia esperar.
JSacksteder
115

Eu acho que você tem algum valor que identifica exclusivamente uma pessoa na qual você pode basear seus cheques.

Este é um assunto complicado. Supondo que você queira manter a estrutura em uma árvore, sugiro o seguinte:

Suponha o seguinte: Atem filhos com sua própria filha.

Aadiciona-se ao programa como Ae como B. Uma vez no papel de pai, vamos chamá-lo de namorado.

Adicione uma is_same_for_out()função que informe à parte geradora de saída de seu programa que todos os links que acessam Binternamente devem estar Ana apresentação de dados.

Isso fará algum trabalho extra para o usuário, mas acho que a TI seria relativamente fácil de implementar e manter.

Com base nisso, você pode trabalhar na sincronização de código AeB evitar inconsistências.

Esta solução certamente não é perfeita, mas é uma primeira abordagem.

Eduard Thamm
fonte
9
Provavelmente, esses nós "proxy" são realmente uma solução adequada. No entanto, não tenho idéia de como eles podem ser colocados na interface do usuário sem ofender o usuário. Posso dizer que escrever um software que lida com pessoas reais (especialmente seus clientes) não é fácil.
Partick Höse
6
Isso nunca acaba - o novo filho de B será seu próprio tio. Eu consideraria um reembolso total do programa!
Bo Persson
3
@ Will A: E então percebe que ele também é sua própria mãe e recruta seu eu mais jovem para a agência do tempo?
Set Nulo
2
A duplicação (e sincronização) de dados em um sistema é uma prática recomendada. Indica que a solução está abaixo do ideal e deve ser reconsiderada. Se a criação de nós extras (duplicados) for necessária, indique-o como um proxy e delegue as leituras e gravações de dados no nó original.
Bert Goethals
84

Você deve se concentrar no que realmente agrega valor ao seu software . O tempo gasto para fazê-lo funcionar para UM consumidor vale o preço da licença? Provavelmente não.

Aconselho que você peça desculpas a esse cliente, diga a ele que a situação dele está fora do escopo do seu software e emita um reembolso a ele.

christopheml
fonte
3
Muito verdadeiro. Mas também pesam outros problemas em potencial com problemas semelhantes que outros levantaram.
O contrato do Prof. Falken violou
2
Claro. O raciocínio é: se for um caso raro em um aplicativo não crítico, você não precisará corrigir ou implementar nada. Se realmente está prejudicando seus usuários, é importante trabalhar nisso.
21411
10
Provavelmente todo mundo tem algum caso de incesto em algum lugar de seus ancestrais. Então, você atingirá esse ponto se aprofundar também a história da família.
datenwolf
1
Tornar a árvore genealógica de uma situação estranha (realeza consanguínea, Fritzl etc.) é um uso válido de software.
precisa saber é o seguinte
1
Um software de árvore genealógica que não permita que primos em segundo grau se casem é inútil. Quase todas as famílias têm pelo menos um caso disso. É por isso que acho que o exemplo original foi criado para o efeito.
precisa saber é o seguinte
79

Você deveria ter configurado a família Atreides (moderna, Dune ou antiga, Édipo Rex ) como um caso de teste. Você não encontra erros usando dados higienizados como um caso de teste.

user779752
fonte
2
Infelizmente, muitas pessoas pensam primeiro nos dados 'ok' em vez dos casos extremos que quebram seus sistemas.
S12 /
59

Essa é uma das razões pelas quais idiomas como "Go" não possuem afirmações. Eles são usados ​​para lidar com casos nos quais você provavelmente não pensou, com muita frequência. Você deve apenas afirmar o impossível, não simplesmente o improvável . Fazer o último é o que dá às afirmações uma má reputação. Toda vez que você digita assert(, sai por dez minutos e realmente pensa sobre isso.

No seu caso particularmente perturbador, é ao mesmo tempo concebível e espantoso que tal afirmação seja falsa em circunstâncias raras, mas possíveis. Portanto, trate-o no seu aplicativo, apenas para dizer "Este software não foi projetado para lidar com o cenário que você apresentou".

Afirmar que seu tataravô ser seu pai como impossível é uma coisa razoável a se fazer.

Se eu estivesse trabalhando para uma empresa de testes contratada para testar seu software, é claro que eu teria apresentado esse cenário. Por quê? Todo "usuário" juvenil, porém inteligente, fará exatamente a mesma coisa e se deliciará com o "relatório de erro" resultante.

Tim Post
fonte
5
Concorde com o argumento 'quando usar asserções'; não vê como isso se relaciona com 'alguns idiomas têm afirmações, o Go não' '.
Phooji
2
@ Red Hue - às vezes compiladores tornam o impossível ... possível. Algumas versões do gcc think -10 == 10 na implementação abs ().
Tim Post
2
@ Red Hue: O objetivo das afirmações é documentar e testar condições que sempre devem ser verdadeiras (ou falsas). Isso ajuda a impedir que você (e outros) "conserte" as coisas de tal maneira que esses casos impossíveis surjam, pois eles explicitamente (em vez de sutilmente) quebram o aplicativo. Se houver uma razão válida para a ocorrência de um caso "impossível", você já afirmou demais.
cHao
1
@cHao @Tim Post Eu só estou tentando entender por que não ter afirmações é uma coisa boa, já que a maioria de vocês concorda que é importante ter afirmações.
Arlen
5
Ter asserções (ou código semelhante a asserção) é irrelevante. O código em idiomas como o Go pode e fará suposições sobre a estrutura dos dados; simplesmente não pode documentar e impor essas suposições com afirmações. Conclusão: o aplicativo tem um bug.
Tommy McGuire
41

Eu odeio comentar sobre uma situação tão complicada, mas a maneira mais fácil de não rejeitar todos os seus invariantes é criar um vértice fantasma no seu gráfico que atua como um proxy para o pai incestuoso.

Sean
fonte
37

Então, eu fiz algum trabalho no software de árvore genealógica. Eu acho que o problema que você está tentando resolver é que você precisa ser capaz de andar na árvore sem entrar em ciclos infinitos - em outras palavras, a árvore precisa ser acíclica.

No entanto, parece que você está afirmando que há apenas um caminho entre uma pessoa e um de seus ancestrais. Isso garantirá que não haja ciclos, mas é muito rigoroso. Biologicamente falando, a descendência é um gráfico acíclico direcionado (DAG). O caso que você tem certamente é um caso degenerado, mas esse tipo de coisa acontece o tempo todo em árvores maiores.

Por exemplo, se você olhar para os 2 ^ n antepassados ​​que você tem na geração n, se não houver sobreposição, terá mais ancestrais em 1000 dC do que pessoas vivas. Então, tem que haver sobreposição.

No entanto, você também tende a receber ciclos inválidos, apenas dados incorretos. Se você estiver atravessando a árvore, os ciclos deverão ser tratados. Você pode fazer isso em cada algoritmo individual ou em carga. Eu fiz isso em carga.

Encontrar ciclos verdadeiros em uma árvore pode ser feito de algumas maneiras. O caminho errado é marcar todos os antepassados ​​de um determinado indivíduo e, ao atravessar, se a pessoa para a qual você vai passar já estiver marcada, corte o link. Isso cortará relacionamentos potencialmente precisos. A maneira correta de fazer isso é começar de cada indivíduo e marcar cada ancestral com o caminho para esse indivíduo. Se o novo caminho contiver o caminho atual como um subcaminho, será um ciclo e deverá ser interrompido. Você pode armazenar caminhos como vetor <bool> (MFMF, MFFFMF, etc.), o que torna a comparação e o armazenamento muito rápidos.

Existem algumas outras maneiras de detectar ciclos, como enviar dois iteradores e ver se eles colidem com o teste de subconjunto, mas acabei usando o método de armazenamento local.

Observe também que você não precisa realmente cortar o link, basta alterá-lo de um link normal para um link 'fraco', que não é seguido por alguns de seus algoritmos. Você também deve tomar cuidado ao escolher qual link marcar como fraco; Às vezes, você pode descobrir onde o ciclo deve ser interrompido observando as informações da data de nascimento, mas geralmente não é possível descobrir nada porque faltam muitos dados.

tfinniga
fonte
Cuidado com essas suposições; um pai e uma mãe não são dados quando as pessoas se adaptam, ou lesibanas que se consideram pais, em um futuro próximo elas poderão até ser biologicamente realmente os pais, pelo menos nas meninas. Nesse caso, se aplicarmos a boneca aos seres humanos, até a suposição de que "uma pessoa tem dois pais distintos" desaparece.
Agrajag
1
@ Grajag, sim, é por isso que eu especifiquei "biologicamente falando" para a detecção do ciclo. Mesmo biologicamente, existem muitas questões possíveis, como mães de aluguel e inseminação artificial. Se você também permitir a adoção e outros métodos não biológicos para definir os pais, é possível ter um ciclo verdadeiro válido em uma árvore - por exemplo, talvez alguém adote o avô quando ficar velho e não puder mais cuidar de si mesmo . Fazer suposições sobre a vida familiar das pessoas é sempre complicado. Mas ao escrever software que você precisa para fazer algumas suposições ..
tfinniga
36

Outra resposta séria e falsa para uma pergunta boba:

A resposta real é, use uma estrutura de dados apropriada. A genealogia humana não pode ser totalmente expressa usando uma árvore pura sem ciclos. Você deve usar algum tipo de gráfico. Além disso, converse com um antropólogo antes de prosseguir com isso, porque há muitos outros lugares em que erros semelhantes poderiam ser cometidos na tentativa de modelar a genealogia, mesmo no caso mais simples de "casamento monogâmico patriarcal ocidental".

Mesmo se quisermos ignorar os relacionamentos tabus localmente, conforme discutido aqui, existem muitas maneiras perfeitamente legais e completamente inesperadas de introduzir ciclos em uma árvore genealógica.

Por exemplo: http://en.wikipedia.org/wiki/Cousin_marriage

Basicamente, o casamento entre primos não é apenas comum e esperado, é a razão pela qual os seres humanos passaram de milhares de pequenos grupos familiares para uma população mundial de 6 bilhões. Não pode funcionar de outra maneira.

Realmente existem muito poucos universais quando se trata de genealogia, família e linhagem. Quase qualquer suposição estrita sobre normas que sugerem quem pode ser uma tia, ou quem pode se casar com quem, ou como as crianças são legitimadas para fins de herança, pode ser perturbada por alguma exceção em algum lugar do mundo ou da história.

clvrmnky
fonte
9
Seu comentário me fez pensar em poligamia. O software de genealogia que apenas modela a reprodução sexual pode exigir um nome associado ao esperma e ao óvulo, mas definições mais amplas da estrutura familiar não.
Steve Kalemkiewicz
O software de genealogia geralmente permite mais de um cônjuge no modelo. A maneira como você exibe o modelo na visualização varia muito, mesmo dentro de um programa, dependendo do "modo" fornecido.
Todd Hopkinson
20

Possíveis implicações legais à parte, certamente parece que você precisa tratar um 'nó' em uma árvore genealógica como uma pessoa predecessora, em vez de assumir que o nó pode ser a única pessoa.

Faça com que o nó da árvore inclua uma pessoa e os sucessores - e então você poderá ter outro nó mais profundo na árvore que inclua a mesma pessoa com sucessores diferentes.

Will A
fonte
13

Algumas respostas mostraram maneiras de manter as asserções / invariantes, mas isso parece um uso indevido de asserções / invariantes. As asserções são para garantir que algo que deva ser verdadeiro seja verdadeiro, e os invariantes devem garantir que algo que não deve mudar não mude.

O que você está afirmando aqui é que não existem relacionamentos incestuosos. É claro que eles fazem existir, assim que sua afirmação é inválido. Você pode contornar essa afirmação, mas o bug real está na própria afirmação. A afirmação deve ser removida.

kerkeslager
fonte
8

Sua árvore genealógica deve usar relações direcionadas. Dessa forma, você não terá um ciclo.

Patrick Cornelissen
fonte
5

Os dados genealógicos são cíclicos e não se enquadram em um gráfico acíclico; portanto, se você tiver afirmações contra ciclos, deverá removê-las.

A maneira de lidar com isso em uma exibição sem criar uma exibição personalizada é tratar o pai cíclico como um pai "fantasma". Em outras palavras, quando uma pessoa é pai e avô da mesma pessoa, o nó do avô é mostrado normalmente, mas o nó do pai é renderizado como um nó "fantasma" que possui um rótulo simples como ("consulte o avô" ) e aponta para o avô.

Para fazer cálculos, pode ser necessário melhorar sua lógica para manipular gráficos cíclicos, para que um nó não seja visitado mais de uma vez se houver um ciclo.

Tyler Durden
fonte
4

O mais importante é avoid creating a problem, então acredito que você deve usar uma relação direta para evitar um ciclo.

Como o @markmywords disse, #include "fritzl.h".

Finalmente eu tenho que dizer recheck your data structure. Talvez algo esteja errado por lá (talvez uma lista vinculada bidirecional resolva seu problema).

Nasser Hadjloo
fonte
4

Afirmações não sobrevivem à realidade

Normalmente, afirmações não sobrevivem ao contato com dados do mundo real. É parte do processo de engenharia de software decidir com quais dados você deseja lidar e quais estão fora do escopo.

Gráficos da família cíclica

Em relação às "árvores" da família (na verdade, são gráficos completos, incluindo ciclos), há uma boa anedota:

Casei-me com uma viúva que tinha uma filha crescida. Meu pai, que frequentemente nos visitava, se apaixonou por minha enteada e se casou com ela. Como resultado, meu pai se tornou meu filho e minha filha se tornou minha mãe. Algum tempo depois, dei à minha esposa um filho, que era irmão de meu pai e meu tio. A esposa do meu pai (que também é minha filha e minha mãe) teve um filho. Como resultado, eu tenho um irmão e um neto na mesma pessoa. Minha esposa agora é minha avó, porque ela é a mãe de minha mãe. Então, eu sou o marido da minha esposa e, ao mesmo tempo, o neto da minha esposa. Em outras palavras, eu sou meu próprio avô.

As coisas ficam ainda mais estranhas quando você leva em consideração os substitutos ou a "paternidade confusa".

Como lidar com isso

Definir ciclos como fora do escopo

Você pode decidir que seu software não deve lidar com casos tão raros. Se esse caso ocorrer, o usuário deve usar um produto diferente. Isso torna o tratamento dos casos mais comuns muito mais robusto, porque você pode manter mais asserções e um modelo de dados mais simples.

Nesse caso, adicione alguns bons recursos de importação e exportação ao seu software, para que o usuário possa migrar facilmente para um produto diferente quando necessário.

Permitir relações manuais

Você pode permitir que o usuário adicione relações manuais. Essas relações não são "cidadãos de primeira classe", ou seja, o software as aceita como estão, não as verifica e não as trata no modelo de dados principal.

O usuário pode então lidar com casos raros manualmente. Seu modelo de dados ainda permanecerá bastante simples e suas afirmações sobreviverão.

Tenha cuidado com as relações manuais. Existe uma tentação de torná-los completamente configuráveis ​​e, portanto, criar um modelo de dados totalmente configurável. Isso não funcionará: seu software não será dimensionado, você receberá bugs estranhos e, finalmente, a interface do usuário ficará inutilizável. Esse anti-padrão é chamado de "codificação flexível" e "O diário WTF" está cheio de exemplos para isso.

Torne seu modelo de dados mais flexível, ignore asserções, teste invariáveis

O último recurso seria tornar seu modelo de dados mais flexível. Você precisaria pular quase todas as asserções e basear seu modelo de dados em um gráfico completo. Como mostra o exemplo acima, é facilmente possível ser seu próprio avô, assim você pode até ter ciclos.

Nesse caso, você deve testar extensivamente seu software. Você teve que pular quase todas as afirmações, para que haja uma boa chance de erros adicionais.

Use um gerador de dados de teste para verificar casos de teste incomuns. Há bibliotecas Verificação rápida para Haskell , Erlang ou C . Para Java / Scala, existem ScalaCheck e Nyaya . Uma idéia de teste seria simular uma população aleatória, deixá-la cruzar aleatoriamente, depois deixar o software primeiro importar e depois exportar o resultado. A expectativa seria que todas as conexões na saída também estivessem na entrada e vice-versa.

Um caso em que uma propriedade permanece a mesma é chamado de invariável. Nesse caso, o invariante é o conjunto de "relações românticas" entre os indivíduos na população simulada. Tente encontrar o máximo de invariantes possível e testá-los com dados gerados aleatoriamente. Invariantes podem ser funcionais, por exemplo:

  • um tio permanece um tio, mesmo quando você adiciona mais "relações românticas"
  • toda criança tem um pai
  • uma população com duas gerações tem pelo menos um avô

Ou eles podem ser técnicos:

  • Seu software não trava em um gráfico de até 10 bilhões de membros (não importa quantas interconexões)
  • Seu software é dimensionado com O (número de nós) e O (número de arestas ^ 2)
  • Seu software pode salvar e recarregar todos os gráficos da família até 10 bilhões de membros

Ao executar os testes simulados, você encontrará muitos casos de canto estranhos. Consertá-los levará muito tempo. Além disso, você perderá muitas otimizações, seu software será executado muito mais lentamente. Você precisa decidir se vale a pena e se isso está no escopo do seu software.

stefan.schwetschke
fonte
3

Em vez de remover todas as asserções, você ainda deve verificar coisas como uma pessoa sendo seus próprios pais ou outras situações impossíveis e apresentar um erro. Talvez emita um aviso se for improvável, para que o usuário ainda possa detectar erros de entrada comuns, mas funcionará se tudo estiver correto.

Eu armazenaria os dados em um vetor com um número inteiro permanente para cada pessoa e os objetos de pais e filhos em pessoa, onde o dito int é o índice do vetor. Isso seria muito rápido entre gerações (mas lento para coisas como pesquisas de nome). Os objetos deveriam estar na ordem em que foram criados.

ctype.h
fonte
-3

Duplique o pai (ou use o link simbólico / referência).

Por exemplo, se você estiver usando um banco de dados hierárquico:

$ #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
numérico
fonte
3
O ln -scomando não funciona dessa maneira; a resolução do link Family/Son/Fatherprocurará por Family/Son/Daughter/Fatherbaixo Family/Son, onde o link reside, não por .onde você emitiu o ln -scomando.
Musiphil
48
clonagem é proibido pelas Convenções de Genebra
MikeIsrael