我试图将家庭关系建模为一个图表,这样我就可以查询它们以找到关联的关系和其他关系。这是一个实践练习,所以我不能使用现有的解决方案,如图形、数据库等等。
我试图建立这样的模型,在相关实体(人)之间存在一个边缘,以表示一种关系。

我就是这样开始的。
public class Person
{
public string Name { get; set; }
List<IEdge> Children { get; set; }
IEdge Spouse { get; set; }
IEdge Father { get; set; }
IEdge Mother { get; set; }
}
public class Edge
{
Person From { get; set; }
Person To { get; set; }
public string RelationshipType { get; set; }
}
public class Family
{
Dictionary<string, Person> familyGraph = new Dictionary<string, Person>();
}邻接列表表示将存储在一个键、值对中,并且来自一个人的所有边缘将存储在相应的person节点中。
因此,用它添加一种关系是很简单的。
现在说到恢复关系,比如找出兄弟姐妹,母子叔叔等等。我有点需要手动导航的边缘,以找到合适的人,为每种类型的关系。对于每一段关系,我都要做同样的事。
例如,为了找到我的侄女,我得去找我妈妈,找到我的兄弟姐妹,接他们的孩子,
因为找到了我的婆婆。我得走遍我妻子找到她妈妈。我想这就是这个数据结构的代码的样子
List<string> FindNeice(string username)
{
currentPerson = GerPerson(username)
siblings = currentPerson.Mother.Children;
niece = siblings.Where(mbox => mbox.Gender == "F").SelectMany(m => m.Children);
}所以每一段关系都要有这样的感觉。是的,有些可以重复使用,因为母子关系和你和你妻子之间交换的人是一样的。
我在想,是否有更好的方法来建模,是否有更好的方法来编写提取关系。
发布于 2019-06-11 05:32:41
家庭关系似乎如此简单,但它们很快就变得复杂起来。你提到了姻亲关系(你是妻子的母亲),但更亲密的关系是复杂的。例如,以兄弟姐妹为例。技术上:
别让我开始谈收养关系。
但让我们暂时抛开这些复杂的事情,设想一个没有异父异母、同父异母的世界:一个简单的家谱。
最灵活的建模方法是有一个Person记录,其中包含有关此人的信息,但不包含任何关系。例如,该信息将是姓名、出生日期等,并且该人有一个永远不会改变的唯一标识符。比如说,64位数字。您有一张大表的Person记录。
您还拥有一大张Relationship记录表。每个记录都包含源、目标和关系类型。有两种关系:父母和配偶。
(我故意把性别关系从这个简单的例子中剔除,因为包括它增加了不必要的复杂性,而目前关于性别认同的社会讨论使它变得更加复杂。)
因此,如果你的直系亲属包括你(乔治),你的父母(玛丽和戴夫),以及你的两个兄弟姐妹(鲍勃和萨利),你的关系是:
Mary, George, Parent
Dave, George, Parent
Mary, Bob, Parent
Dave, Bob, Parent
Mary, Sally, Parent
Dave, Sally, Parent
Mary, Dave, Spouse
Dave, Mary, Spouse把它读成“玛丽是乔治的父母”
请注意,对于是否最好包括相互的配偶关系,有一些争论。我把它们包括在这里是因为这样更容易解释。
因此,如果你想找到一个人的兄弟姐妹,你可以这样做:
然后,您可以选择是为更复杂的关系编写代码,还是为这些关系开发简单的类似脚本的定义。考虑:
parents - intrinsic function
children - intrinsic function
spouse - intrinsic function
siblings - (parents children) (probably should be an intrinsic, to eliminate self)
grandparents - (parents parents)
uncles/aunts - (parents siblings)
cousins - (parents siblings children)
parents-in-law - (spouse parents)
siblings-in-law - (spouse siblings)
nieces/nephews - (siblings children) + (siblings-in-law children)考虑到父母/子女和配偶/配偶之间的关系,您可以轻松地编写查询脚本,以查找任何其他类型的家庭关系。编写代码来执行这些查询是非常容易的,如果您尝试手工编写这些查询,您将消除所有可能遇到的问题。
编写代码就变成了编写四个内在函数(Parents、Children、Siblings和Spouse)的问题,每个函数都以IEnumerable<PersonId>作为参数并返回IEnumerable<PersonId>,然后组合这些函数。Siblings函数必须从结果中排除输入参数中的任何值。表兄妹变成:
var person = new List<PersonId> {personId};
var cousins = person.Parents().Siblings().Children();编写代码以从我描述的简单查询定义生成这些查询并不是非常困难的。或者,如果您更愿意使用静态关系,则可以为每个关系编写单独的函数。
现在,如果您想将其扩展到同级兄弟姐妹、同父异母等,您可以保持相同的基本关系,并添加更多的信息,如关系子类型。您仍然会查询基本的父/子关系,但如果需要,则筛选出“步骤”和“半个”或其他子类型。对于性别关系,只需在Person记录中添加性别即可。对于姐妹,查询兄弟姐妹并筛选结果,使其只包含女性。
现在,如果要扩展查询定义以包括性别,则如下所示:
brother - (siblings male)
grandmother - (parents parents female)
maternal-uncle - (parents female siblings male)
spouse-step-sister - (spouse siblings step female)https://stackoverflow.com/questions/56519345
复制相似问题