问题 有效绘制树木的算法?


我需要在C#中绘制一个公司结构树(类似于家谱)。所有辅助代码都在那里。它是有色的,互动的和花哨的。唯一的麻烦是算法实际决定放置每个节点的位置给了我很多悲伤。

目前,盒子的大小是100x50,我有一个叫做的课程 StaffNode 代表特定x,y坐标的工作人员。

该算法只需要创建一个 List<StaffNode> 使用适当的x和y。

这非常棘手。

基本上,算法是沿公司结构递归的,所以左 - >右,然后沿着树向上 - >向下。显然,如果两个节点在彼此之上是很糟糕的。

我可以想到一些算法可能产生这样的东西:

          *
    o         O
o o o o o     O
o         O O O O O
                O

虽然这样的东西会更好,但树很大,空间非常有限:

       *
    o     O
o o o o o O
o     O O O O O
            O

你们中的任何人以前都要画这样的树吗?如果你有,我相信你已经遇到过我所遇到的许多障碍。有小费吗?到目前为止,我已经花了一整天的时间。


1385
2017-11-27 22:11


起源

你想做什么?不应该在微软visio或其他什么? - DrStrangeLove
拿一些俄罗斯方块解算器...... - Dialecticus
@DrStrangeLove不,我正在编写一个交互式可视化。 - user1002358


答案:


有很多很好的绘制树的算法,每个算法都展示了一些不同的树木属性。如果你想展示层次结构,那就有了 此代码用于绘制层次结构的WPF。有关如何绘制图形和树木的更一般性讨论,请考虑一下 这些讲座幻灯片 详细介绍了许多此类算法。还有 这些优秀的幻灯片 覆盖类似的材料。

希望这可以帮助!


13
2017-11-27 22:19



那绝对是完美的!正是我需要的。它使用Reingold-Tilford算法。 - user1002358
@ user1002358感谢您的评论。我从这里列出的答案中理解算法时遇到了麻烦,但谷歌搜索“Reingold-Tilford算法”引导我 这个问题,我觉得更有用。我还总结了编码算法的步骤 这里 万一其他人正在寻找一个简单的解释 - Rachel


您可以使用迭代方法。使用上面使用的第一个示例来布置树。然后移动节点或子树彼此更接近,同时确保没有违反约束(例如:节点不能重叠,子节点必须低于父节点)。

优点:

  • 简单的算法。
  • 获得一个足够好的解决方案。
  • 可以连续应用于变化的树。
  • 可以看起来很酷。

缺点:

  • 可能需要多次迭代才能看起来很好。
  • 可能找不到最佳解决方案(陷入局部最大值)

1
2017-11-27 22:20



你可以在一次迭代中做这样的事情。 - Michael Nett
同意,但是如果单通道算法对于大量节点在计算上是不可行的,则有时迭代优化方法可能是有用的。 - geofftnz