如何在Java中构建加权有向无环图

如何在Java中构建加权有向无环图,java,directed-acyclic-graphs,weighted,Java,Directed Acyclic Graphs,Weighted,我搜索过类似的主题,但答案对我的理解和理解水平来说太模糊了,我认为它们对我的问题不够具体 类似的线程: 问题: 我已格式化一个文本文件,其中包含以下格式的数据… 示例数据集: 围棋:0000109#围棋:0000111#围棋:0000112#围棋:0000112#围棋:0000113#围棋:000013#围棋:0070312#围棋:0070522#围棋:0070912#围棋:0070912#围棋:0070913#围棋:0070913#围棋:00712#围棋:00022的一部分 GO:0000

我搜索过类似的主题,但答案对我的理解和理解水平来说太模糊了,我认为它们对我的问题不够具体

类似的线程:

问题:
我已格式化一个文本文件,其中包含以下格式的数据…
示例数据集:
围棋:0000109#围棋:0000111#围棋:0000112#围棋:0000112#围棋:0000113#围棋:000013#围棋:0070312#围棋:0070522#围棋:0070912#围棋:0070912#围棋:0070913#围棋:0070913#围棋:00712#围棋:00022的一部分
GO:0000112#部分:GO:0000442
GO:0000118#is#a:GO:0016581#is#a:GO:0034967#is#a:GO:0070210#is#a:GO:0070211#is#a:GO:0070822#is#a:GO:0070823#is#a:GO:0070824
围棋:0000120是围棋:围棋:0000500是围棋:0005668是围棋:0070860
围棋:0000123是围棋:0005671是围棋:0043189是围棋:0070461是围棋:0070775是围棋:0072487
围棋:0000126#is#a:围棋:0034732#is#a:围棋:0034733
GO:0000127#第#部分:GO:0034734#第#部分:GO:0034735
围棋:0000133#是围棋:0031560#是围棋:0031561#是围棋:0031562#是围棋:0031563#部分围棋:0031500
GO:0000137#第#部分:GO:0000136

我希望从这些数据构造一个加权定向DAG(上面只是一个片段)。106kb的整个数据集如下所示:

-------------------------------------------------- 考虑到逐行,每行的数据解释如下…
第一行作为示例:
围棋:0000109#围棋:0000111#围棋:0000112#围棋:0000112#围棋:0000113#围棋:000013#围棋:0070312#围棋:0070522#围棋:0070912#围棋:0070913#围棋:0071942#围棋:00022的一部分#

“#”是行数据的delimeter/tokenizer。
第一个术语GO:0000109是节点名。
is_a:GO:xxxxxxx或部分:GO:xxxxxxx的后续术语是连接到GO:0000109的节点。
如数据集中所示,后面的一些术语也有联系。
当为_a时,边缘的权重为0.8。
当它是的一部分时,边的权重为0.6

-------------------------------------------------- 我有Google-d关于DAG是怎样的,我理解这个概念。然而,我仍然不知道如何将其转化为代码。我正在使用Java。
根据我的理解,图形通常由节点和圆弧组成。此图是否需要邻接列表来确定连接的方向?如果是这样的话,我不知道如何结合图形和邻接列表来相互通信。 在构建图之后,我的第二个目标是从根节点找出每个节点的度。数据集中有一个根节点

为了便于说明,我绘制了下面第一行数据的连接示例:


我希望你们能理解我在这里想要实现的目标。谢谢你仔细检查我的问题。:)

因为它更容易思考,所以我更愿意将它表示为一棵树。(还可以更轻松地遍历地图并保持中间度数。)

您可以有一个
节点
类,该类将包含子
节点
对象的集合。如果必须,还可以将子关系表示为
关系
对象,该对象将具有权重和
节点
指针,并且可以存储
关系
对象的集合

然后,您可以从根开始在树上行走,并用其度数标记每个访问的节点

class Node{
    String name;
    List<Relationship> children;
}

class Relationship{
    Node child;
    double weight;
}

class Tree{
    Node root;
}
节点
应该有如下方法:

public Node findNodeByName(String name);
public void addChild(Node n, double weight);
然后,在解析每一行时,调用Tree.findNodeByName()以查找匹配的节点(如果不存在,则创建一个节点……但如果数据良好,则不应该这样做),并将该行上的后续项附加到该节点


正如您所指出的,DAG不能真正转换为树,特别是因为某些节点有多个父节点。您可以做的是插入与多个父节点的子节点相同的节点,也许可以使用哈希表来确定是否已遍历某个特定节点。

因为更容易思考,所以我更愿意将其表示为树。(还可以更轻松地遍历地图并保持中间度数。)

您可以有一个
节点
类,该类将包含子
节点
对象的集合。如果必须,还可以将子关系表示为
关系
对象,该对象将具有权重和
节点
指针,并且可以存储
关系
对象的集合

然后,您可以从根开始在树上行走,并用其度数标记每个访问的节点

class Node{
    String name;
    List<Relationship> children;
}

class Relationship{
    Node child;
    double weight;
}

class Tree{
    Node root;
}
节点
应该有如下方法:

public Node findNodeByName(String name);
public void addChild(Node n, double weight);
然后,在解析每一行时,调用Tree.findNodeByName()以查找匹配的节点(如果不存在,则创建一个节点……但如果数据良好,则不应该这样做),并将该行上的后续项附加到该节点


正如您所指出的,DAG不能真正转换为树,特别是因为某些节点有多个父节点。您可以做的是插入与多个父节点的子节点相同的节点,可能使用哈希表来确定是否已遍历特定节点。

阅读注释时,您似乎对节点如何包含关系感到困惑,而每个节点又包含一个节点。这是一种非常常见的策略,通常称为复合模式

在树的情况下,可以将树视为由多个子树组成-如果要断开节点及其所有祖先与树的连接,断开连接的节点仍然会生成一棵树,尽管是一棵较小的树。因此,表示树的一种自然方式是让每个节点包含其他节点作为子节点。这种方法可以让你递归地做很多事情,对于树来说,这通常也是很自然的

让节点跟踪