Перехідне зниження DAG


13

Я шукаю алгоритм O (V + E) для пошуку перехідного скорочення, заданого DAG.

Це видалити якомога більше ребер, так що якщо ви могли досягти v з u, для довільних v і u, ви все одно можете дістатися після видалення ребер.

Якщо це стандартна проблема, будь ласка, вкажіть мене на якесь модельне рішення.


Ви не можете скористатись посиланням, наведеним у викладеній вами лемімі у вікіпедії?
Гендрик Ян

2
Ну, алгоритм, обговорюваний у Вікіпедії, працює в (у кращому випадку, тобто у випадку ациклічних графіків) замість як вимагається. Я думаю, що правильна відповідь тут полягає в тому, що алгоритм, який ви зараз шукаєте, може не існуватиO ( V + E )O(V×E)O(V+E)
Карлос Лінарес Лопес

1
Погодився, що не ясно, що те, що ти просиш, існує. Існує досить багато робіт, які були б нецікавими, якби був такий алгоритм, наприклад, sciencedirect.com/science/article/pii/0012365X9390164O . Це означає, що якщо ви можете бути більш конкретними щодо вашої мотивації, можуть бути більш конкретні рішення. Наприклад, чи знаєте ви що-небудь ще про графік чи працював би ? O(n(n+m))
Вільям Макра

Я десь бачив проблему, але додаткової інформації не було, можливо, помилка друку в проблемі.
Каран

1
Що робити, якщо ви робите топологічне сортування у вашій DAG, але відслідковуйте доступні вершини за допомогою дітей, тобто , а потім починайте з останнього елемента в відсортованому графіку, і видаліть невикористані краї та підніміться, зберігаючи доступну функцію, це дає вам максимально можливі ребра для видалення, але я не впевнений, чи отримає це максимальна можливість (це .O ( | E | + | V | )reachable[v]=vchildrenvreachable[v]O(|E|+|V|)

Відповіді:


8

Ми можемо вирішити цю проблему, просто виконавши DFS з кожної вершини.

  1. Для кожної вершини почніть DFS з кожної вершини таким чином, що є прямим нащадком , тобто. - край.v v u ( u , v )uGvvu(u,v)
  2. Для кожної вершини доступної DFS від , видаліть край . v ( u , v )vv(u,v)

Загальна складність вищезазначеного - це складність запуску DFS ', що є .O ( N ( N + M ) )NO(N(N+M))


1
Зауважимо, що, асимптотично, це має таку ж складність, як алгоритм у статті Вікіпедії, пов'язаний у самому питанні. O(NM)
Девід Річербі

1
Домовились. Оскільки на це питання мала бути стисла відповідь, я представив її. Крім того, рішення є IMO, навряд чи. O(N)
пратякш

3

Не те, що ви шукаєте. Але тільки для обміну знаннями мети, ви можете зробити це з повідомлень , якщо припустити , що кожна вершина , щоб виступати в якості процесора . Зауважте, кожна вершина має порівнянне значення. Тому існують деякі вершини такі, що вони більші за всіх їхніх сусідів. Ці вершини роблять наступне:O(|E|)

  1. Нехай - максимально менший сусід v ,uv
  2. надіслати повідомлення та включити край ( v , u ) у вихід.u(v,u)
  3. Для кожного сусіда з u та v (і менше, ніж обидва) не включайте ( v , w ) у вихід.wuv(v,w)
  4. Повторюйте кроки, поки весь край для меншого сусіда v вершини v не буде включений або не включений у висновок.(v,v)vv

Тепер, якщо вузол отримав повідомлення від кожного більшого сусіда (тобто всі ребра ( v ' , v ) або включені, або не включені, тоді вузол v діє так, ніби він був найбільшим у своєму районі. Тобто він виконує раніше згадані 4 етапи.v(v,v)v

Цей алгоритм закінчується в повідомленнях у розподіленому середовищі. Я знаю, що це не те, що ви просите.O(|E|)


1

Лема: Якщо є край V -> Y, а Y також є непрямим наступником V (наприклад, V -> W -> + Y), то край V -> Y є перехідним і не є частиною перехідного кореня.

Метод: слідкуйте за перехідним закриттям кожної вершини, працюючи від кінцевих до початкових вершин у зворотному топологічному порядку. Сукупність непрямих наступників V - це об’єднання перехідних замкнень безпосередніх наступників В. Перехідне закриття V - це об'єднання її непрямих наступників та його безпосередніх наступників.

Алгоритм:

    Initialise Visited as the empty set.
    For each vertex V of G, 
        Invoke Visit(V).

    Visit(V):
        If V is not in Visited,
            Add V to Visited, 
            Initialise Indirect as the empty set,
            For each edge V -> W in G,
                Invoke Visit(W),
                Add Closure(W) to Indirect.
            Set Closure(V) to Indirect.
            For each edge V -> W in G,
                Add W to Closure(V),
                If W is in the set Indirect,
                    Delete the edge V -> W from G.

Це передбачає, що у вас є ефективний спосіб відстеження наборів вершин (наприклад, бітових карт), але я думаю, що це припущення зроблено і в інших алгоритмах O (V + E).

Потенційно корисним побічним ефектом є те, що він знаходить перехідне закриття кожної вершини G.


Я видалив відповідь, розміщену у вашому попередньому обліковому записі. Якщо ви все-таки хочете об'єднати два облікові записи, виконайте дії в довідковому центрі . Це було сказано, оскільки попередній обліковий запис більше не має видимого вмісту, ви можете просто дотримуватися нового.
Жил 'ТАК - перестань бути злим'

0

Я вирішив ту саму проблему, але вона була не зовсім однаковою. Попросили отримати мінімальну кількість ребер у графіку після зменшення, щоб вершини, спочатку підключені, все ще були підключені і нові з'єднання не здійснювалися. Як зрозуміло, він не каже знайти зменшений графік, але скільки зайвих ребер є. Цю задачу можна вирішити в O (V + E). Посилання на пояснення https://codeforces.com/blog/entry/56326 . Але я думаю, щоб зробити графік насправді, він матиме більшу складність, ніж O (N)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.