我是一些家谱软件(用C++和Qt编写)的开发人员。直到我的一位客户给我邮寄了一份错误报告,我才发现问题。问题是,客户有两个孩子和自己的女儿,因此,由于错误,他无法使用我的软件。

这些错误是我对正在处理的族图的各种断言和不变量的结果(例如,在走完一个循环后,程序声明X不能既是Y的父亲又是Y的祖父)。

如何在不删除所有数据断言的情况下解决这些错误?


当前回答

你应该把Atreides家族(现代的Dune,或古代的Oedipus Rex)作为一个测试案例。通过使用经过净化的数据作为测试用例,您不会发现错误。

其他回答

家谱数据是循环的,不适合于非循环图,所以如果你有针对循环的断言,你应该删除它们。

在不创建自定义视图的情况下在视图中处理此问题的方法是将循环父对象视为“幽灵”父对象。换句话说,当一个人同时是同一个人的父亲和祖父时,祖父节点正常显示,但父亲节点被渲染为“幽灵”节点,该节点具有简单的标签(如“看见祖父”)并指向祖父。

为了进行计算,您可能需要改进处理循环图的逻辑,以便在存在循环的情况下不会多次访问节点。

看来你(和/或你的公司)对家谱应该是什么有着根本的误解。

让我澄清一下,我也在一家公司工作,该公司的产品组合中有一个家谱(作为其产品之一),我们一直在解决类似的问题。

在我们的案例中,我假设你的案例也是如此,问题来自于GEDCOM格式,它对家庭应该是什么非常有见解。然而,这种格式包含了一些关于家庭树真实外观的严重误解。

GEDCOM有很多问题,例如同性关系不相容、乱伦等。现实生活中发生的事情比你想象的要多(尤其是当追溯到1700-1800年时)。

我们已经将我们的家谱模型化为现实世界中发生的事情:事件(例如,出生、婚礼、订婚、结婚、死亡、收养等)。我们没有对这些事情施加任何限制,但逻辑上不可能的事情除外(例如,一个人不能成为自己的父母,关系需要两个人,等等)

缺乏验证为我们提供了一个更“真实”、更简单、更灵活的解决方案。

对于这个具体的案例,我建议删除这些断言,因为它们并不普遍适用。

为了显示问题(可能会出现),我建议根据需要多次绘制同一节点,通过选择其中一个副本点亮所有副本来暗示重复。

我讨厌评论这种糟糕的情况,但最简单的方法是在你的图中创建一个虚拟顶点,作为回到乱伦父亲的代理。

我想,你有一些价值,可以唯一地识别一个人,你可以根据这个人进行检查。

这是一个棘手的问题。假设您希望将结构保持为树,我建议如下:

假设这样:A和自己的女儿有孩子。

A在节目中以A和B的身份加入节目。一旦扮演了父亲的角色,我们就称之为男朋友。

添加一个is_same_for_out()函数,该函数告诉程序的输出生成部分,所有内部指向B的链接在数据表示时都应该指向a。

这将为用户带来一些额外的工作,但我想IT将相对容易实现和维护。

在此基础上,您可以进行代码同步A和B,以避免不一致。

这种解决方案肯定不是完美的,但却是第一种方法。

最重要的是避免产生问题,所以我认为你应该使用直接关系来避免循环。

正如@markmywords所说,#包括“fritzl.h”。

最后,我不得不说重新检查您的数据结构。也许那边出了问题(也许双向链接列表解决了您的问题)。