有图形理论答案和程序员对此的答案。我假设您可以自己处理程序员部分。对于图论的答案:
- DAG 是一组模块,其中 A 需要 B,同时 B(或 B 需要的模块之一)需要 A,用模块来说:没有循环依赖。我已经看到发生了循环依赖(在 Gentoo 论坛中搜索示例),所以你甚至不能 100% 确定你有一个 DAG,但让我们假设你有。检查循环依赖并不难,所以我建议你在模块加载器的某个地方这样做。
- 在树中,永远不会发生的事情是 A 依赖于 B 和 C,而 B 和 C 都依赖于 D(菱形),但这可能发生在 DAG 中。
- 此外,一棵树只有一个根节点,但 DAG 可以有多个“根”节点(即没有任何依赖关系的模块)。例如像 GIMP 这样的程序,GIMP 程序将是模块集的根节点,但对于 GENTOO,几乎所有带有 GUI 的程序都是“根”节点,而库等是它们的依赖项。(Konqueror 和 Kmail 的 IE 都依赖于 Qtlib,但不依赖于 Konqueror,也不依赖于 Kmail)
正如其他人指出的那样,您的问题的图表理论答案是 DAG 不能转换为树,而每棵树都是 DAG。
但是,(高级程序员回答)如果您想要树用于图形表示,您只对特定模块的依赖关系感兴趣,而不是依赖于该模块的内容。让我举个例子吧:
A depends on B and C
B depends on D and E
C depends on D and F
我不能将它显示为 ASCII 艺术树,原因很简单,它不能转换成树。但是,如果要显示 A 依赖的内容,可以显示:
A
+--B
| +--D
| +--E
+--C
+--D
+--F
如您所见,您的树中有两个条目 - 在这种情况下“仅” D 但如果您在 Gentoo 树上执行“全部扩展”,我向您保证您的树将具有至少 1000 倍的节点数量有模块。(至少有 100 个包依赖于 Qt,所以 Qt 所依赖的所有东西都会在树中出现至少 100 次)。
如果你有一个“大”或“复杂”的树,最好动态地扩展树,而不是提前,否则你可能会有一个非常占用内存的过程。
上面树的缺点是,如果你点击打开 B,然后打开 D,你会看到 A 和 B 依赖于 D,但不是 C 也依赖于 D。但是,根据你的情况,这可能根本不重要- 如果您维护已加载模块的列表,则在加载 C 时,您会看到您已经加载了 D,并且它不是为 C 加载的,而是为 B 加载的并不重要。它已加载,仅此而已。如果您动态维护直接依赖于某个模块的内容,您也可以处理相反的问题(卸载)。
然而,你不能用树做的是你最后一句话中的内容:保持拓扑顺序,即如果 B 与 C 被加载到同一个容器中,你将永远无法将 C 加载到同一个容器中。或者您可能不得不忍受将所有东西都放在一个容器中(并不是我完全理解“装入同一个容器”的意思)
祝你好运!