使用图表建模家庭关系 [英] Modeling family relationships using a graph

查看:61
本文介绍了使用图表建模家庭关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将家庭关系建模为图表,以便我可以查询它们以找到关联的关系和其他关系.这是一个练习,所以我不能使用现有的解决方案,例如图形数据库等.

I am trying to model family relationship as a graph so that I can query them to find associated relationship and others. This is for a practice exercise so I can't use existing solutions like graph databases and so on.

我正在尝试对类似的东西进行建模,其中相关对象之间存在一条边 实体(人)表示关系.

I'm trying to model something like this where an edge exists between related entities(Person) to signify a relationship.

这就是我的入门方式.

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>();
}

邻接表表示形式将存储在键,值对中,并且人的所有边都将存储在相应的人"节点中.

The adjacency list representation will be stored in a key, value pair and all the edges from a person will be stored in the corresponding Person node.

因此添加关系很简单.

现在,在找回关系时,例如找出同胞,母叔叔等等.我有点必须手动导航边缘以找到适合每种关系类型的合适人员.对于每种关系,我都必须做同样的事情.

Now when it comes to retrieving relationship, like finding out siblings, Maternal Uncle and so on. I kinda have to manually navigate the edges to find the appropriate person for each type of relationship. And for each relationship, I'll have to do the same.

例如,要找到我的侄女,我必须走遍我的妈妈,找到我的兄弟姐妹并找到他们的孩子,

For example, for finding my niece, I'll have to traverse to my mom find my siblings and get their children,

寻找我的岳母.我必须横穿我的妻子找到她的妈妈. 我在想,这就是这种数据结构的代码的样子

for finding my mother in law. I have to traverse to my wife find her mum. I'm thinking this is how the code will look like with this data structure

List<string> FindNeice(string username)
{
    currentPerson = GerPerson(username)
    siblings = currentPerson.Mother.Children;
    niece = siblings.Where(mbox => mbox.Gender == "F").SelectMany(m => m.Children);
}

因此每个关系都必须存在.是的,有些可以重用,因为母子关系与您和妻子之间交换的始作俑者相同.

So this has to be there for every relationship. Yes, some can be reused because Maternal/Paternal relationships are the same as starting person swapped between you and your wife.

我在考虑是否有更好的方法对此建模,也有更好的方法来编写提取关系.

I'm thinking if there is a better way to model this and a better way to write extraction relationships.

推荐答案

家庭关系看起来很简单,但很快就会变得复杂.您提到姻亲关系(您是妻子的母亲),但更紧密的关系却很复杂.例如,考虑同级.技术上:

Family relationships seem so simple, but they become complex in a hurry. You mention in-law relationships (you're wife's mother), but even closer relationships are complex. Consider siblings, for example. Technically:

  • 兄弟姐妹是与您有相同的生母父亲的人.
  • 同父异母的兄弟姐妹是您与同一位亲生母亲父亲同住的人.
  • 继兄弟姐妹是指其亲生母亲或父亲已与您的亲生母亲或父亲结婚的人.
  • A sibling is a person with whom you share the same biological mother and father.
  • A half-sibling is a person with whom you share the same biological mother or father.
  • A step-sibling is a person whose biological mother or father is married to your biological mother or father.

甚至都不要让我开始领养关系.

And don't even get me started on adoptive relationships.

但是让我们暂时将这些复杂性放在一旁,并假设一个没有继兄弟,同父异母姐妹等的世界:一个简单的家谱.

But let's put those complications aside for a moment and assume a world without step-brothers, half-sisters, etc: a simple family tree.

对此建模最灵活的方法是拥有一个Person记录,其中包含有关该人的信息,但不包含有关任何关系的信息.该信息将是例如姓名,出生日期等.此人具有一个唯一的标识符,该标识符永远不会改变.说一个64位数字.您有一个很大的Person记录表.

The most flexible way to model this is to have a Person record that contains information about that person, but not about any relationships. That info would be, for example, name, date of birth, etc. And that person has a unique identifier that won't ever change. Say, a 64-bit number. You have a big table of Person records.

您还有一个很大的Relationship记录表.每个记录都包含源,目标和关系类型.有两种类型的关系:父母和配偶.

You also have a big table of Relationship records. Each record contains the Source, the Target, and the type of relationship. There are two types of relationships: Parent, and Spouse.

(我故意从这个简单的示例中删除了性别关系,因为包括它会增加不必要的复杂性,而当前关于性别身份的社会讨论使它变得更加复杂.)

(I've purposely left gendered relationships out of this simple example because including it adds needless complexity, and the current social discussion about gender identity makes it even more complicated.)

因此,如果您的直系亲属由您(乔治),父母(玛丽和戴夫)和两个兄弟姐妹(鲍勃和莎莉)组成,则亲戚关系为:

So if your immediate family consists of you (George), your parents (Mary and Dave), and your two siblings (Bob and Sally), the relationships are:

Mary, George, Parent
Dave, George, Parent
Mary, Bob, Parent
Dave, Bob, Parent
Mary, Sally, Parent
Dave, Sally, Parent
Mary, Dave, Spouse
Dave, Mary, Spouse

读作玛丽是乔治的父母".

Read that as "Mary is George's Parent."

请注意,关于是否最好包括互惠的配偶关系存在一些争论.我将它们包括在这里是因为这样更容易推理.

Note that there is some debate about whether it's best to include the reciprocal spousal relationships. I've included them here because it's easier to reason about that way.

因此,如果要查找某个人的兄弟姐妹,请执行以下操作:

So if you want to find a person's siblings, you do this:

  1. 在关系"表中查询该人的ID为目标"的所有关系以及父"关系的类型.这会给您列出此人父母的标识符的列表.
  2. 在关系"表中查询所有关系,其中父母的标识符之一是源",关系类型是父母".这样就可以列出所有父母的孩子.该列表将包括原始人和所有父母的子女:按照定义,原始人的兄弟姐妹.

然后,您可以选择是要为更复杂的关系编写代码,还是为这些关系开发简单的类似于脚本的定义.考虑:

You can then choose whether you want to write code for the more complex relationships, or develop simple script-like definitions for those. Consider:

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)

鉴于父母/子女和配偶/配偶的关系,您可以轻松地编写查询脚本以查找任何其他类型的家庭关系.编写代码来执行这些查询非常容易,并且消除了尝试手工编写代码时会遇到的各种问题.

Given the parent/child and spouse/spouse relationships, you can easily script queries to find any other type of familial relationship. Writing the code to perform those queries is pretty easy, and you eliminate all kinds of problems you'll encounter if you try to hand-code them.

编码这是编写四个内在函数(ParentsChildrenSiblingsSpouse)的问题,每个函数都将IEnumerable<PersonId>作为参数并返回IEnumerable<PersonId> ,然后组合这些功能. Siblings函数必须从结果中排除输入参数中的任何值.表兄弟变成:

Coding it becomes a matter of writing the four intrinsic functions (Parents, Children, Siblings, and Spouse), each of which takes as a parameter an IEnumerable<PersonId> and returns an IEnumerable<PersonId>, and then combining those functions. The Siblings function has to exclude from the result any values that were in the input parameter. Cousins becomes:

var person = new List<PersonId> {personId};
var cousins = person.Parents().Siblings().Children();

编写代码以根据我描述的简单查询定义生成那些查询并不是很困难.或者,如果您希望使用静态关系,则可以为每个关系编写单独的函数.

Writing the code to generate those queries from the simple query definitions I described isn't terribly difficult. Or, if you'd rather go with static relationships, you can write individual functions for each of the relationships.

现在,如果要将其扩展到继兄弟姐妹,半兄弟姐妹等,则可以保持相同的基本关系,并添加更多信息,例如关系子类型.您仍然会查询基本的父/子关系,但是如果需要,可以过滤掉步骤"和半"或其他子类型.对于性别关系,只需将性别添加到Person记录中.对于姐妹,请查询同级并将结果过滤为仅包括雌性.

Now, if you want to extend it to step-siblings, half-siblings, etc., you keep the same basic relationships and add more information like relationship sub-type. You'd still query for the basic parent/child relationship, but then filter out the "steps" and "halfs" or other sub-types if you want. For gendered relationships, just add a gender to the Person record. For sister, query for siblings and filter the result to include only females.

现在,如果您想扩展查询定义以包括性别,它将变成:

Now if you want to extend your query definitions to include gender, it becomes something like:

brother - (siblings male)
grandmother - (parents parents female)
maternal-uncle - (parents female siblings male)
spouse-step-sister - (spouse siblings step female)

这篇关于使用图表建模家庭关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆