Метод имитации отжига задача коммивояжера python

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

Решение задачи коммивояжера методом имитации отжига

NataliaPopkova/travelling_salesman

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Sign In Required

Please sign in to use Codespaces.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Читайте также:  Computer science java courses

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats

Files

Failed to load latest commit information.

README.md

Вам дана карта, на которой отмечено N поселений. Поселения находятся на различном расстоянии друг от друга. Торговец отправляется из поселения N0. Предложите алгоритм, который позволит найти оптимальный маршрут для обхода всех N поселений и вернуться в точку старта.

Решение задачи оптимизации методом отжига

Пусть S – множество всех состояний (решений) нашей задачи. Пусть Si текущее состояние на i-ом шаге алгоритма. Пусть Т — температура на текущем шаге.

Для того, чтобы использовать имитацию отжига, нам понадобится определить три функции:

  1. Функцию энергии или, проще говоря, то что мы оптимизируем (E:S -> R). В данном случае это будет длина маршрута.
  2. Функцию изменения температуры T с течением времени. Она должна быть убывающей, так что в текущей реализации выбран простой линейный вариант.
  3. Функцию, порождающую новое состояние Si. В текущей реализации эта функция обращает случайную подпоследовательность городов в маршруте.

Если энергия состояния-кандидата меньше текущего, совершается переход в это состояние, иначе переход вероятностный (чтобы избежать застревания в локальном минимуме).

В контексте данной задачи целевой функцией (функцией энергии) является сумма евклидовых расстояний между парой городов в маршруте.

Иллюстрация к проекту

About

Решение задачи коммивояжера методом имитации отжига

Источник

Русские Блоги

Алгоритм имитации отжига и его реализация в Python (две) -TSP проблема

Алгоритм имитации отжига и его реализация в Python (две) -TSP проблема

В предыдущей статье были представлены основные принципы алгоритма имитации отжига ( Алгоритм имитации отжига и его питон достижения ( Один) ), в данной статье представлен тип проблемы, наиболее часто используемой в математическом моделировании имитируемого алгоритма отжига — задача коммивояжера, которая является проблемой коммивояжера. Описание проблемы такого типа:

Торговый продавец начинает свой путь из города 1, ему нужно отправиться в другие города n для продажи товаров и, наконец, возвращается в город 1. Если расстояние между любыми двумя городами известно, как продавец выбирает лучший маршрут?

Этот тип проблемы является очень типичным типом NP-трудной задачи, упомянутой в предыдущей статье.Если используется метод перечисления, когда число городов увеличивается, объем вычислений будет увеличиваться геометрически. Итак, как использовать алгоритм SA, чтобы найти приближенное оптимальное решение? Прежде всего, наша задача превращается в математическую модель:

Предполагать

Мы ищем минимальное значение функции Z. Ниже мы будем использовать python для построения SA-модели задачи TSP и постараемся найти приближенное оптимальное решение.

Сначала импортируйте данные проблемы и разберитесь с ними:

from __future__ import division import pandas as pd import utils import numpy as np import math import matplotlib.pyplot as plt citys=pd.read_table('./data/tsp100.txt',sep='\t',header=None) citys.columns=['x'] citys['y']=None for i in range(len(citys)): coordinate=citys['x'][i].split() citys['x'][i]=float(coordinate[0]) citys['y'][i]=float(coordinate[1]) print citys.head(5)

1.string.split () может вырезать строку, ее использование заключается в следующем:

Затем посмотрите, как выглядят данные

Набор данных хранит координаты каждого города.В качестве отправной точки мы берем первый город, а также конечную точку. Затем удалите этот город из набора данных, чтобы облегчить вычисления.

start=list(citys.iloc[0]) end=list(citys.iloc[0]) citys=citys.drop([0]) citys.index=[i for i in range(len(citys))]

Затем мы можем инициализировать наш пешеходный маршрут, мы напрямую используем порядок городов, хранящихся в наборе данных, в качестве нашего начального пешеходного маршрута.

paths=[i for i in range(len(citys))]# initiate path 

Исходную карту маршрутов можно получить с помощью matplotlib:

Затем мы устанавливаем начальную температуру в соответствии с правилами, указанными выше, то есть случайным образом выбираем несколько групп состояний, вычисляем группу с наибольшей разностью энергий и получаем начальную температуру на основе этого. Мы устанавливаем вероятность принятия в 0,5.

''' random path and calculate distance to sreach for optimal initiate temperature ''' distance1=0 distance2=0 dif=0 for i in range(10): #np.random.shuffle(path) newPaths1=list(np.random.permutation(paths)) newPaths2=list(np.random.permutation(paths)) distance1=utils.CalLength(citys,newPaths1,start,end) distance2=utils.CalLength(citys,newPaths2,start,end) difNew=abs(distance1-distance2) if difNew>=dif: dif=difNew Pr=0.5 #initiate accept possibility T0=dif/Pr#initiate terperature

1. Функция для расчета расстояния определяется в модуле utils:

import math def CalDistance(x,y): return math.sqrt(x**2+y**2) def CalLength(citys, paths,start,end): length=0 n=1 for i in range(len(paths)): if i==0: length+=CalDistance(start[0]-citys['x'][paths[i]],start[1]-citys['y'][paths[i]]) n+=1 elif n

2. np.random.permutation (список) может нарушить сортировку данных в списке, но он не заменит исходный список напрямую, а np.random.shuffle (список) заменит его напрямую.

Теперь мы можем инициализировать другие параметры:

T=T0 Tmin=T/50 k=10*len(paths) #times of internal circulation length=0#initiate distance according to the initiate path length=utils.CalLength(citys,paths,start,end) print length t=0 #time 

Расстояние, необходимое для получения начального пути, рассчитывается как:

Затем выполните процесс охлаждения. Здесь, в отношении настройки функции соседства, мы сначала настроим ее на изменение положения пары узлов на пути.

while T>Tmin: for i in range(k): a=0 b=0 newPaths=paths while a==b: a=np.random.randint(0,len(paths)) b=np.random.randint(0,len(paths)) te=newPaths[a] newPaths[a]=newPaths[b] newPaths[b]=te newLength=utils.CalLength(citys,newPaths,start,end) if newLength

Окончательный результат выполнения выглядит следующим образом

Диаграмма пути выглядит следующим образом:

Теперь мы пытаемся улучшить алгоритм SA:

Сначала мы изменим начальный путь, чтобы начальный путь также генерировался случайным образом:

paths=list(np.random.permutation(paths))

Затем мы улучшаем функцию соседства и устанавливаем функцию, чтобы поменять местами несколько пар узлов в соответствии с температурой, чтобы увеличить вероятность пересечения целого.

for j in range(int(T0/500)): a=0 b=0 while a==b: a=np.random.randint(0,len(paths)) b=np.random.randint(0,len(paths)) te=newPaths[a] newPaths[a]=newPaths[b] newPaths[b]=te newLength=utils.CalLength(citys,newPaths,start,end)

Тогда мы можем установить процесс прогрева, то есть есть определенная вероятность того, что температура снова поднимется, чтобы избежать застоя алгоритма на локальном минимуме. Мы устанавливаем вероятность повторного нагрева до 0,15.

back=np.random.uniform(low=0,high=1) if back>=0.85: T=T*2 continue

В итоге наша модель SA выглядит следующим образом:

paths=list(np.random.permutation(paths)) while T>Tmin: for i in range(k): newPaths=paths for j in range(int(T0/500)): a=0 b=0 while a==b: a=np.random.randint(0,len(paths)) b=np.random.randint(0,len(paths)) te=newPaths[a] newPaths[a]=newPaths[b] newPaths[b]=te newLength=utils.CalLength(citys,newPaths,start,end) if newLength=0.85: T=T*2 continue t+=1 print t T=T0/(1+t) print length

Выполните алгоритм и получите результат:

Источник

Метод имитации отжига в Python

Метод имитации отжига является эвристическим алгоритмом оптимизации, вдохновленным процессом отжига в металлургии. Этот метод используется для решения задач оптимизации, таких как коммивояжер, упаковка и другие.

Основные идеи метода имитации отжига

  1. Генерация начального решения
  2. Оценка качества решения
  3. Изменение текущего решения
  4. Принятие или отклонение нового решения на основе вероятности
  5. Повторение шагов 3-4 до достижения критерия остановки

Реализация метода имитации отжига на Python

import random import math def simulated_annealing(init_state, eval_func, perturb_func, T, cooling_func, max_iter): state = init_state state_eval = eval_func(state) best_state = state best_eval = state_eval for i in range(max_iter): T = cooling_func(T, i) if T == 0: break new_state = perturb_func(state) new_eval = eval_func(new_state) delta_eval = new_eval - state_eval if delta_eval < 0 or random.random() < math.exp(-delta_eval / T): state = new_state state_eval = new_eval if state_eval < best_eval: best_state = state best_eval = state_eval return best_state, best_eval

Пример применения метода имитации отжига

Рассмотрим пример решения задачи коммивояжера с использованием метода имитации отжига:

import numpy as np def distance(city1, city2): return np.linalg.norm(city1 - city2) def total_distance(cities, tour): dist = 0 for i in range(len(tour) - 1): dist += distance(cities[tour[i]], cities[tour[i + 1]]) dist += distance(cities[tour[-1]], cities[tour[0]]) return dist def perturb_tour(tour): i, j = random.sample(range(len(tour)), 2) new_tour = tour[:] new_tour[i], new_tour[j] = new_tour[j], new_tour[i] return new_tour def cooling_schedule(T, i): return 0.99 * T cities = np.random.rand(10, 2) init_tour = list(range(len(cities))) best_tour, best_dist = simulated_annealing(init_tour, lambda tour: total_distance(cities, tour), perturb_tour, T=100, cooling_func=cooling_schedule, max_iter=10000) print("Лучший маршрут:", best_tour) print("Расстояние:", best_dist) 

Заключение

Метод имитации отжига является универсальным подходом к решению задач оптимизации. В данной статье была представлена реализация этого метода на языке программирования Python, а также пример его применения для решения задачи коммивояжера. Метод имитации отжига может быть адаптирован для решения других задач оптимизации с помощью соответствующих функций оценки и возмущения.

Источник

Метод отжига в Python

Метод отжига, также известный как алгоритм имитации отжига, является эвристическим алгоритмом оптимизации, основанным на метафоре процесса отжига металла. В контексте Python, этот метод можно использовать для решения задач оптимизации.

Принцип работы метода отжига

  1. Инициализация начального состояния
  2. Выбор случайного соседнего состояния
  3. Вычисление изменения энергии между текущим и соседним состоянием
  4. Принятие или отклонение нового состояния на основе изменения энергии и температуры
  5. Понижение температуры и повторение процесса с шага 2 до выполнения условий остановки

Пример реализации алгоритма отжига на Python

import random import math def simulated_annealing(cost_function, initial_state, temperature, cooling_rate, stopping_temperature): current_state = initial_state current_cost = cost_function(current_state) while temperature > stopping_temperature: neighbour_state = generate_neighbour(current_state) neighbour_cost = cost_function(neighbour_state) delta_cost = neighbour_cost - current_cost acceptance_probability = math.exp(-delta_cost / temperature) if delta_cost < 0 or random.random() < acceptance_probability: current_state, current_cost = neighbour_state, neighbour_cost temperature *= cooling_rate return current_state def generate_neighbour(state): # Реализация функции генерации соседнего состояния pass def cost_function(state): # Реализация функции оценки стоимости состояния pass

В приведенном выше коде функции generate_neighbour и cost_function являются заглушками, которые необходимо заменить на реализации, соответствующие вашей конкретной задаче оптимизации.

Заключение

Метод отжига - это эффективный алгоритм оптимизации, который можно использовать для решения различных задач, таких как задача коммивояжера, оптимизациярасписаний и размещение элементов. Реализация алгоритма отжига на языке Python довольно проста и понятна. Важно выбрать подходящую функцию стоимости и функцию генерации соседних состояний, чтобы алгоритм работал эффективно для вашей конкретной задачи оптимизации.

Преимущества и недостатки метода отжига

Метод отжига имеет следующие преимущества:

  • Простота реализации
  • Способность находить глобальные минимумы
  • Хорошая работа с задачами большой размерности и сложностью

Однако, существуют также и недостатки:

  • Не гарантирует нахождение оптимального решения
  • Зависимость от правильного выбора параметров алгоритма (начальная температура, скорость охлаждения)
  • Требует больше времени на выполнение, чем некоторые другие оптимизационные алгоритмы

Несмотря на недостатки, метод отжига остается популярным и полезным инструментом для решения сложных задач оптимизации в Python и других языках программирования.

Источник

Оцените статью