在开始之前,我对图论不太了解。然而,
引自Wikipedia,
任何没有简单循环的连通图都是树。森林是一个 不相交的树木联盟。
在浏览JUNG库的源代码时,我注意到了forest的定义为
public interface Forest<V,E> extends DirectedGraph<V,E>
在纯粹的语义层面上讲,那是不是不正确?
OR
为什么会这样做有一些具体原因? (比如在某些算法实现中更有意义/易于理解)
PS:我知道DirectedGraph
只是一个标记接口,并没有声明任何函数。因此,使用DirectedGraph
代替UndirectedGraph
会产生任何后果(至少我看不到)。
答案 0 :(得分:1)
鉴于JUNG将树定义为有向图,因此将森林定为有向图也是有意义的 - 有向图的并集是有向图。
这减少了你的问题,树是否应该扩展DirectedGraph。树是Graphs当然是有道理的:它们肯定有节点和边缘,你上面引用的定义将它们定义为某类图。所以问题就变成了,树木应该被引导吗?
通常有意义的是考虑边缘都指向根的有向树(这些用于union-find算法),或者所有边指向远离根(搜索树就是一个例子)。但是,考虑无向树(例如无向图的生成树)也是有意义的。
对我来说,设计师选择指定所有树都是定向的,而不指定边缘方向和树结构之间的关系,这有点令人惊讶(但并非“错误”)。也就是说,我认为简单地指定Tree扩展Graph是合理的,并让特定的实例化进一步指定树是定向还是未定向,或我会选择一个约定(指向朝向或远离根,并在javadoc中明确指定该约定。开发人员选择的解决方案强制Tree实现者指定其边缘的方向,以防止Tree用户使用该结构。例如,如果用户知道所有边都指向远离根,他们可以通过从根开始并访问从根出来的所有边来遍历图,但如果他们不知道他们必须考虑两个传入和外向的边缘。
由于Java的instanceof测试,实现没有方法的接口可能会产生后果。例如,图形绘制例程可以检查图形是否是有向图的实例,如果是,则绘制箭头而不是线。
作为最后一点,在尝试理解库中使用的术语时,我会对去维基百科或任何其他来源时要小心,因为通常不同的人会为事物选择微妙的不同含义。例如,在某些库中,“Graph”实际上意味着“定向加权图”。你最好去javadoc。
答案 1 :(得分:1)
JUNG的Forest
界面定义了getChildren
和getParent
方法。这些是人们通常期望与树木和森林相关联的方法,除非图表是针对的,否则没有意义。
此外,没有这种方法签名的林或树接口没有意义。确实,在图论中,树只是一个连通的非循环图。但是,没有任何方法(至少是通用的)适用于具有无向边的树,这些方法通常不适用于图形。也就是说,您当然可以创建一个Graph的实现,它将自己限制为具有无向边的树 - 您可以自由地这样做。