<?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=217.66.152.140&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=217.66.152.140&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/217.66.152.140"/>
		<updated>2026-05-19T16:51:00Z</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=26005</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=26005"/>
				<updated>2012-06-20T09:47:42Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.152.140: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Введение ===&lt;br /&gt;
Способ нахождения эйлерова цикла, описанный в данной статье, является примером применения эволюционных алгоритмов на практике. Мы опишем вариант построения, время работы которого &amp;lt;tex&amp;gt;O(m \cdot log \, m )&amp;lt;/tex&amp;gt;&amp;lt;ref&amp;gt;Doerr B., Johannsen D. Adjacency List Matchings - An Ideal Genotype for Cycle Covers. Proceeding GECCO '07 Proceedings of the 9th annual conference on Genetic and evolutionary computation, 1203-1210 (2007)&amp;lt;/ref&amp;gt; (до недавнего времени лучшим считался результат &amp;lt;tex&amp;gt;O(m^2 \cdot log\,m)&amp;lt;/tex&amp;gt;)&amp;lt;ref&amp;gt;B. Doerr, C. Klein, and T. Storch. Faster evolutionary algorithms by superior graph representation. In Proc. of the 2007 IEEE Symposium on Foundations of Computational Intelligence (FOCI), 245–250 (2007). IEEE, 2007.&amp;lt;/ref&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;. Как их выбрать описано в &lt;br /&gt;
[[Эволюционные алгоритмы поиска эйлерова цикла в графе#Выбор вершин для мутации|следующем разделе]].&lt;br /&gt;
Происходит она так:&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)} \cdot m \cdot log \, m)&amp;lt;/tex&amp;gt; для стратегии, ориентированной на вершины;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\Delta(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на ребра;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\delta d(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на пары.&lt;br /&gt;
&lt;br /&gt;
=== Литература ===&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>217.66.152.140</name></author>	</entry>

	<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=26004</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=26004"/>
				<updated>2012-06-20T09:45:36Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.152.140: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Введение ===&lt;br /&gt;
Способ нахождения эйлерова цикла, описанный в данной статье, является примером применения эволюционных алгоритмов на практике. Мы опишем вариант построения, время работы которого &amp;lt;tex&amp;gt;O(m \cdot log \, m )&amp;lt;/tex&amp;gt;&amp;lt;ref&amp;gt;Doerr B., Johannsen D. Adjacency List Matchings - An Ideal Genotype for Cycle Covers. Proceeding GECCO '07 Proceedings of the 9th annual conference on Genetic and evolutionary computation&lt;br /&gt;
Pages 1203-1210&amp;lt;/ref&amp;gt; (до недавнего времени лучшим считался результат &amp;lt;tex&amp;gt;O(m^2 \cdot log\,m)&amp;lt;/tex&amp;gt;)&amp;lt;ref&amp;gt;B. Doerr, C. Klein, and T. Storch. Faster evolutionary algorithms by superior graph representation. In Proc. of the 2007 IEEE Symposium on Foundations of Computational Intelligence (FOCI), pages 245–250. IEEE, 2007.&amp;lt;/ref&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;. Как их выбрать описано в &lt;br /&gt;
[[Эволюционные алгоритмы поиска эйлерова цикла в графе#Выбор вершин для мутации|следующем разделе]].&lt;br /&gt;
Происходит она так:&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)} \cdot m \cdot log \, m)&amp;lt;/tex&amp;gt; для стратегии, ориентированной на вершины;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\Delta(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на ребра;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\delta d(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на пары.&lt;br /&gt;
&lt;br /&gt;
=== Литература ===&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>217.66.152.140</name></author>	</entry>

	<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=26000</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=26000"/>
				<updated>2012-06-20T09:37:57Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.152.140: /* Введение */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Введение ===&lt;br /&gt;
Способ нахождения эйлерова цикла, описанный в данной статье, является примером применения эволюционных алгоритмов на практике. Мы опишем вариант построения, время работы которого &amp;lt;tex&amp;gt;O(m \cdot log \, m )&amp;lt;/tex&amp;gt;&amp;lt;ref&amp;gt;Doerr B., Johannsen D. Adjacency List Matchings - An Ideal Genotype for Cycle Covers&amp;lt;/ref&amp;gt; (до недавнего времени лучшим считался результат &amp;lt;tex&amp;gt;O(m^2 \cdot log\,m)&amp;lt;/tex&amp;gt;)&amp;lt;ref&amp;gt;B. Doerr, C. Klein, and T. Storch. Faster evolutionary algorithms by superior graph representation. In Proc. of the 2007 IEEE Symposium on Foundations of Computational Intelligence (FOCI), pages 245–250. IEEE, 2007.&amp;lt;/ref&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;. Как их выбрать описано в &lt;br /&gt;
[[Эволюционные алгоритмы поиска эйлерова цикла в графе#Выбор вершин для мутации|следующем разделе]].&lt;br /&gt;
Происходит она так:&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)} \cdot m \cdot log \, m)&amp;lt;/tex&amp;gt; для стратегии, ориентированной на вершины;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\Delta(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на ребра;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\delta d(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на пары.&lt;br /&gt;
&lt;br /&gt;
=== Литература ===&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>217.66.152.140</name></author>	</entry>

	<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=25999</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=25999"/>
				<updated>2012-06-20T09:36:51Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.152.140: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Введение ===&lt;br /&gt;
Способ нахождения эйлерова цикла, описанный в данной статье, является примером применения эволюционных алгоритмов на практике. Мы опишем вариант построения, время работы которого &amp;lt;tex&amp;gt;O(m \cdot log \, m )&amp;lt;/tex&amp;gt; &amp;lt;ref&amp;gt;Doerr B., Johannsen D. Adjacency List Matchings - An Ideal Genotype for Cycle Covers&amp;lt;/ref&amp;gt; (до недавнего времени лучшим считался результат &amp;lt;tex&amp;gt;O(m^2 \cdot log\,m)&amp;lt;/tex&amp;gt;) &amp;lt;ref&amp;gt;B. Doerr, C. Klein, and T. Storch. Faster evolutionary algorithms by superior graph representation. In Proc. of the 2007 IEEE Symposium on Foundations of Computational Intelligence (FOCI), pages 245–250. IEEE, 2007.&amp;lt;/ref&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;. Как их выбрать описано в &lt;br /&gt;
[[Эволюционные алгоритмы поиска эйлерова цикла в графе#Выбор вершин для мутации|следующем разделе]].&lt;br /&gt;
Происходит она так:&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)} \cdot m \cdot log \, m)&amp;lt;/tex&amp;gt; для стратегии, ориентированной на вершины;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\Delta(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на ребра;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\delta d(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на пары.&lt;br /&gt;
&lt;br /&gt;
=== Литература ===&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>217.66.152.140</name></author>	</entry>

	<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=25996</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=25996"/>
				<updated>2012-06-20T09:35:15Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.152.140: /* Введение */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Введение ===&lt;br /&gt;
Способ нахождения эйлерова цикла, описанный в данной статье, является примером применения эволюционных алгоритмов на практике. Мы опишем вариант построения, время работы которого &amp;lt;tex&amp;gt;O(m \cdot log \, m )&amp;lt;/tex&amp;gt; &amp;lt;ref&amp;gt;Doerr B., Johannsen D. Adjacency List Matchings - An Ideal Genotype for Cycle Covers&amp;lt;/ref&amp;gt; (до недавнего времени лучшим считался результат &amp;lt;tex&amp;gt;O(m^2 \cdot log\,m)&amp;lt;/tex&amp;gt;)&amp;lt;ref&amp;gt;B. Doerr, C. Klein, and T. Storch. Faster evolutionary algorithms by superior graph representation. In Proc. of the 2007 IEEE Symposium on Foundations of Computational Intelligence (FOCI), pages 245–250. IEEE, 2007.&amp;lt;\ref&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;. Как их выбрать описано в &lt;br /&gt;
[[Эволюционные алгоритмы поиска эйлерова цикла в графе#Выбор вершин для мутации|следующем разделе]].&lt;br /&gt;
Происходит она так:&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)} \cdot m \cdot log \, m)&amp;lt;/tex&amp;gt; для стратегии, ориентированной на вершины;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\Delta(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на ребра;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\delta d(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на пары.&lt;br /&gt;
&lt;br /&gt;
=== Литература ===&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>217.66.152.140</name></author>	</entry>

	<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=25995</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=25995"/>
				<updated>2012-06-20T09:32:56Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.152.140: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Введение ===&lt;br /&gt;
Способ нахождения эйлерова цикла, описанный в данной статье, является примером применения эволюционных алгоритмов на практике. Мы опишем вариант построения, время работы которого &amp;lt;tex&amp;gt;O(m \cdot log \, m )&amp;lt;/tex&amp;gt; &amp;lt;ref&amp;gt;Doerr B., Johannsen D. Adjacency List Matchings - An Ideal Genotype for Cycle Covers&amp;lt;/ref&amp;gt; (до недавнего времени лучшим считался результат &amp;lt;tex&amp;gt;O(m^2 \cdot 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;. Как их выбрать описано в &lt;br /&gt;
[[Эволюционные алгоритмы поиска эйлерова цикла в графе#Выбор вершин для мутации|следующем разделе]].&lt;br /&gt;
Происходит она так:&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)} \cdot m \cdot log \, m)&amp;lt;/tex&amp;gt; для стратегии, ориентированной на вершины;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\Delta(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на ребра;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\delta d(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на пары.&lt;br /&gt;
&lt;br /&gt;
=== Литература ===&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>217.66.152.140</name></author>	</entry>

	<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=25994</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=25994"/>
				<updated>2012-06-20T09:26:47Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.152.140: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Введение ===&lt;br /&gt;
Способ нахождения эйлерова цикла, описанный в данной статье, является примером применения эволюционных алгоритмов на практике. Мы опишем вариант построения, время работы которого &amp;lt;tex&amp;gt;O(m \cdot log \, m )&amp;lt;/tex&amp;gt; (до недавнего времени лучшим считался результат &amp;lt;tex&amp;gt;O(m^2 \cdot 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;. Как их выбрать описано в &lt;br /&gt;
[[Эволюционные алгоритмы поиска эйлерова цикла в графе#Выбор вершин для мутации|следующем разделе]].&lt;br /&gt;
Происходит она так:&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)} \cdot m \cdot log \, m)&amp;lt;/tex&amp;gt; для стратегии, ориентированной на вершины;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\Delta(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на ребра;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\delta d(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на пары.&lt;br /&gt;
&lt;br /&gt;
=== Литература ===&lt;br /&gt;
1. [[ http://www.google.ru/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0CEwQFjAA&amp;amp;url=http%3A%2F%2Fhalma.mpi-inf.mpg.de%2Fintranet%2Fag1%2Fag1publ.nsf%2F2a58943dc07cf5f2c125729f00364aec%2F%255C%24FILE%2FDoerrJohannsen_2007_AdjacencyListMatchings-AnIdealGenotypeForCycleCovers.pdf&amp;amp;ei=7ZfhT834OqmEmQWTwfHaAw&amp;amp;usg=AFQjCNGEN04hWu3jSLTiYX_DTmpJtqJI_g&amp;amp;sig2=Rm0Y8vZC4NKNn3Sf7X-Ang | Doerr B., Johannsen D. Adjacency List Matchings - An Ideal Genotype for Cycle Covers ]]&lt;/div&gt;</summary>
		<author><name>217.66.152.140</name></author>	</entry>

	<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=25993</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=25993"/>
				<updated>2012-06-20T09:21:44Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.152.140: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Введение ===&lt;br /&gt;
Способ нахождения эйлерова цикла, описанный в данной статье, является примером применения эволюционных алгоритмов на практике. Мы опишем вариант построения, время работы которого &amp;lt;tex&amp;gt;O(m \cdot log \, m )&amp;lt;/tex&amp;gt; (до недавнего времени лучшим считался результат &amp;lt;tex&amp;gt;O(m^2 \cdot 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;. Как их выбрать описано в &lt;br /&gt;
[[Эволюционные алгоритмы поиска эйлерова цикла в графе#Выбор вершин для мутации|следующем разделе]].&lt;br /&gt;
Происходит она так:&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)} \cdot m \cdot log \, m)&amp;lt;/tex&amp;gt; для стратегии, ориентированной на вершины;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\Delta(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на ребра;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\delta d(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на пары.&lt;/div&gt;</summary>
		<author><name>217.66.152.140</name></author>	</entry>

	<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=25992</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=25992"/>
				<updated>2012-06-20T09:17:52Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.152.140: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Введение ===&lt;br /&gt;
Способ нахождения эйлерова цикла, описанный в данной статье, является примером применения эволюционных алгоритмов на практике. Мы опишем вариант построения, время работы которого &amp;lt;tex&amp;gt;O(m \cdot log \, m )&amp;lt;/tex&amp;gt; (до недавнего времени лучшим считался результат &amp;lt;tex&amp;gt;O(m^2 \cdot 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;. Как их выбрать описано в &lt;br /&gt;
[[Эволюционные алгоритмы поиска эйлерова цикла в графе#Выбор вершин для мутации|следующем разделе]].&lt;br /&gt;
Происходит она так:&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)} \cdot m \cdot log \, m)&amp;lt;/tex&amp;gt; для стратегии, ориентированной на вершины;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\Delta(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на ребра;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;O(\delta d(G) \cdot m \cdot log \, m )&amp;lt;/tex&amp;gt; для стратегии, ориентированной на пары.&lt;/div&gt;</summary>
		<author><name>217.66.152.140</name></author>	</entry>

	<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=25991</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=25991"/>
				<updated>2012-06-20T09:16:22Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.152.140: /* Введение */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Введение ===&lt;br /&gt;
Способ нахождения эйлерова цикла, описанный в данной статье, является примером применения эволюционных алгоритмов на практике. Мы опишем вариант построения, время работы которого &amp;lt;tex&amp;gt;O(m \cdot log \, m )&amp;lt;/tex&amp;gt; (до недавнего времени лучшим считался результат &amp;lt;tex&amp;gt;O(m^2 \cdot 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;. Как их выбрать описано в &lt;br /&gt;
[[Эволюционные алгоритмы поиска эйлерова цикла в графе#Выбор вершин для мутации|следующем разделе]].&lt;br /&gt;
Происходит она так:&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>217.66.152.140</name></author>	</entry>

	<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=25990</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=25990"/>
				<updated>2012-06-20T09:15:45Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.152.140: /* Введение */&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 \cdot 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;. Как их выбрать описано в &lt;br /&gt;
[[Эволюционные алгоритмы поиска эйлерова цикла в графе#Выбор вершин для мутации|следующем разделе]].&lt;br /&gt;
Происходит она так:&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>217.66.152.140</name></author>	</entry>

	</feed>