Алгоритм наименьшей фиксированной точки применяется к ситуациям, когда у вас есть конечное число наборов, члены которых происходят из конечного юниверса, и где членство в каждом наборе (возможно) зависит от членства других наборов, в частности, путем включения элементовиз конкретных других наборов.
Если зависимости образуют ориентированный ациклический граф (DAG), то проблем нет;наборы могут быть вычислены путем топологического упорядочения наборов в отношении зависимости, а затем вычисления наборов по порядку.(Из-за топологической сортировки ни один набор не зависит от предыдущего набора, поэтому к тому времени, когда набор должен быть вычислен, все его зависимости уже вычислены.)
Но если граф зависимостей имеет циклы, aТопологическая сортировка невозможна, поэтому мы используем алгоритм с наименьшей фиксированной точкой.Мы начинаем с установки всех наборов на пустые, а затем обрабатываем их все в некотором порядке.Когда мы приходим к зависимости, мы просто добавляем элементы, которые оказались в зависимости в тот момент.Если какой-либо набор был изменен во время этого цикла, мы обрабатываем все наборы снова.(Нет необходимости обрабатывать их в одном и том же порядке, но обычно это самый простой способ.) И мы продолжаем делать это снова и снова, пока не пройдем полный цикл без добавления какого-либо нового элемента в какой-либо набор.На данный момент мы достигли согласованного набора зависимостей членства («фиксированная точка»), в которой нет посторонних элементов (так что это «наименее фиксированная точка»).
Теоретически, этот алгоритм может приниматьдолгое время, но он должен завершиться, потому что каждый цикл включает в себя фиксированное количество вычислений набора и (за исключением последнего цикла) добавляет по крайней мере один элемент к некоторому набору.В худшем случае каждый набор включает в себя каждый элемент, поэтому существует только конечное число возможных циклов (самое большее количество наборов, умноженное на количество элементов).На практике для многих проблемных областей алгоритм работает намного быстрее, чем это, или произведение наборов и элементов не слишком велико (или оба).
Эти проблемы обычно могут быть решены путем вычисления транзитивного замыканияреляционного уравнения.Поскольку алгоритмы транзитивного замыкания, как правило, быстрее (как с точки зрения теоретической сложности, так и с точки зрения практического времени выполнения внутреннего цикла), они будут предпочтительным решением, если скорость имеет значение.Однако алгоритм с наименьшей фиксированной точкой легче понять, а код несколько менее загадочный.
В конкретном алгоритме определения живучести установленные отношения зависимостей перечислены на предыдущем слайде;Вы можете видеть, что каждый набор in
и out
определяется некоторыми фиксированными элементами и объединением одного или нескольких других наборов.Как показано, алгоритм сохраняет копию всех наборов в начале цикла и сравнивает каждую копию с соответствующим набором в конце цицила.Если какой-либо набор был изменен в течение цикла, алгоритм еще не завершен.
На практике чаще всего просто установить логический флаг в false в начале цикла и в true, если объединениеоперация вызывает добавление нового элемента к набору (который легко добавить к операции объединения, но его сложно описать в формальном алгоритме).Затем алгоритм завершается, если логическое значение все еще ложно в конце цикла.