Блог пользователя Guliash

Автор Guliash, 11 лет назад, По-русски

Расскажите, пожалуйста, или дайте ссылку, где можно почитать про O(E) алгоритм поиска узкого остовного дерева.

Узкое остовное дерево неориентированного графа G есть остовное дерево G, в котором наибольший вес ребра минимален среди всех возможных остовных деревьев.

Теги mst, bst
  • Проголосовать: нравится
  • +10
  • Проголосовать: не нравится

»
11 лет назад, # |
Rev. 6   Проголосовать: нравится 0 Проголосовать: не нравится

Этот коммент можно не читать

  • »
    »
    11 лет назад, # ^ |
      Проголосовать: нравится +3 Проголосовать: не нравится

    Возможно, тем, что он работает не за O(E)? :)

»
11 лет назад, # |
Rev. 3   Проголосовать: нравится +5 Проголосовать: не нравится

мне кажется алгоритм должен выглядеть как алгоритм поиска к-той порядковой статисткики по ходу дела нужно поддерживать DSU (возможно с "откатами", т.е. уметь отменять добавление рёбер до некоторого старого значения). т.е. примерно такая рекурсия. разбиваем рёбра на две половины так, что в первой половине рёбра имеют меньшие веса, чем во второй. добавляем рёбра с меньшими весами в DSU, если у нас осталось одно множество, то надо взять поменьше рёбер. если несколько множеств, то побольше. Неуверен, но кажется можно такое реализовать за O(E)

  • »
    »
    11 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    Блин :D

    • »
      »
      »
      11 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      вроде можно, да?

      • »
        »
        »
        »
        11 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Да, можно. DSU с откатами нужен. то есть запоминаем какие значения в массиве мы меняли на какие, и потом в обратном порядке выполняем замены.

        • »
          »
          »
          »
          »
          11 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          Если делать DSU с откатами, то нельзя применять эвристику сжатия путей. Или я не прав?

          • »
            »
            »
            »
            »
            »
            11 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится

            Я слабо в теме разбираюсь, а почему нельзя изменения эти тоже в стек записывать, а потом откатить?

          • »
            »
            »
            »
            »
            »
            11 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится

            почему нельзя?

          • »
            »
            »
            »
            »
            »
            11 лет назад, # ^ |
            Rev. 2   Проголосовать: нравится +5 Проголосовать: не нравится
            • »
              »
              »
              »
              »
              »
              »
              11 лет назад, # ^ |
                Проголосовать: нравится +16 Проголосовать: не нравится

              Меня тут умные люди поправили, что от эвристики сжатия путей не будет никакого толка, так как доказательство её эффективности основывается на факте, что ранг родителя только растёт. При откате это условие перестаёт выполняться. Вы можете проверить на больших тестах, даёт ли прибавку в скорости эта эвристика.

              • »
                »
                »
                »
                »
                »
                »
                »
                11 лет назад, # ^ |
                  Проголосовать: нравится +41 Проголосовать: не нравится

                Привет) Меня тут попросили уточнить, уточняю:

                На случайных тестах сжатие путей дает выигрыш. На не случайных не дает. Не случайный тест:

                1. Построили join-ами полное бинарное дерево. При этом соединяли мы всегда корни, поэтому сжатие путей ничего не сжало.

                2. Породили новую версию.

                3. Сделали в новой версии запрос от листа за время Theta(logn).

                4. goto 2

                • »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  11 лет назад, # ^ |
                  Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

                  Спасибо за уточнения. Наш случай отличается от общего тем, что мы не откатываем изменения после одного запроса за O(log(N)), мы выполняем серию запросов. Допустим на самом первом шаге рекурсии мы построили полное бинарное дерево из N/2 вершин. в следующем шаге рекурсии у нас есть E/2 запросов, и их суммарная стоимость не сможет быть N logN из-за сжатия путей на этом шаге. Тем не менее имхо асимптотика ухудшилась и стала нелинейной(не могу оценить достоверно).

                  А что если безоткатно сжимать пути перед вызовом рекурсии? т.е. для множества вершин из рёбер [L, R) вызвать Get и забыть про эти изменения.

                • »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  11 лет назад, # ^ |
                    Проголосовать: нравится 0 Проголосовать: не нравится

                  Посмотрел исходную задачу. Решается она так. Найдем вес max ребра:

                  1. Ищем ребро-медиану за O(E)

                  2. Проверяем за O(V+E) меньше ответ медианы или больше. Для этого за O(V+E) сжимаем компоненты связности, образованные ребрами меньшими медианы. И за O(E) для всех больших медианы ребер проверяем, соединяют ли они разные компоненты.

                  3. Делаем за O(V+E) переход к задаче с E/2 ребрами. Если ответ меньше медианы, выкинем все ребра большие медианы. Если же ответ больше медианы, сожмем компоненты связности, получим новый граф.

                  4. Чтобы всё это решение работало за O(E) достаточно поддерживать V = O(E). Нужно после каждого уменьшения задачи выкидывать вершины степени 0 и перенумеровывать оставшиеся.

                  Как по весу max ребра восстановить дерево, думаю, понятно.

                  Сойдет? =)

                • »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  11 лет назад, # ^ |
                    Проголосовать: нравится 0 Проголосовать: не нравится

                  По поводу СНМ: когда я пытаюсь думать, как бы соптимизить сжатие путей, чтобы получилась линия, я получаю именно описанное выше. Сжимать, так сжимать!

  • »
    »
    11 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Оффтоп: раз уж зашла речь о к-той порядковой статистике, дайте пару задач на неё, чтоб сдать можно было. Спасибо.

»
11 лет назад, # |
Rev. 4   Проголосовать: нравится -8 Проголосовать: не нравится

Фигня, потому что откатывать нельзя.

Спасибо Eledven.

»
11 лет назад, # |
Rev. 3   Проголосовать: нравится +67 Проголосовать: не нравится

1) делим ребра на 2 равных множества, так что веса ребер в первом не больше весов во втором;

2) проверяем, не образуют ли остов ребра из первого множества;

3) если образуют, то рекурсивно находим ответ для данного подграфа;

4) если не образуют, то рассматриваем граф из сконденсированных несвязанных компонент и ребер из 2-го множества.

5) на последнем шаге алгоритма мы соединим ребром две оставшихся компоненты; вес этого ребра будет ответом на задачу.

статья с этим алгоритмом опубликована Камерини в 78-м году

статья в википедии: http://en.wikipedia.org/wiki/User:Yuxwiki/Camerini%27s_algorithm

  • »
    »
    11 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    Я так понимаю, что основное свойство этого алгоритма, заключается в том, что ребро вес которого равен величине узкого остовного дерева всегда передаётся в следующий рекурсивный вызов.

    Доказательство: Пусть это будет ребро e. Пусть e попало в сконденсированную компоненту. Очевидно, что существует цикл c, состоящий из ребёр вес которых меньше чем вес e. Добавим этот цикл в узкое остовное дерево T, заменим e на любое ребро из цикла c, а остальные рёбра из цикла почистим без нарушения связности. Очевидно, что тогда T не узкое остовное дерево.

»
11 лет назад, # |
  Проголосовать: нравится +8 Проголосовать: не нравится

Минимальное основное дерево является узким. Допустим, что это не так. Тогда, удалим из минимального дерева самое большое ребро. Оно разбилось на две компоненты. Между ними есть путь в узком. Посмотрим на ребро пути, которое не лежит в минимальном. Оно меньше удаленного, потому что иначе минимальное было узким. Но тогда минимальное не было минимальнм, потому что если удалить самое большое и добавить это, получится меньше.

  • »
    »
    11 лет назад, # ^ |
      Проголосовать: нравится +1 Проголосовать: не нравится

    Но мы не можем найти минимальное остовное дерево за O(E). Сортировка рёбер портит оценку.

  • »
    »
    11 лет назад, # ^ |
      Проголосовать: нравится +13 Проголосовать: не нравится

    узкое дерево не обязательно является минимальным. Кстати, его легко найти за — бинпоиском по весу максимального ребра

    • »
      »
      »
      11 лет назад, # ^ |
        Проголосовать: нравится -16 Проголосовать: не нравится

      Извиняюсь за минус, не сразу понял что Вы написали.

    • »
      »
      »
      11 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Под логарифмом значится V — число вершин? Как сделать бинпоиск с LogE понятно, а LogV не очень.

      • »
        »
        »
        »
        11 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Ну log E = O(log V), когда нет кратных ребер. Если кратные ребра есть — от них можно избавиться за ElogV опять же

        • »
          »
          »
          »
          »
          11 лет назад, # ^ |
            Проголосовать: нравится -8 Проголосовать: не нравится

          Ты прав, но указание V под логарифмом могло иметь именно такой смысл, что мы ищем в диапазоне из V весов.

  • »
    »
    11 лет назад, # ^ |
      Проголосовать: нравится +13 Проголосовать: не нравится

    Для теста из 3х вершин и ребер (x = 1, y = 2, w = 1) (x = 1, y = 2, w = 2) (x = 2, y = 3, w = 100). Можно выбрать и не мин остов. То есть это доказательство только в одну сторону. Может этим можно как то пользоваться?

    • »
      »
      »
      11 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      http://e-maxx.ru/algo/mst_prim

      Минимальный остов является остовом с минимальным весом самого тяжёлого ребра.

      Вместе с примером выходит, что MST сильнее узкого ST.