<?xml version="1.0" encoding="UTF-8"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" >

  <channel>
    <title><![CDATA[Комментарии к публикации «Выделение бесхордовых циклов из ненаправленного графа»]]></title>
    <link>https://habr.com/ru/articles/528002/</link>
    <description><![CDATA[Комментарии к публикации «Выделение бесхордовых циклов из ненаправленного графа»]]></description>
    <language>ru</language>
    <managingEditor>editor@habr.com</managingEditor>
    <generator>habr.com</generator>
    <pubDate>Thu, 20 Aug 2026 09:41:31 GMT</pubDate>
    
    
      <image>
        <link>https://habr.com/ru/</link>
        <url>https://habrastorage.org/webt/ym/el/wk/ymelwk3zy1gawz4nkejl_-ammtc.png</url>
        <title>Хабр</title>
      </image>
    

    
      

      
        
  
    <item>
      <title>15.11.2020 18:35:40 AlexKarpan</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/528002/#comment_22308416</guid>
      <link>https://habr.com/ru/articles/528002/#comment_22308416</link>
      <description><![CDATA[А ведь действительно. Вы правы :(]]></description>
      <pubDate>Sun, 15 Nov 2020 18:35:40 GMT</pubDate>
      <dc:creator><![CDATA[AlexKarpan]]></dc:creator>
    </item>
  

  
    <item>
      <title>15.11.2020 14:36:39 wataru</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/528002/#comment_22307686</guid>
      <link>https://habr.com/ru/articles/528002/#comment_22307686</link>
      <description><![CDATA[<p>Вряд ли это применимо к вашему графу. Тут используется, что граф нарисован на плоскости — у всех ребер есть направления и можно в каждой вершине повернуть &quot;направо&quot; при обходе.</p>]]></description>
      <pubDate>Sun, 15 Nov 2020 14:36:39 GMT</pubDate>
      <dc:creator><![CDATA[wataru]]></dc:creator>
    </item>
  

  
    <item>
      <title>15.11.2020 14:10:16 AlexKarpan</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/528002/#comment_22307616</guid>
      <link>https://habr.com/ru/articles/528002/#comment_22307616</link>
      <description><![CDATA[Передо мной стояла похожая задача с направленным графом: я писал декомпилятор — восстанавливал код высокоуровневого языка из ассемблерных инструкций. Посмотрю, как ваши идеи можно применить в моей случае. Спасибо!]]></description>
      <pubDate>Sun, 15 Nov 2020 14:10:16 GMT</pubDate>
      <dc:creator><![CDATA[AlexKarpan]]></dc:creator>
    </item>
  

  
    <item>
      <title>15.11.2020 12:55:12 Sergey_Kovalenko</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/528002/#comment_22307396</guid>
      <link>https://habr.com/ru/articles/528002/#comment_22307396</link>
      <description><![CDATA[Проснулся и понял, что к лемме 3 есть контрпример. Похоже, в таком виде алгоритм найдет не все бесхордовые циклы.]]></description>
      <pubDate>Sun, 15 Nov 2020 12:55:12 GMT</pubDate>
      <dc:creator><![CDATA[Sergey_Kovalenko]]></dc:creator>
    </item>
  

  
    <item>
      <title>14.11.2020 18:31:34 Massaraksh147</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/528002/#comment_22305372</guid>
      <link>https://habr.com/ru/articles/528002/#comment_22305372</link>
      <description><![CDATA[Спасибо. Нашёл, добавил в закладки.]]></description>
      <pubDate>Sat, 14 Nov 2020 18:31:34 GMT</pubDate>
      <dc:creator><![CDATA[Massaraksh147]]></dc:creator>
    </item>
  

  
    <item>
      <title>14.11.2020 18:05:52 Sergey_Kovalenko</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/528002/#comment_22305250</guid>
      <link>https://habr.com/ru/articles/528002/#comment_22305250</link>
      <description><![CDATA[Свое знакомство с графовыми алгоритмами я начал с книг Ахо, Ульмана и Хопфорта «Алгоритмы. Построение и анализ» и с довольно устаревшей, но хорошо написанной монографии Кристофидеса «Теория графов. Алгоритмический подход». Возможно, они окажутся полезными и Вам тоже.]]></description>
      <pubDate>Sat, 14 Nov 2020 18:05:52 GMT</pubDate>
      <dc:creator><![CDATA[Sergey_Kovalenko]]></dc:creator>
    </item>
  

  
    <item>
      <title>14.11.2020 17:33:37 Massaraksh147</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/528002/#comment_22305158</guid>
      <link>https://habr.com/ru/articles/528002/#comment_22305158</link>
      <description><![CDATA[Люблю конструктивные предложения. Обязательно попробую.]]></description>
      <pubDate>Sat, 14 Nov 2020 17:33:37 GMT</pubDate>
      <dc:creator><![CDATA[Massaraksh147]]></dc:creator>
    </item>
  

  
    <item>
      <title>14.11.2020 17:32:19 Massaraksh147</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/528002/#comment_22305148</guid>
      <link>https://habr.com/ru/articles/528002/#comment_22305148</link>
      <description><![CDATA[Спасибо, это интересно. Будет время, обязательно попробую и напишу.]]></description>
      <pubDate>Sat, 14 Nov 2020 17:32:19 GMT</pubDate>
      <dc:creator><![CDATA[Massaraksh147]]></dc:creator>
    </item>
  

  
    <item>
      <title>14.11.2020 12:48:19 Sergey_Kovalenko</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/528002/#comment_22304212</guid>
      <link>https://habr.com/ru/articles/528002/#comment_22304212</link>
      <description><![CDATA[Всегда очень приятно видеть статью, где автор описывает свой творческий опыт. Пока читал Вашу, на ум пришел тоже какой-никакой алгоритм. Не уверен, что он работает быстрее, но все же:<br>
<br>
Предположим граф связен (иначе разбить на компоненты связности и применить алгоритм к каждой из них)<br>
1)Игнорировать ориентацию в графе и построить в нем любое остовное дерево T.<br>
Лемма 1: для любых двух вершин N_1, N_2 в дереве существует и притом единственный соединяющий их путь prim(N_1, N_2) без повторений ребер и вершин<br>
<br>
Лемма 2: если пара вершин N_1, N_2 соединена каким-то ребром E, не входящим в остовное дерево, то присоединив его к prim(N_1, N_2), вы получите базисный относительно T цикл. Это цикл является простым, то есть, он проходит через все свои ребра и вершины ровно по одному разу.<br>
<br>
Поскольку циклы — это ориентированные пути, то их можно складывать и вычитать друг из друга. Обратный для C цикл получается, если пройти его в обратном направлении. Сумма циклов C_1 С_2 с общей вершиной B определяется так: стартуя из B, вам нужно сначала пройти по C_1, а после возвращения в B — потом еще и по С_2. Если у циклов несколько общих вершин, можно начать обход из любой — на результат суммы это никак не повлияет. Разность определяется как сумма с обратным циклом.<br>
<br>
Каждый цикл индуцирует циклический порядок на экземплярах тех ребер, через которые он проходит. Назовем цикл невозвратным, если в этом порядке два экземпляра одного ребра не стоят рядом. Вычеркивая рядом стоящие экземпляры, любой цикл можно привести к невозвратному, результат не зависит от порядка вычеркивания. Два цикла, которые приводятся к одному и тому же невозвратному будем считать эквивалентными<br>
<br>
Лемма 3. Пусть простой цикл C образован ребрами остовного дерева T и еще k ребрами, которые не принадлежат T. Тогда C с точностью до эквивалентности можно представить в виде суммы некоторого базисного относительно T цикла и простого цикла С', у которого только (k-1) его ребро не входит в T <br>
<br>
2) Итеративно найдем все простые циклы. Простые циклы первого G_0 поколения — это в точности все базисные циклы относительно T. Пусть у нас уже есть поколение G_(n-1). Если G_(n-1) пусто, то поиск простых циклов завершен и переходим к следующему пункту. Иначе составим всевозможные суммы (и разности) между циклами поколения G_(n-1) и циклами, которые являются базисными относительно T. Приведем результаты к безвозвратному виду. Те из сумм, которые окажутся простыми, даст нам следующие поколение G_n.<br>
<br>
3) Каждый бесхордовый цикл, является в том числе и простым. Все простые циклы мы нашли. Остается вернуть графу его направленность и отобрать те простые циклы ненаправленного графа, которые к тому же являются циклами и в его направленном варианте.]]></description>
      <pubDate>Sat, 14 Nov 2020 12:48:19 GMT</pubDate>
      <dc:creator><![CDATA[Sergey_Kovalenko]]></dc:creator>
    </item>
  

  
    <item>
      <title>14.11.2020 11:35:20 wataru</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/528002/#comment_22304006</guid>
      <link>https://habr.com/ru/articles/528002/#comment_22304006</link>
      <description><![CDATA[<p>Судя по алгоритму, у вас не просто граф, а планарный граф на плоскости. И задача у вас, похоже, не найти бесхордовые циклы, а выделить на плоскости простые замкнутые контуры, у которых нет &quot;возможности срезать угол&quot; строго внутри области.</p><br>
<p>Например, вот такой граф:</p><br>
<div class="spoiler" role="button" tabindex="0">
                        <b class="spoiler_title">картинка</b>
                        <div class="spoiler_text"><img src="https://habrastorage.org/webt/ja/im/k5/jaimk5ckyhohjs5il102ciy3kfg.png"></div>
                    </div><br>
<p>Бесхордовых циклов тут три (идем вправо по одному из трех путей и возвращаемся обратно по любому из остальных, 6 вариантов делим на два, ибо обошли каждый цикл в двух направлениях). Если требовать, чтобы не было более короткого пути между двумя вершинами в цикле, то цикл только один — внешние ребра. Если же требовать, чтобы вообще лишних путей между вершинами не было, то циклов вообще нет. Но мне кажется, что вы хотите видеть тут 2 цикла — вокруг нижней и верхней замкнутой области, так?</p><br>
<p>Эта задача очень похожа на известную задачу <a href="https://e-maxx.ru/algo/facets">выделения граней у планарного графа</a>. С тем лишь дополнением, что надо удалить &quot;петли&quot; если цикл проходит по каким-то вершинам несколько раз. Ну, и компоненты связности внутри граней разрешены и игнорируются. В приведенном алгоритме они ничего не ломают — просто он в случае их наличия выдает не совсем грани графа, а просто замкнутые циклы, как вам и надо.</p><br>
<p>Ваше решение, судя по всему, в n раз медленнее, чем описанное по ссылке: вы начинаете обход с каждого ребра пока не вернетесь в вершину и таким образом получаете каждый цикл много раз со всеми сдвигами. Следует, во-первых, работать с направленными ребрами (каждое ребро вашего графа — это 2 направленных ребра в разные стороны). Во-вторых, надо помечать обойденные ребра и начинать обход с любого не помеченного направленного ребра.</p><br>
<p>Единственное усложнение тут, что вы можете получить цикл с касаниями с каким-то произвольным сдвигом. Тогда просто удалять вершины между двумя повторениями одной вершины нельзя — вы можете удалить внешность цикла, оставив только внутренность. Но это лечится нахождением самой нижней-левой вершины в цикле. Если начинать обход цикла с нее, то уже можно спокойно удалять все вершины между двумя повторениями одной и той же вершины. Главное, чтобы эта самая нижняя-левая вершина оставалась в ответе.</p>]]></description>
      <pubDate>Sat, 14 Nov 2020 11:35:20 GMT</pubDate>
      <dc:creator><![CDATA[wataru]]></dc:creator>
    </item>
  


      

      

    
  </channel>
</rss>
