Data structures 深度优先搜索,如何检测钻石依赖关系?

Data structures 深度优先搜索,如何检测钻石依赖关系?,data-structures,graph,Data Structures,Graph,我想知道是否有人可以提供一些关于如何在对图形执行深度优先搜索时检查菱形依赖关系的指针…我有以下图形a->B,a->F,B->C,B->E,C->D,E->D 我正在尝试构造一个表示指定图形的容器的hirearchy,但是当我达到菱形依赖时,我不确定该怎么做。例如,在我的图中,C和E都是B的子容器,当我解析D时,我需要引用C和E。我是否可以检测菱形依赖项并将C和E组合到一个容器中?我不知道您如何定义图形的节点。假设表示节点的一种方法如下所示- public interface Node {

我想知道是否有人可以提供一些关于如何在对图形执行深度优先搜索时检查菱形依赖关系的指针…我有以下图形
a->B,a->F,B->C,B->E,C->D,E->D


我正在尝试构造一个表示指定图形的容器的hirearchy,但是当我达到菱形依赖时,我不确定该怎么做。例如,在我的图中,
C
E
都是
B
的子容器,当我解析
D
时,我需要引用
C
E
。我是否可以检测菱形依赖项并将
C
E
组合到一个容器中?

我不知道您如何定义图形的节点。假设表示节点的一种方法如下所示-

public interface Node {
            int getValue();
            List<Node> getChildren();
        }
公共接口节点{
int getValue();
列出getChildren();
}
这种实现的问题是——我们不知道一个节点的父节点。如果我们有办法知道谁是一个节点的paretent,我们就可以找出diamond依赖关系

例如,在你的例子中,我们应该从树的底部开始,我们可以看到D有两个parenet,它们来自B。
所以我想说,建立一个图表,它不仅照顾孩子,也照顾父母。然后在一个过程中,找出哪些节点具有多个父节点(如D),以及这些Parenet(C和E)是否具有相同的父节点(B)。

我不知道如何定义图中的节点。假设表示节点的一种方法如下所示-

public interface Node {
            int getValue();
            List<Node> getChildren();
        }
公共接口节点{
int getValue();
列出getChildren();
}
这种实现的问题是——我们不知道一个节点的父节点。如果我们有办法知道谁是一个节点的paretent,我们就可以找出diamond依赖关系

例如,在你的例子中,我们应该从树的底部开始,我们可以看到D有两个parenet,它们来自B。
所以我想说,建立一个图表,它不仅照顾孩子,也照顾父母。然后在一个过程中,找出哪些节点有多个父节点(如D节点),以及这些Parenet(C和E)是否有相同的父节点(B)。

我发现最容易想到使用颜色的图形算法

所有节点都以白色开头

正在处理的节点为灰色

处理完节点后,将其涂成黑色

一旦遇到节点,就将其着色为灰色

处理完节点的子节点后,可以将其着色为黑色


如果你遇到一个黑色节点,那么你遇到了钻石依赖。

我发现最容易想到使用颜色的图形算法

所有节点都以白色开头

正在处理的节点为灰色

处理完节点后,将其涂成黑色

一旦遇到节点,就将其着色为灰色

处理完节点的子节点后,可以将其着色为黑色


如果你遇到一个黑色节点,那么你就遇到了钻石依赖。

图论是一个非常庞大而复杂的数学领域。这是一件很危险的事情:)即使是图论的基本应用,也很难找到简单的解释。很有可能,任何你可能遇到的图形都被打死了,并且有比你解决问题时想象的多5倍的陷阱和陷阱


我猜你会在这里看到一些非常合理的建议,然后过一会儿,他们会被认为是部分错误,甚至大部分错误。仔细一点。

图论是一个非常庞大而复杂的数学领域。这是一件很危险的事情:)即使是图论的基本应用,也很难找到简单的解释。很有可能,任何你可能遇到的图形都被打死了,并且有比你解决问题时想象的多5倍的陷阱和陷阱


我猜你会在这里看到一些非常合理的建议,然后过一会儿,他们会被认为是部分错误,甚至大部分错误。仔细一步。

我不确定你到底想做什么,但最晚当你的图表包含循环时,你真的需要检测你在搜索过程中反复找到的节点。通常,这是通过在处理节点时以某种方式标记节点来完成的,以便以后可以查看之前是否已经访问过它们。在您的案例中,这种方法的效果如何取决于您的实现以及这些节点的外观……

我不确定您到底想做什么,但最晚当您的图形包含循环时,您确实需要检测在搜索过程中反复找到的节点。通常,这是通过在处理节点时以某种方式标记节点来完成的,以便以后可以查看之前是否已经访问过它们。在您的案例中,这种方法的效果如何取决于您的实现以及这些节点的外观……

Rohan,因为我有时会教授算法和数据结构,我可能有偏见,但我怀疑您需要阅读一本图形算法书。有很多不同的方法来做这些事情,但并不完全清楚你真正想做什么。是的,在这种情况下,如果有两个节点的传入边和传出边与相同节点(此处,(B,E),(B,C)(C,D),(E,D))相连,则将两个节点C和E合并为“C,E”节点是合法的。也可以将D分解为D1和D2,使其成为一棵树而不是DAG


也就是说,根据问题的不同,这样做是合法的。

Rohan,因为我有时教算法和数据结构,我可能有偏见,但我怀疑你需要