<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>https://discopal.ispras.ru/index.php?action=history&amp;feed=atom&amp;title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D0%B2%D0%BE%D1%8F%D0%B6%D0%B5%D1%80%D0%B0</id>
		<title>Задача коммивояжера - История изменений</title>
		<link rel="self" type="application/atom+xml" href="https://discopal.ispras.ru/index.php?action=history&amp;feed=atom&amp;title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D0%B2%D0%BE%D1%8F%D0%B6%D0%B5%D1%80%D0%B0"/>
		<link rel="alternate" type="text/html" href="https://discopal.ispras.ru/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D0%B2%D0%BE%D1%8F%D0%B6%D0%B5%D1%80%D0%B0&amp;action=history"/>
		<updated>2026-04-24T11:50:14Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.26.4</generator>

	<entry>
		<id>https://discopal.ispras.ru/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D0%B2%D0%BE%D1%8F%D0%B6%D0%B5%D1%80%D0%B0&amp;diff=1111&amp;oldid=prev</id>
		<title>StasFomin в 17:52, 30 ноября 2011</title>
		<link rel="alternate" type="text/html" href="https://discopal.ispras.ru/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D0%B2%D0%BE%D1%8F%D0%B6%D0%B5%D1%80%D0%B0&amp;diff=1111&amp;oldid=prev"/>
				<updated>2011-11-30T17:52:38Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Задача коммивояжера (В англоязычной литературе — [[Traveling Salesman Problem]], сокращенно TSP), заключается в следующем:&lt;br /&gt;
&lt;br /&gt;
Заданы ''n'' городов &amp;lt;m&amp;gt;v_1,v_2,\ldots,v_n&amp;lt;/m&amp;gt;&lt;br /&gt;
и попарные расстояния &amp;lt;m&amp;gt;d_{ij} \equiv d(v_i,v_j)&amp;lt;/m&amp;gt; между ними,&lt;br /&gt;
являющиеся положительными целыми числами.&lt;br /&gt;
&lt;br /&gt;
Чему равна наименьшая возможная длина кольцевого маршрута,&lt;br /&gt;
проходящего по одному разу через все города? Иными словами, требуется&lt;br /&gt;
найти минимально возможное значение суммы&lt;br /&gt;
&amp;lt;m&amp;gt;\sum_{i=1}^{n-1} d_{\pi(i),\pi(i+1)} +d_{\pi(n),\pi(1)}&amp;lt;/m&amp;gt;,&lt;br /&gt;
где минимум берется по всем перестановкам &amp;lt;m&amp;gt;\pi(1),\ldots,\pi(n)&amp;lt;/m&amp;gt; чисел&lt;br /&gt;
''1,…,n''.&lt;br /&gt;
&lt;br /&gt;
Приведенный ниже пример переборного алгоритма и его выполнения, демонстрирует его неэффективность, и невозможность нахождения точного решения для данных реальных объемов:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code-python&amp;gt;&lt;br /&gt;
# Находит и возвращает гамильтонов цикл минимального веса &lt;br /&gt;
# в графе G. Использует перебор по всем вершинам кроме первой.&lt;br /&gt;
def tsp_permutations(G):&lt;br /&gt;
    min_path_length=1e300   # устанавливаем минимальную длину в бесконечность&lt;br /&gt;
    min_path=[]&lt;br /&gt;
    start_node=G.nodes()[0] # Фиксируем начальный узел (сокращаем перебор).&lt;br /&gt;
    for path in xpermutations(G.nodes()[1:]): # перебор всех узлов кроме первого.&lt;br /&gt;
        path.insert(0,start_node)    # добавляем в начало пути стартовый узел&lt;br /&gt;
        path_length=0                # обнуляем длину текущего пути  &lt;br /&gt;
        path_is_ok=1                 # Сначала считаем, что путь проходим&lt;br /&gt;
        for i in range(0,len(path)):&lt;br /&gt;
            v1=path[i]   #выбираем ребро (v1,v2), для текущей вершины&lt;br /&gt;
            if i&amp;lt;len(path)-1:      &lt;br /&gt;
                v2=path[i+1]&lt;br /&gt;
            else:&lt;br /&gt;
                v2=path[0]           # Если нода-последняя, то замыкаем путь. &lt;br /&gt;
&lt;br /&gt;
            if G.has_edge(v1,v2):&lt;br /&gt;
                path_length=path_length+G.get_edge(v1,v2)        &lt;br /&gt;
            else:  &lt;br /&gt;
                path_is_ok=0  # нет ребра (v1,v2) - путь непроходим.&lt;br /&gt;
                break &lt;br /&gt;
        if (path_is_ok):&lt;br /&gt;
                print path, path_length&lt;br /&gt;
                if min_path_length&amp;gt;path_length:&lt;br /&gt;
                    min_path_length=path_length        &lt;br /&gt;
                    min_path=path        &lt;br /&gt;
    print &amp;quot;Optimal path:&amp;quot;,min_path, min_path_length&lt;br /&gt;
    return min_path	&lt;br /&gt;
&amp;lt;/code-python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ['NY', 'Moscow', 'Minsk', 'Berlin', 'Kiev'] 205&lt;br /&gt;
 ['NY', 'Moscow', 'Minsk', 'Kiev', 'Berlin'] 170&lt;br /&gt;
 ['NY', 'Moscow', 'Berlin', 'Minsk', 'Kiev'] 225&lt;br /&gt;
 ['NY', 'Moscow', 'Kiev', 'Minsk', 'Berlin'] 155&lt;br /&gt;
 ['NY', 'Berlin', 'Moscow', 'Minsk', 'Kiev'] 210&lt;br /&gt;
 ['NY', 'Berlin', 'Minsk', 'Moscow', 'Kiev'] 175&lt;br /&gt;
 ['NY', 'Berlin', 'Minsk', 'Kiev', 'Moscow'] 155&lt;br /&gt;
 ['NY', 'Berlin', 'Kiev', 'Minsk', 'Moscow'] 170&lt;br /&gt;
 ['NY', 'Kiev', 'Moscow', 'Minsk', 'Berlin'] 175&lt;br /&gt;
 ['NY', 'Kiev', 'Minsk', 'Moscow', 'Berlin'] 210&lt;br /&gt;
 ['NY', 'Kiev', 'Minsk', 'Berlin', 'Moscow'] 225&lt;br /&gt;
 ['NY', 'Kiev', 'Berlin', 'Minsk', 'Moscow'] 205&lt;br /&gt;
 Optimal path: ['NY', 'Moscow', 'Kiev', 'Minsk', 'Berlin'] 155&lt;br /&gt;
&lt;br /&gt;
&amp;lt;graph&amp;gt;&lt;br /&gt;
 graph G{ rankdir=LR; &lt;br /&gt;
 NY -- Berlin[fontcolor=&amp;quot;blue&amp;quot;,label=&amp;quot;$50&amp;quot;,style=&amp;quot;bold&amp;quot;]; &lt;br /&gt;
 NY -- Moscow[fontcolor=&amp;quot;blue&amp;quot;,label=&amp;quot;$60&amp;quot;,style=&amp;quot;bold&amp;quot;]; &lt;br /&gt;
 NY -- Kiev[fontcolor=&amp;quot;blue&amp;quot;,label=&amp;quot;$80&amp;quot;,style=&amp;quot;solid&amp;quot;]; &lt;br /&gt;
 Moscow -- Berlin[fontcolor=&amp;quot;blue&amp;quot;,label=&amp;quot;$50&amp;quot;,style=&amp;quot;solid&amp;quot;]; &lt;br /&gt;
 Moscow -- Minsk[fontcolor=&amp;quot;blue&amp;quot;,label=&amp;quot;$15&amp;quot;,style=&amp;quot;solid&amp;quot;]; &lt;br /&gt;
 Moscow -- Kiev[fontcolor=&amp;quot;blue&amp;quot;,label=&amp;quot;$10&amp;quot;,style=&amp;quot;bold&amp;quot;]; &lt;br /&gt;
 Minsk -- Berlin[fontcolor=&amp;quot;blue&amp;quot;,label=&amp;quot;$20&amp;quot;,style=&amp;quot;bold&amp;quot;]; &lt;br /&gt;
 Minsk -- Kiev[fontcolor=&amp;quot;blue&amp;quot;,label=&amp;quot;$15&amp;quot;,style=&amp;quot;bold&amp;quot;]; &lt;br /&gt;
 Berlin -- Kiev[fontcolor=&amp;quot;blue&amp;quot;,label=&amp;quot;$30&amp;quot;,style=&amp;quot;solid&amp;quot;]; &lt;br /&gt;
 } &lt;br /&gt;
&amp;lt;/graph&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, разработаны различные методы сокращения перебора, кроме того, переборные задачи допускают эффективное распараллеливание на многопроцессорную технику или вычисление сетью обычных компьютеров (см. например, [http://www.tsp.gatech.edu/d15sol/ отчет]), но это не отменяет невозможности точного решения этой задачи, с ростом размера входных данных. Отсутствие же алгоритма субэкспоненциальной сложности для точного решения этой задачи следует из того, что эта задача является NP-полной, и общепринятой гипотезы о несовпадении классов '''P''' и '''NP'''.&lt;br /&gt;
&lt;br /&gt;
Существуют различные алгоритмы для приближенного решения этой задачи или ее частных случаев.&lt;br /&gt;
&lt;br /&gt;
==Метрическая задача коммивояжера==&lt;br /&gt;
&lt;br /&gt;
Задача коммивояжера называется '''метрической''',&lt;br /&gt;
если для матрицы расстояний выполнено неравенство треугольника:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;m&amp;gt;&lt;br /&gt;
   \forall i,j,k \ \  d_{ik} \leq d_{ij} + d_{jk}&lt;br /&gt;
&amp;lt;/m&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для метрической задачи коммивояжера существует приближенный [[алгоритм Кристофидеса]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Задачи]]&lt;/div&gt;</summary>
		<author><name>StasFomin</name></author>	</entry>

	</feed>