Ciclos en software de árbol genealógico

1594

Soy el desarrollador de algún software de árbol genealógico (escrito en C ++ y Qt). No tuve problemas hasta que uno de mis clientes me envió un informe de error. El problema es que el cliente tiene dos hijos con su propia hija y, como resultado, no puede usar mi software debido a errores.

Esos errores son el resultado de mis diversas afirmaciones e invariantes sobre el gráfico familiar que se está procesando (por ejemplo, después de caminar un ciclo, el programa establece que X no puede ser padre y abuelo de Y).

¿Cómo puedo resolver esos errores sin eliminar todas las aserciones de datos?

Partick Höse
fuente
30
Si rastrea su árbol genealógico lo suficientemente atrás, encontrará este problema con mucha más frecuencia de la que quisiera. Abandonar la representación del árbol puede ser doloroso, pero en última instancia sería más correcto.
Thomas
55
No debe agregar afirmaciones para cosas improbables, solo cosas imposibles. Los ciclos son las cosas obvias que no son posibles en un gráfico de árbol genealógico ... nadie puede ser su propio antepasado a través de ningún método. Estas otras afirmaciones son simplemente falsas y deben eliminarse.
pgod 01 de
44
Esta no es una pregunta tonta en el mundo de la cría de mascotas. La técnica estándar allí es hija a padre, madre a hijo, hermana a hermano, nietos a abuelos, y los criadores de mascotas también necesitan el software del árbol genealógico. "Pura raza" mi ¤% # &.
kaleissin 01 de
31
Casarse con primos hermanos era muy común en la Inglaterra victoriana, especialmente entre las clases altas (era una excelente manera de mantener el dinero dentro de la familia). Charles Darwin, por ejemplo, se casó con su prima hermana, Emma Wedgwood. Cualquier software de árbol genealógico necesita soportar situaciones como esta.
rtperson 01 de

Respuestas:

727

Parece que usted (y / o su empresa) tienen un malentendido fundamental de lo que se supone que es un árbol genealógico.

Permítanme aclarar, también trabajo para una empresa que tiene (como uno de sus productos) un árbol genealógico en su cartera, y hemos estado luchando con problemas similares.

El problema, en nuestro caso, y supongo que su caso también, proviene del formato GEDCOM que es extremadamente obstinado sobre lo que debería ser una familia. Sin embargo, este formato contiene algunas ideas falsas sobre cómo se ve realmente un árbol genealógico.

GEDCOM tiene muchos problemas, como la incompatibilidad con las relaciones del mismo sexo, el incesto, etc., que en la vida real ocurre con más frecuencia de lo que imagina (especialmente cuando se remonta en el tiempo al 1700-1800).

Hemos modelado nuestro árbol genealógico a lo que sucede en el mundo real: eventos (por ejemplo, nacimientos, bodas, compromiso, uniones, defunciones, adopciones, etc.). No establecemos ninguna restricción sobre estos, excepto los lógicamente imposibles (por ejemplo, uno no puede ser el propio padre, las relaciones necesitan dos individuos, etc.)

La falta de validaciones nos da una solución más "real", más simple y más flexible.

En cuanto a este caso específico, sugeriría eliminar las afirmaciones, ya que no son válidas universalmente.

Para mostrar problemas (que surgirán), sugeriría dibujar el mismo nodo tantas veces como sea necesario, insinuando la duplicación encendiendo todas las copias al seleccionar una de ellas.

Bert Goethals
fuente
32
Este parece el enfoque correcto, y es lo suficientemente fácil de extender para detectar problemas más complejos. Puede elaborar un conjunto de relaciones "A sucedió antes que B" entre eventos. Por ejemplo, que una persona nació antes de cualquier otro evento que la involucre. Este es un gráfico dirigido. Luego, puede verificar que el gráfico no contenga ciclos. Vea esta pregunta en StackOverflow. Esto debería estar bien hasta que se invente el viaje en el tiempo.
Paul Harrison
41
@ Paul-Harrison Si solo fuera así de simple. En los registros más antiguos (incluso los nuevos) hay inconsistencias de fecha. Bautismo antes del nacimiento, múltiples registros de nacimiento, etc. Así que hasta cierto punto, en los registros oficiales, hay viajes en el tiempo. Permitimos estos datos inconsistentes. Permitimos que los usuarios indiquen qué debe considerar la aplicación "el" registro de nacimiento en caso de duplicados. E indicaremos líneas de tiempo rotas si se encuentran.
Bert Goethals
38
@ ben-voigt GEDCOM es un formato creado por La Iglesia de Jesucristo de los Santos de los Últimos Días. La especificación establece claramente que el matrimonio (MARR) debe ser entre hombres y mujeres. Para el matrimonio o incesto entre personas del mismo sexo, se debe usar la etiqueta ASSO (ASOCIADOS), que también se usa para indicar amistad o ser vecinos. Está claro que el matrimonio entre personas del mismo sexo es una relación de segunda clase dentro de esta especificación. Una especificación más neutral no exigiría relaciones hombre-mujer.
Bert Goethals
1
@Bert Goethals: está confundiendo a GEDCOM con ciertos programas que no admiten el matrimonio entre personas del mismo sexo (PAF, Legacy). GEDCOM no excluye construcciones como "0 @ F1 @ FAM / 1 HUSB @ I1 @ / 1 HUSB @ I2 @" y, por lo tanto, admite matrimonios del mismo sexo si su software lo desea.
Pierre
1
@Pierre Puedes engañar al sistema de hecho. Esto es directamente de los documentos 5.5.1: "MARR {MATRIMONIO}: = Un evento legal, de derecho común o consuetudinario de crear una unidad familiar de un hombre y una mujer como marido y mujer". ( homepages.rootsweb.ancestry.com/~pmcbride/gedcom/55gcappa.htm ) Como puede ver, no hay matrimonio entre personas del mismo sexo aquí.
Bert Goethals
563

Relaja tus afirmaciones.

No cambiando las reglas, que probablemente sean muy útiles para el 99.9% de sus clientes al detectar errores al ingresar sus datos.

En cambio, cámbielo de un error "no se puede agregar la relación" a una advertencia con un "agregar de todos modos".

Ben Voigt
fuente
143
Cuando se encuentra una situación muy improbable , es decir, una en la que un usuario generalmente solo lo haría por error, es una buena idea mostrarle una advertencia. Esa es una buena respuesta. Pero luego deje que el usuario continúe si está realmente seguro de querer hacerlo. Así que creo que esta es una buena respuesta, incluso si no entra en detalles.
thomasrutter 01 de
15
¡Buena respuesta! Me pregunto, ¿cómo manejará este tipo de software la situación "Soy mi propio abuelo" ( youtube.com/watch?v=eYlJH81dSiw )?
Zaur Nasibov
44
Esto no es realmente una respuesta, porque creo que el problema proviene de atravesar el árbol. Sin embargo, es una buena sugerencia.
bdwakefield 01 de
3
@bdwakefield: La pregunta era "¿Cómo resuelvo estos errores sin eliminar todas las afirmaciones de datos?" Creo que he respondido eso.
Ben Voigt
2
@Ben Depende de para qué son las afirmaciones. Si evitan que ocurran bucles infinitos o errores fatales, entonces está sugiriendo efectivamente eliminar las afirmaciones. Si solo están allí para advertir a un usuario de un posible error, entonces su respuesta es buena.
rm999
224

Aquí está el problema con los árboles genealógicos: no son árboles. Son gráficos acíclicos dirigidos o DAG. Si entiendo los principios de la biología de la reproducción humana correctamente, no habrá ningún ciclo.

Hasta donde yo sé, incluso los cristianos aceptan matrimonios (y, por lo tanto, hijos) entre primos, lo que convertirá el árbol genealógico en un DAG familiar.

La moraleja de la historia es: elegir las estructuras de datos correctas.

exDM69
fuente
77
Necesitaría una restricción adicional de cada nodo que tenga 1 o 2 nodos máximos apuntando a él para la reproducción in vitro y sexual. Aunque para ser más fiel a la vida real, puede permitir múltiples líneas discontinuas para una descendencia incierta por parte del padre (siempre está claro quién es la madre, pero solo las pruebas de ADN pueden asegurar quién es el padre, y eso rara vez se hace incluso hoy), o incluso para ambos se tiene en cuenta la adopción.
manixrock 01 de
77
@manixrock: como esta pregunta es sobre casos raros, me gustaría afirmar que no siempre está claro quién es la madre. adopciones, bebés abandonados, madres sustitutas, etc., todo puede complicar las cosas.
Peter Recore 01 de
99
No es necesariamente acíclico, ¿verdad? El hombre se casa con la abuela.
Ed Ropple
13
El hombre que se casa con su abuela no se convertirá en su propio abuelo y agregará un ciclo. Si tienen hijos, será un borde de gráfico regular que no sea de ciclismo.
exDM69
11
En realidad son DOS ADG. Existe el gráfico de paternidad y el gráfico de relación legal. Por lo general, lo mismo, pero divergente más de lo que cabría esperar.
JSacksteder
115

Supongo que tiene algún valor que identifica de manera única a una persona en la que puede basar sus cheques.

Este es complicado. Suponiendo que desea mantener la estructura en un árbol, sugiero esto:

Supongamos esto: Atiene hijos con su propia hija.

Ase agrega al programa como Ay como B. Una vez en el papel de padre, llamémoslo novio.

Agregue una is_same_for_out()función que le diga a la salida que genera parte de su programa que todos los enlaces que van Binternamente deberían ir a la Apresentación de datos.

Esto hará un poco de trabajo extra para el usuario, pero supongo que sería relativamente fácil de implementar y mantener.

A partir de eso, podría trabajar en la sincronización de código Ay Bevitar inconsistencias.

Esta solución seguramente no es perfecta, pero es un primer enfoque.

Eduard Thamm
fuente
99
Probablemente, tales nodos "proxy" son de hecho una solución adecuada. Sin embargo, no tengo idea de cómo se pueden poner en la interfaz de usuario sin ofender al usuario. Puedo decirle que escribir software que trata con personas reales (especialmente sus clientes) no es fácil.
Partick Höse
66
Nunca termina: el nuevo hijo de B será su propio tío. ¡Consideraría un reembolso completo por el programa!
Bo Persson
3
@Will A: ¿Y luego se da cuenta de que él también es su propia madre y recluta a su yo más joven en la agencia del tiempo?
Null Set
2
La duplicación (y sincronización) de datos dentro de un sistema es una mala práctica. Indica que la solución es subóptima y debe reconsiderarse. Si fuera necesario crear nodos adicionales (duplicados), indíquelo como un proxy y delegue las lecturas y escrituras de datos al nodo original.
Bert Goethals
84

Debería centrarse en lo que realmente hace valor para su software . ¿Vale la pena el precio de la licencia el tiempo dedicado a hacer que funcione para UN consumidor? Probablemente no.

Le aconsejo que se disculpe con este cliente, que le diga que su situación está fuera del alcance de su software y que le emita un reembolso.

christopheml
fuente
3
Muy cierto. Pero también sopesan otros problemas potenciales con problemas similares que otros han planteado.
contrato del Prof. Falken incumplió el
2
Por supuesto. El razonamiento es: si es un caso marginal raro en una aplicación no crítica, no es necesario que arregle o implemente nada. Si realmente está perjudicando a sus usuarios, tiene valor trabajar en ello.
christopheml
10
Probablemente todos tengan algún caso de incesto en algún lugar de su ascendencia. Así que golpeará ese golpe si uno profundiza en la historia familiar (demasiado).
datenwolf
1
Hacer un árbol genealógico de alguna situación extraña (realeza endogámica, Fritzl, etc.) es un uso válido del software.
Bulwersator
1
Un software de árbol genealógico que no permita que se casen primos segundos es inútil. Casi todas las familias tienen al menos un caso de esto. Por eso creo que el ejemplo original está hecho para el efecto.
Fuzzy76
79

Debería haber configurado la familia Atreides (ya sea moderna, Dune o antigua, Edipo Rey ) como un caso de prueba. No encuentra errores al usar datos desinfectados como un caso de prueba.

usuario779752
fuente
2
Lamentablemente, demasiadas personas piensan primero en los datos 'ok' en lugar de los casos extremos que rompen sus sistemas.
sjas
59

Esta es una de las razones por las cuales idiomas como "Go" no tienen afirmaciones. Se utilizan para manejar casos en los que probablemente no pensó, con demasiada frecuencia. Solo debes afirmar lo imposible, no simplemente lo improbable . Hacer esto último es lo que le da a las afirmaciones una mala reputación. Cada vez que escribe assert(, aléjese durante diez minutos y piense realmente en ello.

En su caso particularmente inquietante, es concebible y atroz que tal afirmación sea falsa en circunstancias raras pero posibles. Por lo tanto, trátelo en su aplicación, aunque solo sea para decir "Este software no fue diseñado para manejar el escenario que presentó".

Afirmar que su tatara tatarabuelo es su padre como imposible es algo razonable.

Si estuviera trabajando para una compañía de pruebas que fue contratada para probar su software, por supuesto, habría presentado ese escenario. ¿Por qué? Cada 'usuario' juvenil pero inteligente hará exactamente lo mismo y saboreará en el 'informe de error' resultante.

Tim Post
fuente
55
De acuerdo con el argumento 'cuándo usar las aserciones'; no veo cómo se relaciona con "algunos idiomas tienen afirmaciones, Go no".
phooji 01 de
2
@Red Hue: a veces los compiladores hacen que lo imposible ... sea posible. Algunas versiones de gcc piensan -10 == 10 en la implementación abs ().
Tim Post
2
@Red Hue: el objetivo de las afirmaciones es documentar y probar condiciones que siempre deben ser verdaderas (o falsas). Ayuda a evitar que usted (y otros) "arreglen" las cosas de tal manera que surjan esos casos imposibles, ya que entonces romperían explícitamente (en lugar de sutilmente) la aplicación. Si hay una razón válida para que aparezca un caso "imposible", entonces has afirmado demasiado.
cHao
1
@cHao @Tim Post Solo estoy tratando de entender por qué Go no tener afirmaciones es algo bueno ya que la mayoría de ustedes está de acuerdo en que es importante tener una afirmación.
Arlen
55
Tener aserciones (o código similar a aserciones) es irrelevante. El código en idiomas como Go puede y hará suposiciones sobre la estructura de datos; simplemente no puede documentar y hacer cumplir esas suposiciones con afirmaciones. En pocas palabras: la aplicación tiene un error.
Tommy McGuire
41

Odio comentar sobre una situación tan jodida, pero la forma más fácil de no reajustar a todos sus invariantes es crear un vértice fantasma en su gráfico que actúe como un proxy para el padre incestuoso.

Sean
fuente
37

Entonces, he trabajado en el software del árbol genealógico. Creo que el problema que estás tratando de resolver es que debes poder caminar por el árbol sin entrar en bucles infinitos; en otras palabras, el árbol debe ser acíclico.

Sin embargo, parece que estás afirmando que solo hay un camino entre una persona y uno de sus antepasados. Eso garantizará que no haya ciclos, pero es demasiado estricto. Biológicamente hablando, la descendencia es un gráfico acíclico dirigido (DAG). El caso que tiene es ciertamente un caso degenerado, pero ese tipo de cosas suceden todo el tiempo en árboles más grandes.

Por ejemplo, si observa los 2 ^ n antepasados ​​que tiene en la generación n, si no hubiera superposición, entonces tendría más antepasados ​​en el año 1000 DC que personas vivas. Entonces, debe haber una superposición.

Sin embargo, también tiende a obtener ciclos que no son válidos, solo datos incorrectos. Si atraviesas el árbol, entonces los ciclos deben ser tratados. Puede hacer esto en cada algoritmo individual o en carga. Lo hice en carga.

Encontrar ciclos verdaderos en un árbol se puede hacer de varias maneras. La forma incorrecta es marcar a cada antepasado de un individuo determinado, y al atravesar, si la persona a la que va a pasar ya está marcada, corte el enlace. Esto cortará relaciones potencialmente precisas. La forma correcta de hacerlo es comenzar desde cada individuo y marcar a cada antepasado con el camino hacia ese individuo. Si la nueva ruta contiene la ruta actual como una ruta secundaria, entonces es un ciclo y debe romperse. Puede almacenar rutas como vector <bool> (MFMF, MFFFMF, etc.), lo que hace que la comparación y el almacenamiento sean muy rápidos.

Hay algunas otras formas de detectar ciclos, como enviar dos iteradores y ver si alguna vez chocan con la prueba de subconjunto, pero terminé usando el método de almacenamiento local.

También tenga en cuenta que no necesita cortar realmente el enlace, simplemente puede cambiarlo de un enlace normal a un enlace 'débil', al que no siguen algunos de sus algoritmos. También tendrá que tener cuidado al elegir qué enlace marcar como débil; a veces puedes averiguar dónde se debe romper el ciclo mirando la información de la fecha de nacimiento, pero a menudo no puedes descubrir nada porque faltan tantos datos.

tfinniga
fuente
Cuidado con esos supuestos; un padre y una madre no son un hecho cuando las personas se adaptan, o las lesbianas que se consideran a sí mismas como padres, en un futuro cercano pueden incluso ser biológicamente los padres, al menos de las niñas. Para el caso, si aplicamos dolly a los humanos, incluso la suposición "una persona tiene dos padres distintos" está fuera de lugar.
Agrajag
1
@Agrajag, sí, por eso especifiqué "biológicamente hablando" para la detección del ciclo. Incluso biológicamente, hay muchos problemas posibles, como las madres sustitutas y la inseminación artificial. Si también permite adopciones y otros métodos no biológicos para definir a los padres, entonces es posible tener un ciclo verdadero válido en un árbol; por ejemplo, tal vez alguien adopte a sus abuelos cuando sean viejos y ya no puedan cuidarse a sí mismos. . Hacer suposiciones sobre la vida familiar de las personas siempre es complicado. Pero cuando escribes software necesitas hacer algunas suposiciones ..
tfinniga
36

Otra falsa respuesta seria para una pregunta tonta:

La respuesta real es utilizar una estructura de datos adecuada. La genealogía humana no se puede expresar completamente usando un árbol puro sin ciclos. Deberías usar algún tipo de gráfico. Además, hable con un antropólogo antes de continuar con esto, porque hay muchos otros lugares en los que se podrían cometer errores similares al tratar de modelar la genealogía, incluso en el caso más simple del "matrimonio monógamo patriarcal occidental".

Incluso si queremos ignorar las relaciones tabúes locales como se discutió aquí, hay muchas formas perfectamente legales y completamente inesperadas de introducir ciclos en un árbol genealógico.

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

Básicamente, el matrimonio de primos no solo es común y esperado, es la razón por la cual los humanos han pasado de miles de pequeños grupos familiares a una población mundial de 6 mil millones. No puede funcionar de otra manera.

Realmente hay muy pocos universales cuando se trata de genealogía, familia y linaje. Casi cualquier suposición estricta sobre las normas que sugieren quién puede ser una tía, o quién puede casarse con quién, o cómo se legitiman los hijos con el propósito de heredar, puede verse alterada por alguna excepción en algún lugar del mundo o de la historia.

clvrmnky
fuente
99
Tu comentario me hizo pensar en la poligamia. El software de genealogía que solo modela la reproducción sexual puede requerir un nombre adjunto al esperma y al óvulo, pero las definiciones más amplias de la estructura familiar no.
Steve Kalemkiewicz
El software de genealogía a menudo permitirá más de un cónyuge en el modelo. La forma en que muestra el modelo en la vista varía ampliamente, incluso dentro de un programa, dependiendo del "modo" que se haya proporcionado.
Todd Hopkinson
20

Dejando a un lado las posibles implicaciones legales, ciertamente parece que debe tratar a un 'nodo' en un árbol genealógico como una persona predecesora en lugar de asumir que el nodo puede ser la única persona.

Haga que el nodo del árbol incluya tanto a una persona como a los sucesores, y luego puede tener otro nodo más profundo en el árbol que incluya a la misma persona con diferentes sucesores.

Will A
fuente
13

Algunas respuestas han mostrado formas de mantener las aserciones / invariantes, pero esto parece un mal uso de aserciones / invariantes. Las afirmaciones son para asegurarse de que algo que debe ser verdadero sea verdadero, y los invariantes deben asegurarse de que algo que no debe cambiar no cambie.

Lo que estás afirmando aquí es que las relaciones incestuosas no existen. Es evidente que hacen existir, por lo que su afirmación no es válida. Puede evitar esta afirmación, pero el error real está en la afirmación misma. La afirmación debe ser eliminada.

Kerkeslager
fuente
8

Su árbol genealógico debe usar relaciones dirigidas. De esta manera no tendrás un ciclo.

Patrick Cornelissen
fuente
5

Los datos genealógicos son cíclicos y no caben en un gráfico acíclico, por lo que si tiene afirmaciones contra los ciclos, debe eliminarlos.

La forma de manejar esto en una vista sin crear una vista personalizada es tratar al padre cíclico como un padre "fantasma". En otras palabras, cuando una persona es padre y abuelo de la misma persona, entonces el nodo abuelo se muestra normalmente, pero el nodo padre se representa como un nodo "fantasma" que tiene una etiqueta simple como ("ver abuelo" ) y señala al abuelo.

Para hacer cálculos, es posible que necesite mejorar su lógica para manejar gráficos cíclicos de modo que no se visite un nodo más de una vez si hay un ciclo.

Tyler Durden
fuente
4

Lo más importante es hacerlo avoid creating a problem, así que creo que debes usar una relación directa para evitar tener un ciclo.

Como dijo @markmywords, #include "fritzl.h".

Finalmente tengo que decir recheck your data structure. Tal vez algo va mal allí (tal vez una lista enlazada bidireccional resuelva su problema).

Nasser Hadjloo
fuente
4

Las afirmaciones no sobreviven a la realidad

Por lo general, las afirmaciones no sobreviven al contacto con datos del mundo real. Es una parte del proceso de ingeniería de software decidir, con qué datos desea tratar y cuáles están fuera del alcance.

Gráficos familiares cíclicos

Con respecto a los "árboles" familiares (de hecho, son gráficos completos, incluidos los ciclos), hay una bonita anécdota:

Me casé con una viuda que tenía una hija adulta. Mi padre, que a menudo nos visitaba, se enamoró de mi hijastra y se casó con ella. Como resultado, mi padre se convirtió en mi hijo y mi hija se convirtió en mi madre. Algún tiempo después, le di a mi esposa un hijo, hermano de mi padre, y mi tío. La esposa de mi padre (que también es mi hija y mi madre) tuvo un hijo. Como resultado, obtuve un hermano y un nieto en la misma persona. Mi esposa ahora es mi abuela, porque ella es la madre de mi madre. Así que soy el esposo de mi esposa y, al mismo tiempo, el nieto de mi esposa. En otras palabras, soy mi propio abuelo.

Las cosas se ponen aún más extrañas cuando tomas en cuenta a los sustitutos o la "paternidad difusa".

Cómo lidiar con eso

Definir ciclos como fuera de alcance

Podrías decidir que tu software no debería tratar casos tan raros. Si ocurre tal caso, el usuario debe usar un producto diferente. Esto hace que lidiar con los casos más comunes sea mucho más robusto, porque puede mantener más afirmaciones y un modelo de datos más simple.

En este caso, agregue algunas buenas características de importación y exportación a su software, para que el usuario pueda migrar fácilmente a un producto diferente cuando sea necesario.

Permitir relaciones manuales

Podría permitir al usuario agregar relaciones manuales. Estas relaciones no son "ciudadanos de primera clase", es decir, el software los toma tal cual, no los verifica y no los maneja en el modelo de datos principal.

El usuario puede manejar casos raros a mano. Su modelo de datos seguirá siendo bastante simple y sus afirmaciones sobrevivirán.

Tenga cuidado con las relaciones manuales. Existe la tentación de hacerlos completamente configurables y, por lo tanto, crear un modelo de datos totalmente configurable. Esto no funcionará: su software no escalará, obtendrá errores extraños y finalmente la interfaz de usuario quedará inutilizable. Este antipatrón se llama "codificación suave" , y "El WTF diario" está lleno de ejemplos para eso.

Haga que su modelo de datos sea más flexible, omita aserciones, pruebe invariantes

El último recurso sería hacer que su modelo de datos sea más flexible. Tendría que omitir casi todas las afirmaciones y basar su modelo de datos en un gráfico completo. Como muestra el ejemplo anterior, es fácilmente posible ser su propio abuelo, por lo que incluso puede tener ciclos.

En este caso, debe probar exhaustivamente su software. Debes omitir casi todas las afirmaciones, por lo que hay una buena posibilidad de errores adicionales.

Use un generador de datos de prueba para verificar casos de prueba inusuales. Hay bibliotecas rápidos del cheque para Haskell , Erlang o C . Para Java / Scala hay ScalaCheck y Nyaya . Una idea de prueba sería simular una población aleatoria, dejar que se entrecrucen al azar, luego dejar que su software primero importe y luego exporte el resultado. La expectativa sería que todas las conexiones en la salida también están en la entrada y viceversa.

Un caso en el que una propiedad permanece igual se llama invariante. En este caso, el invariante es el conjunto de "relaciones románticas" entre los individuos en la población simulada. Trate de encontrar tantos invariantes como sea posible y pruébelos con datos generados aleatoriamente. Las invariantes pueden ser funcionales, por ejemplo:

  • un tío sigue siendo tío, incluso cuando agrega más "relaciones románticas"
  • cada niño tiene un padre
  • una población con dos generaciones tiene al menos un abuelo

O pueden ser técnicos:

  • Su software no se bloqueará en un gráfico de hasta 10 mil millones de miembros (no importa cuántas interconexiones)
  • Su software escala con O (número de nodos) y O (número de bordes ^ 2)
  • Su software puede guardar y volver a cargar cada gráfico familiar hasta 10 mil millones de miembros

Al ejecutar las pruebas simuladas, encontrará muchos casos extraños de esquina. Arreglarlos llevará mucho tiempo. También perderá muchas optimizaciones, su software funcionará mucho más lento. Tienes que decidir si vale la pena y si esto está dentro del alcance de tu software.

stefan.schwetschke
fuente
3

En lugar de eliminar todas las afirmaciones, aún debe verificar si una persona es su propio padre u otras situaciones imposibles y presentar un error. Tal vez emita una advertencia si es poco probable para que el usuario pueda detectar errores de entrada comunes, pero funcionará si todo es correcto.

Almacenaría los datos en un vector con un número entero permanente para cada persona y almacenaría a los padres y a los niños en objetos personales donde dicho int es el índice del vector. Esto sería bastante rápido entre generaciones (pero lento para cosas como búsquedas de nombres). Los objetos estarían en orden de cuando fueron creados.

ctype.h
fuente
-3

Duplicar al padre (o usar enlace simbólico / referencia).

Por ejemplo, si está utilizando una base de datos jerárquica:

$ #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
fuente
3
El ln -scomando no funciona de esa manera; la resolución del enlace Family/Son/Fatherse buscará Family/Son/Daughter/Fatherdesde abajo Family/Son, donde reside el enlace, no desde .donde emitió el ln -scomando.
musiphil
48
la clonación está prohibida por las convenciones de ginebra
MikeIsrael