Я предполагаю, что выполняются следующие условия:
- Граф ациклический. Вы упомянули об этом в своем комментарии, но я хотел бы четко указать, что это исходное предположение.
- Существует известный набор корневых узлов. Нам нужно иметь некоторый способ узнать, какие узлы всегда считаются доступными, и я предполагаю, что (каким-то образом) эта информация известна.
- Начальный график не содержит лишних узлов. То есть, если начальный граф содержит любые узлы, которые необходимо удалить, они уже были удалены. Это позволяет алгоритму работать, поддерживая инвариант, что каждый узел должен быть там.
Если это так, то дается начальная установка, единственная причина, что узел в графе будет либо
- узел находится в корневом достижимости узлов, или
- У узла есть родитель, который находится в корневом наборе узлов.
Следовательно, каждый раз, когда вы удаляете узел из графика, единственными узлами, которые могут быть удалены, являются потомки этого узла. Если удаляемый узел находится в корневом наборе, вам может потребоваться сократить количество графиков, и если удаляемый узел будет потомком с несколькими из его собственных потомков, вам может потребоваться сделать очень мало.
Учитывая эту настройку, после удаления узла вам нужно будет сканировать все дочерние узлы этого узла, чтобы увидеть, нет ли у кого-либо из них других родителей, которые сохранили бы их на графике. Поскольку мы предполагаем, что единственными узлами в графе являются узлы, которые должны быть там, если у дочернего элемента удаленного узла есть хотя бы один другой родитель, то он все равно должен быть на графике. В противном случае этот узел необходимо удалить.Один из способов сделать шаг удаления, таким образом, был бы следующий рекурсивный алгоритм:
- Для каждого из детей узла удаляемых:
- Если этот узел имеет только один из родителей: (он должен быть узел, который мы собираемся удалить)
- Рекурсивно удалить этот узел с графика.
- Удалить указанный узел из графа.
Это, вероятно, не очень хороший алгоритм для реализации непосредственно, однако, поскольку вовлеченная рекурсия может стать довольно глубокой, если у вас большой граф. Таким образом, вы можете реализовать его с помощью алгоритма рабочего списка, как это:
- Создать рабочий список W.
- Добавить V, узел удалять, W.
- Хотя W не пусто:
- Удалить первую запись из W; назовите его w.
- Для каждого из детей в W:
- Если ребенок имеет только один из родителей, добавьте его в W.
- Удалить ж из графика.
Это заканчивает тем, что в худшем случае O (м) время, где М числа ребер в графе, так как в теории, каждое ребро должно быть отсканировано. Однако это может быть намного быстрее, если предположить, что ваш график имеет некоторые избытки в нем.
Надеюсь, это поможет!
Является ли ваш график всегда ациклическим или может содержать циклы? – templatetypedef
Он не содержит циклов. Каждый узел в основном представляет собой список ежедневных наблюдений, которые связаны с наблюдениями за последующими днями. Иногда я нахожу ошибочные наблюдения, поэтому, когда я их удаляю, я хочу, чтобы другие узлы, которые были извлечены из этого удаленного узла, также были удалены. – Lostsoul