Алгоритм топологической сортировки при наличии циклов

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

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

Существует ли алгоритм, который при заданном наборе зависимостей выводит минимальное количество модулей, которые необходимо скомпилировать в качестве прерывателей цикла для успешной компиляции программы?

Пример

Я пытаюсь пояснить, что я имею в виду в этом примере.

Рассмотрим проект с четырьмя модулями A, B, Cи D. Это список зависимостей между этими модулями, запись X yозначает, чтоyзависит от x:

A C
A D
B A
C B
D B

То же отношение, представленное в виде ASCII-диаграммы :

D ---> B
^    / ^
|   /  |
|  /   |
| L    |
A ---> C

В этом графе зависимостей есть два цикла: ADBи ACB. Чтобы разорвать эти циклы, можно, например, скомпилировать модули Cи Dкак прерыватели циклов.Очевидно, что это не лучший подход. Компиляции Aв качестве прерывателя цикла вполне достаточно для разрыва обоих циклов, и вам нужно скомпилировать на один модуль меньше в качестве прерывателя цикла.

12
задан fuz 15 May 2012 в 19:54
поделиться