<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=188.134.48.45&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=188.134.48.45&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/188.134.48.45"/>
		<updated>2026-05-27T03:21:23Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%AD%D0%B2%D0%BE%D0%BB%D1%8E%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0_%D1%8D%D0%B9%D0%BB%D0%B5%D1%80%D0%BE%D0%B2%D0%B0_%D1%86%D0%B8%D0%BA%D0%BB%D0%B0_%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%B5&amp;diff=25930</id>
		<title>Эволюционные алгоритмы поиска эйлерова цикла в графе</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%AD%D0%B2%D0%BE%D0%BB%D1%8E%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0_%D1%8D%D0%B9%D0%BB%D0%B5%D1%80%D0%BE%D0%B2%D0%B0_%D1%86%D0%B8%D0%BA%D0%BB%D0%B0_%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%B5&amp;diff=25930"/>
				<updated>2012-06-19T22:13:14Z</updated>
		
		<summary type="html">&lt;p&gt;188.134.48.45: /* Операция мутации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Введение ===&lt;br /&gt;
Способ нахождения эйлерова цикла, описанный в данной статье, является примером применения эволюционных алгоритмов на практике. Мы опишем вариант построения, время работы которого &amp;lt;tex&amp;gt;O(m*log(m))&amp;lt;/tex&amp;gt; (до недавнего времени лучшим считался результат &amp;lt;tex&amp;gt;O(m^2*log(m))&amp;lt;/tex&amp;gt;). При этом оптимальный (не эволюционный) алгоритм работает за &amp;lt;tex&amp;gt;O(m)&amp;lt;/tex&amp;gt;. Здесь и далее &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; — количество ребер в графе.&lt;br /&gt;
&lt;br /&gt;
Сначала опишем представление графа, затем то, как устроена фитнес функция и операция мутации, а потом адаптируем RLS и (1+1) EA стратегии для нашего случая.&lt;br /&gt;
&lt;br /&gt;
=== Постановка задачи ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition='''Эйлеров цикл в графе''' — это цикл, проходящий по всем рёбрам графа ровно по одному разу. &lt;br /&gt;
}}&lt;br /&gt;
Задача — для заданного графа найти такой цикл. Заметим, что это возможно тогда и только тогда, когда граф связный и степень каждой его вершины четна (для неориентированного графа).&lt;br /&gt;
&lt;br /&gt;
=== Обзор методов ===&lt;br /&gt;
====Перестановка ребер ====&lt;br /&gt;
Пусть для графа &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; задан набор всех его ребер &amp;lt;tex&amp;gt;(e_1, e_2, \dots e_m)&amp;lt;/tex&amp;gt;. На каждом шаге два случайно выбранных ребра меняются местами. Фитнес функция — длина максимального пути в множестве ребер. Алгорим работает за экспоненциальное от количества ребер время.&lt;br /&gt;
====Jump-оператор====&lt;br /&gt;
Jump-оператор работает следующим образом. Для набора ребер &amp;lt;tex&amp;gt;(e_1, e_2, \dots e_m)&amp;lt;/tex&amp;gt; оператор &amp;lt;tex&amp;gt;jump(i,j)&amp;lt;/tex&amp;gt; передвигает &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-й элемент на позицию &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; и циклически сдвигает ребра между позициями &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; влево (если &amp;lt;tex&amp;gt;i &amp;gt; j&amp;lt;/tex&amp;gt; то вправо) .  Таким образом, набор &amp;lt;tex&amp;gt;(e_1, e_2, \dots e_m)&amp;lt;/tex&amp;gt; превратится в &amp;lt;tex&amp;gt;(e_1, e_2, \dots e_{i-1}, e_{i+1}, \dots e_j, e_i, e_{j+1}, \dots e_m)&amp;lt;/tex&amp;gt;. Алгоритм с использованием jump-оператора работает за &amp;lt;tex&amp;gt;O(m^5)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; — количество ребер в графе.&lt;br /&gt;
====Улучшенный jump-оператор====&lt;br /&gt;
Лучших результатов можно достичь, если использовать только операции вида &amp;lt;tex&amp;gt;jump(i, 1)&amp;lt;/tex&amp;gt;. Тогда время работы алгоритма будет &amp;lt;tex&amp;gt;O(m^3)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== Алгоритм ===&lt;br /&gt;
==== Представление графа ====&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; — неориентированный связный граф, &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; — множество его вершин, &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; — множество ребер; всего вершин &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, а ребер &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; . Будем хранить ребра в виде списков смежности. Пусть &amp;lt;tex&amp;gt;L_v&amp;lt;/tex&amp;gt; — множество вершин, соединенных с &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; ребром, &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — множество всех &amp;lt;tex&amp;gt;L_v&amp;lt;/tex&amp;gt;. Для каждой вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; введем также множество &amp;lt;tex&amp;gt;M_v&amp;lt;/tex&amp;gt;, хранящее в себе неупорядоченные пары вершин из &amp;lt;tex&amp;gt;L_v&amp;lt;/tex&amp;gt;. Обозначим через &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; множество всех &amp;lt;tex&amp;gt;M_v&amp;lt;/tex&amp;gt;. Таким образом, если для всех вершин &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; вершины из &amp;lt;tex&amp;gt;L_v&amp;lt;/tex&amp;gt; разбиты на пары в &amp;lt;tex&amp;gt;M_v&amp;lt;/tex&amp;gt;, то с точностью до первого ребра на &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; задан порядок обхода: пара &amp;lt;tex&amp;gt;(u,w)&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;L_v&amp;lt;/tex&amp;gt; означает, что придя из &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; далее нужно идти в &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; (или наоборот).&lt;br /&gt;
&lt;br /&gt;
==== Фитнес функция ====&lt;br /&gt;
Фитнес функция для эволюционного алгоритма поиска эйлерова цикла в графе выглядит так: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f(M) = m - |M| + k&amp;lt;/tex&amp;gt;, где&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; — количество ребер в графе;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;|M|&amp;lt;/tex&amp;gt; — размер множества &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; — количество путей в &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Операция мутации ====&lt;br /&gt;
Операция мутации вводится для двух вершин &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;L_v&amp;lt;/tex&amp;gt;. Как их выбрать описано в [http://neerc.ifmo.ru/wiki/index.php?title=%D0%AD%D0%B2%D0%BE%D0%BB%D1%8E%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0_%D1%8D%D0%B9%D0%BB%D0%B5%D1%80%D0%BE%D0%B2%D0%B0_%D1%86%D0%B8%D0%BA%D0%BB%D0%B0_%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%B5#.D0.92.D1.8B.D0.B1.D0.BE.D1.80_.D0.B2.D0.B5.D1.80.D1.88.D0.B8.D0.BD_.D0.B4.D0.BB.D1.8F_.D0.BC.D1.83.D1.82.D0.B0.D1.86.D0.B8.D0.B8 следующем разделе]. Происходит она так:&lt;br /&gt;
* если &amp;lt;tex&amp;gt;u=w&amp;lt;/tex&amp;gt;, то ничего не делаем;&lt;br /&gt;
* если для &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и для &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; нет пары, то добавляем к &amp;lt;tex&amp;gt;M_v&amp;lt;/tex&amp;gt; пару &amp;lt;tex&amp;gt;(u,w)&amp;lt;/tex&amp;gt;;&lt;br /&gt;
* если &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; уже содержатся в &amp;lt;tex&amp;gt;M_v&amp;lt;/tex&amp;gt; как пара, то удалим ее;&lt;br /&gt;
* если &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; уже добавлена в паре с некоторой вершиной &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; не имеет пары, то удалим &amp;lt;tex&amp;gt;(u,p)&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;M_v&amp;lt;/tex&amp;gt; и добавим &amp;lt;tex&amp;gt;(u,w)&amp;lt;/tex&amp;gt;;&lt;br /&gt;
* если &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; уже добавлена в паре с некоторой вершиной &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; не имеет пары, то удалим &amp;lt;tex&amp;gt;(w,p)&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;M_v&amp;lt;/tex&amp;gt; и добавим &amp;lt;tex&amp;gt;(u,w)&amp;lt;/tex&amp;gt;;&lt;br /&gt;
* если &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; уже добавлена в паре с некоторой вершиной &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; уже добавлена в паре с некоторой &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, то удалим &amp;lt;tex&amp;gt;(u,p)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;(w,k)&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;M_v&amp;lt;/tex&amp;gt; и добавим &amp;lt;tex&amp;gt;(u,w)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;(p,k)&amp;lt;/tex&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
==== Выбор вершин для мутации ====&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;d(v)&amp;lt;/tex&amp;gt; — степень вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; (количество ребер, которые из нее выходят), &amp;lt;tex&amp;gt;d(G)&amp;lt;/tex&amp;gt; — средняя степень среди вершин &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;\Delta G&amp;lt;/tex&amp;gt; — максимальная степень среди вершин &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;\delta d(G) = \frac{1} {2m} \sum_{v \in V}d(v)^2&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Есть три способа выбрать две вершины для мутации.&lt;br /&gt;
&lt;br /&gt;
'''Ориентированный на вершины'''&lt;br /&gt;
&lt;br /&gt;
Сначала случайно выбираем &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt;. Затем случайно и независимо выбираем &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;L_v&amp;lt;/tex&amp;gt;. Вероятность &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; выбрать пару &amp;lt;tex&amp;gt;(u,w)&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;L_v&amp;lt;/tex&amp;gt; удовлетворяет соотношению:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;p = \frac{1} {d(v)^2n} = \frac{d(G)} {2d(v)^2m} \ge \frac{d(G)} {2 \Delta (G)^2m}&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Ориентированный на ребра'''&lt;br /&gt;
&lt;br /&gt;
Выбираем случайно вершину &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; из всех &amp;lt;tex&amp;gt;2m&amp;lt;/tex&amp;gt; вершин во всех списках &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Пусть она оказалась в &amp;lt;tex&amp;gt;L_v&amp;lt;/tex&amp;gt;. Далее случайно выбираем &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;L_v&amp;lt;/tex&amp;gt;. Вероятность &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; выбрать пару &amp;lt;tex&amp;gt;(u,w)&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;L_v&amp;lt;/tex&amp;gt; удовлетворяет соотношению:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;p = \frac{1} {2d(v)m} \ge \frac{1} {2 \Delta (G)m}&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Ориентированный на пары вершин'''&lt;br /&gt;
&lt;br /&gt;
Выбираем случайно пару &amp;lt;tex&amp;gt;(u,w)&amp;lt;/tex&amp;gt; из всех пар для всех &amp;lt;tex&amp;gt;2m&amp;lt;/tex&amp;gt; вершин во всех списках в &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Пусть обе вершины присутствуют в &amp;lt;tex&amp;gt;L_v&amp;lt;/tex&amp;gt;. Тогда вероятность &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; выбрать пару &amp;lt;tex&amp;gt;(u,w)&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;L_v&amp;lt;/tex&amp;gt; удовлетворяет соотношению:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;p = \frac{1} {2\delta d(G)m} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эти три случая эквивалентны в случае разреженного графа (в котором &amp;lt;tex&amp;gt;d(G) = \delta d(G) = \Delta (G)&amp;lt;/tex&amp;gt;). В общем случае &amp;lt;tex&amp;gt;d(G) \le \delta d(G) \le \Delta (G)&amp;lt;/tex&amp;gt; и лучший результат достигается для способа, который ориентирован на вершины.&lt;br /&gt;
&lt;br /&gt;
==== Стратегии RLS и (1+1) EA ====&lt;br /&gt;
Эволюционный алгоритм поиска эйлерова цикла в графе работает следующим образом. Размер популяции возьмем равным одному; представление графа, операция мутации и фитнес функция будут такими, как описано выше. Начальное заполнение множества &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; можно сделать случаным образом или оставить пустым, на время работы алгоритма это не влияет.&lt;br /&gt;
&lt;br /&gt;
Стратегия Randomized local search будет работать так: на каждом шаге к текущему индивиду (он один, так как в популяции только одна особь) применяется операция мутации. Если полученный индивид лучше текущего, он выбирается для дальнейшей работы, в противном случае ничего не происходит. Алгоритм работает до тех пор, пока фитнес функция не минимизирована.&lt;br /&gt;
&lt;br /&gt;
Псевдокод:&lt;br /&gt;
  Initialize(M)&lt;br /&gt;
  while (f(M) &amp;gt; 1) do&lt;br /&gt;
      M′:=φ(M) &lt;br /&gt;
      if f(M′) ≤ f(M) &lt;br /&gt;
          then M := M′&lt;br /&gt;
&lt;br /&gt;
Стратегия (1+1) evolutionary algorithm в классическом варианте применяет операцию мутации к каждому биту &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-битной строки с вероятностью &amp;lt;tex&amp;gt; \frac{1} {n}&amp;lt;/tex&amp;gt;. В текущем алгоритме применять изменения можно только последовательно, поэтому просто делают операцию мутации несколько раз.&lt;br /&gt;
&lt;br /&gt;
Псевдокод:&lt;br /&gt;
  Initialize(M) &lt;br /&gt;
  while (f(M) &amp;gt; 1) do&lt;br /&gt;
      M′ :=M &lt;br /&gt;
      for i := 0 to k do //k — некоторое число&lt;br /&gt;
          M′ := φ(M′) &lt;br /&gt;
      if f(M′) ≤ f(M) &lt;br /&gt;
          then M := M′&lt;br /&gt;
&lt;br /&gt;
==== Время работы алгоритма ====&lt;br /&gt;
Для RLS и (1+1) EA верны следующие оценки времени работы алгоритма:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\frac{\Delta(G)^2} {d(G)}*m*log(m))&amp;lt;/tex&amp;gt; для стратегии, ориентированной на вершины;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\Delta(G)*m*log(m))&amp;lt;/tex&amp;gt; для стратегии, ориентированной на ребра;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\delta d(G)*m*log(m))&amp;lt;/tex&amp;gt; для стратегии, ориентированной на пары.&lt;/div&gt;</summary>
		<author><name>188.134.48.45</name></author>	</entry>

	</feed>