如何在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不能真正转换为树,特别是因为某些节点有多个父节点。您可以做的是插入与多个父节点的子节点相同的节点,可能使用哈希表来确定是否已遍历特定节点。阅读注释时,您似乎对节点如何包含关系感到困惑,而每个节点又包含一个节点。这是一种非常常见的策略,通常称为复合模式 在树的情况下,可以将树视为由多个子树组成-如果要断开节点及其所有祖先与树的连接,断开连接的节点仍然会生成一棵树,尽管是一棵较小的树。因此,表示树的一种自然方式是让每个节点包含其他节点作为子节点。这种方法可以让你递归地做很多事情,对于树来说,这通常也是很自然的 让节点跟踪