Преобразование неориентированного графа в дерево

предоставлена неориентированный граф в котором каждый узел имеет декартову координату в пространстве, которая имеет общую форму дерева, есть ли алгоритм преобразования графика в дерево и найти соответствующий корневой узел?

обратите внимание, что наше определение "дерева" требует, чтобы ветви не расходились от родительских узлов под острыми углами.

см. примеры графиков ниже. Как мы найдем Красный Узел?

Example input graphExample output tree

2 ответов


здесь предложение о том, как решить вашу проблему.

предпосылки

  • Примечание:
    • g графика g.v вершин графа
    • v,w,z: отдельные вершины
    • e: индивидуальные краю
    • n: количество вершин
  • любая комбинация неориентированного дерева g и заданного узла g.V однозначно определяет направленное дерево с корнем g.v (доказуемо индукцией)

идея

  • дополнить края g по ориентациям в направленном дереве, подразумеваемым g и еще не найденный корневой узел локальными вычислениями в узлах g.
  • эти ориентации будут представлять дочерние-родительские-relationsships между узлами (v -> w: v ребенка, w parent).
  • полностью отмеченное дерево будет содержать единственный узел с outdegree 0, который является желаемый корневой узел. вы можете получить 0 или более одного корневого узла.

алгоритм

предполагает стандартное представление структуры графика / дерева (например, список смежности)

  1. все вершины в g.v изначально помечены как не посещенные, не законченные.
  2. посетить все вершины в произвольном порядке. пропустить узлы, помеченные как "готово".
    пусть v быть посещаемой вершиной.

    • 2.1 развертки через все края, связывающие v по часовой стрелке, начиная со случайно выбранного e_0 в порядке угла ребер с e_0.
    • 2.2. ориентация смежных ребер e_1=(v,w_1), e_2(v,w_2), которые охватывают острый угол.
      смежный: wrt упорядочивается в соответствии с углом, который они заключают в e_0.

      [ Примечание: существование такой пары не гарантируется, см. 2-й комментарий и последнее замечание. если нет острого угла, перейти на 2. со следующим узлом. ]

      • 2.2.1 положения края e_1, e_2 известны:

        • w_1 -> v -> w_2: невозможно, так как дедушка-ребенок-сегмент будет заключать острый угол
        • w_1 <- v <- w_2: невозможно, по той же причине
        • w_1 <- v -> w_2: невозможно, нет узлов с outdegree >1 в дереве

        • w_1 -> v <- w_2:
          возможна только пара ориентаций. e_1, e_2 может были ориентированы раньше. если предыдущая ориентация нарушает текущее назначение, экземпляр проблемы не имеет решения.

      • 2.2.2 это назначение подразумевает древовидную структуру на подграфах, индуцированных всеми вершинами, достижимыми из w_1 (w_2) на пути, не включающем e_1 (e_2`). отметьте все вершины в обоих индуцированных поддеревьях как законченные

        [ Примечание: структура поддерева может нарушать ограничения угла. в в этом случае проблема не имеет решения. ]

    • 2.3 метки v посетил. после завершения шагов 2.2 в vertex v проверьте количество nc соединяющихся ребер, которым еще не назначена ориентация.

      • nc = 0: это корень, который вы искали , но вы должны проверить, совместимо ли решение с вашими ограничениями.
      • nc = 1: пусть этот край будет (v,z).
        ориентация этого ребра v - >z, как вы находитесь в дереве. Марк v как законченный.

        • 2.3.1 проверить z помечено ли оно готово. если это не так, проверьте номер nc2 из неориентированных ребер, соединяющих z. nc2 = 1: повторите шаг 2.3, взяв z на v.
  3. если вы еще не нашли корневой узел, экземпляр проблемы неоднозначен: ориентируйте оставшиеся неориентированные края по желанию.

Примечания

  1. прекращение: каждый узел посещается максимум 4 раза:

    • один раз на Шаг 2
    • на максимальном дважды в шаг 2.2.2
    • на максимальном раз в шаг 2.3
  2. правильность:

    • все края заключая острый угол ориентированы в шаг 2.2.1
  3. сложность (время):

    • посещение каждого узла: O (n);
    • развертка по часовой стрелке через все ребра, соединяющие данную вершину, требует сортировки этих ребер.
      таким образом, вам нужно O( sum_i=1..m ( k_i * lg k_i ) ) at m <= n вершины под ограничением sum_i=1..m k_i = n.

      в общей сложности это требует O ( n * lg n), as sum_i=1..m ( k_i * lg k_i ) <= n * lg n дано sum_i=1..m k_i = n любой m <= n (доказуемо путем применения оптимизации Лагранжа).

      [ Примечание: Если ваши деревья имеют степень, ограниченную константой, вы теоретически сортируете в постоянное время на каждом затронутом узле; общая сумма в этом случае:O(n) ]

    • поддерево обозначение:
      каждый узел на графике посещается не более 2 раз этой процедурой, если она реализована как dfs. таким образом, в общей сложности O(n) для вызова этой подпрограммы.

      в итоге: O(n * lg n)

  4. сложности (пространство):

    • O(n) для сортировки (с вершинной степенью, не связанной с константой).
  5. проблема, вероятно, плохо определена:

    • несколько решений: например, steiner tree
    • нет решения: например, график в форме стрелки с двойным наконечником ( )

простым решением было бы определить 2d-прямоугольник вокруг красного узла или центра вашего узла и вычислить каждый узел с кривой Мура. Кривая Мура-это кривая заполнения пространства, больше по специальной версии кривой Гильберта, где начальная и конечная вершины одинаковы, а координата находится в середине 2d-прямоугольника. В generell ваша проблема выглядит как дискретная проблема пространства адресации.