Algorithm 分层数据的最佳图形绘制算法?

Algorithm 分层数据的最佳图形绘制算法?,algorithm,language-agnostic,graph,graph-drawing,Algorithm,Language Agnostic,Graph,Graph Drawing,我有一个接近树的有向无环图的集合,在以下意义上:每个图都有一个根,并且顶点被组织成层次,如果v1和v2是顶点,那么如果v1的层次小于v2的层次,那么在图中从v2到v1没有边,尽管从v1到顶点可能有许多边处于相同或更高级别。例如,表达式树、函数调用图或线性类层次结构就是此类图的示例。以下是此类图表的一个示例: A1 / \ A1 -> A4, A3 / \

我有一个接近树的有向无环图的集合,在以下意义上:每个图都有一个根,并且顶点被组织成层次,如果v1和v2是顶点,那么如果v1的层次小于v2的层次,那么在图中从v2到v1没有边,尽管从v1到顶点可能有许多边处于相同或更高级别。例如,表达式树、函数调用图或线性类层次结构就是此类图的示例。以下是此类图表的一个示例:

              A1            
             /  \           A1 -> A4, A3
            /    \          A3 -> A2, A6, A7
          A4  A2--A3        A2 -> A6
              | \ / \
              A6 \_ A7

有过多的图形绘制算法,我无法确定哪种算法最适合这种情况。一些初步研究表明,绘制Hasse图的算法可能是合适的,但这些算法的输出似乎并不适合我试图建模的数据结构类型。还有几种算法用于对分层数据进行建模,但我不确定哪种算法能够平衡实现的简单性和效率。前一种方法的一个问题是,这些图有根,也有方向。如果可能,该算法将支持循环图,并最小化数值计算的数量,但这不是必需的。出于这些原因,我更愿意避免使用力导向算法,如果可能的话,还可以使用点这样的GraphViz算法。

如果它是一棵树,那么我以前就已经很好地看到了这项工作

顺便说一句,我觉得允许节点A2“升级”到与其祖先相同的级别的决定并没有真正起到多大作用

取而代之的是,我将允许一个节点进一步向下移动,而不是向上移动。 我认为这个例子可以画得更好,如下所示

          A1            
         /  \           A1 -> A4, A3
        /    \          A3 -> A2, A6, A7
      A4     A3         A2 -> A6
            / | \
          A2  |  A7
            \ |
             A6
这样,您甚至不需要标记边方向。
[我是否误解了您原来的图表?我认为A2和A7之间没有优势,对吗?]

这不是一个真正的答案,但太长了,无法发表评论

你的图与一般的有向无环图有何不同

DAG不必有根,但我认为这对绘制图形没有什么影响

就级别而言,对于任何DAG,可以定义一个功能级别(v),以便对于任何边缘vi→vj,一级≤ (j)级。平凡水平函数是顶点拓扑顺序中的顶点索引。另一个是从根到顶点的最长路径的长度

Reingold-Tilford树绘制算法绘制有序树(即顶点边有序的树)。你的例子表明你的图不是有序的,事实上,你面临的主要问题是找到一个边序,它最小化了边交叉。所以这可能就是你想要解决的问题。(这不是一个容易的问题。)


根据我的经验,
dot
实际上在DAG方面做得很好,尽管有时需要一些帮助。特别是,如果知道每个顶点的级别,可以使用“rank=”same“属性为每个级别创建一个子图。(请参阅。)

问题在于这些图位于树和完全非循环图之间。如果是前者,我可以使用你建议的算法;如果是后者,我可以使用Sukiyama算法的线性时间优化,或者类似的方法。你是对的,允许一个节点“上升”到与它的故事相同的级别可能没有帮助;对于我正在使用的数据结构,这将导致按照您的建议进行转换,但会限制可以绘制的图形类别;我没有意识到还有另外一个答案。我认为你是对的:除了使用交叉边算法外,使用树绘制算法将是最好的选择。这似乎是最好的答案,因为它通过建议将树绘制算法与最小化边缘交叉的算法相结合来解决问题。