我的工作是一种语言模糊,依赖管理不善的语言。为了帮助提供14000个文件代码库,我编写了一些解析工具(用Java编写)并生成了一个依赖图。
我编写了自己的图形和BFS类,它们工作得很好。有了它们,我有getParents()
和getChildren()
等方法。
现在我正在尝试在此图中找到“孤岛”;也就是说,我试图找到我们的代码库的哪些部分不相互依赖,希望将它们收集到孤立的模块中。
稍后,我还计划分析各个岛屿,看看它们中是否存在任何薄弱点,我们可以在这些弱点上建立模块障碍并定义该模块的界面,但这是在路上。
现在,我正在考虑这样做:
Map<DependencyEntry, Set<DependencyEntry>> allChildren = new ...;
for(DependencyEntry entry : allFiles) allChildren.put(entry,getAllChildren(entry));
Set<DependencyEntry> visited = new ...;
Set<DependencyEntry> largest = new HashSet<DependencyEntry>(); // size 0
// slightly more expensive but more readable
for(DependencyEntry entry : allChildren.keySet()) {
Set<DependencyEntry> set = allChildren.get(key);
if(set.size() > largest.size()) largest = set;
}
visited.addAll(largest);
这应该是我最大的岛屿。从那里,我可以通过并排除任何包含任何访问节点的集合,然后再次运行它以获得下一个最大的岛屿,等等。
这是一个准确的算法吗?有没有更好的方法来解决我没有看到的这个问题?
答案 0 :(得分:2)
听起来你想构建一个在依赖图中找到的connected components集合。从那里你可以迭代集合并识别最大的组件(或任何其他有趣的指标)。
答案 1 :(得分:1)
使用图库会更简单,因为这些东西都是内置的。通常它们允许您在节点,边缘中存储任意信息,因此您仍然可以使用自己的类来获取数据,但是库提供了支持和标准算法。
您描述的算法似乎有点不清楚什么是根节点。如果你不从根开始那么你将找不到“整个岛屿” - 只是你开始的下面的部分(孩子们)。你可以通过跟随父母和孩子来解决这个问题。除此之外,听起来还不错 - 正如PaulF的回答所说的那样,就我所知,并找到相关的组件。