Я работаю на непонятном языке с плохим управлением зависимостями. Чтобы помочь 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);

Это должно дать мне самый большой остров. Оттуда я могу пройти и исключить любые наборы, содержащие любые посещенные узлы, а затем запустить его снова, чтобы получить следующий по величине остров, и так далее.

Это точный алгоритм? Есть ли лучший способ решить эту проблему, которого я не вижу?

6
corsiKa 25 Авг 2011 в 20:50

2 ответа

Лучший ответ

Похоже, вы хотите создать набор связанных компонентов, обнаруженных в графе зависимостей. Оттуда вы можете перебрать коллекцию и определить самый большой компонент (или любую другую интересную метрику).

3
PaulF 25 Авг 2011 в 17:00

Было бы проще использовать библиотеку графов, потому что подобные вещи встроены. обычно они позволяют хранить произвольную информацию в узлах, ребрах, поэтому вы все равно можете использовать свои собственные классы для данных, но библиотека предоставляет поддержку и стандартные алгоритмы.

Алгоритм, который вы описываете, кажется немного неясным, что такое корневые узлы. если вы не начнете с корня, вы не найдете «весь остров» - только части ниже (дочерние) того места, где вы начали. вы можете исправить это, следя за родителями, а также за детьми. Помимо этого, это звучит нормально - он делает, как говорит ответ PaulF, насколько я могу судить, и находит подключенные компоненты.

См. также Хорошую библиотеку алгоритмов графа Java?

1
Community 23 Май 2017 в 11:50