Добавил:
baraevaliza
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабы по ОМО 2025 / Baraeva_Elizaveta_lb5
.pdf
11
учетом штрафов. Функция plot_route визуализирует полученный маршрут на
плоскости. Цвет точки указывает приоритет города (от зеленого до черного).
Зеленые линии – допустимые перелеты, красные – превышающие 5 км.
В конце программа выводит лучший найденный маршрут, его стоимость,
а также отображает график маршрута. Реализация представлена в Листинге
2.3.1. Результат представлен в Листинге 2.3.2 и на Рисунке 2.3.3.
Листинг 2.3.1 – Запуск и визуализация ГА
import matplotlib.pyplot as plt
def GA(coords, priorities, params):
dist_matrix = compute_distance_matrix(coords)
N = len(coords)
if not hasattr(creator, 'FitnessMin'):
creator.create("FitnessMin", base.Fitness, weights=(-
1.0,))
if not hasattr(creator, 'Individual'):
creator.create("Individual", list,
fitness=creator.FitnessMin)
toolbox = base.Toolbox()
toolbox.register("indices", random.sample, range(N), N)
toolbox.register("individual", tools.initIterate,
creator.Individual, toolbox.indices)
toolbox.register("population", tools.initRepeat, list,
toolbox.individual)
toolbox.register("evaluate", eval_route,
dist_matrix=dist_matrix, penalty_coef=params['penalty_coef'])
toolbox.register("mate", tools.cxOrdered)
toolbox.register("mutate", tools.mutShuffleIndexes,
indpb=0.2)
toolbox.register("select", tools.selTournament,
tournsize=params['tour_size'])
pop = toolbox.population(n=params['pop_size'])
hof = tools.HallOfFame(1)
stats = tools.Statistics(lambda ind: ind.fitness.values)
stats.register("min", np.min)
stats.register("avg", np.mean)
pop, log = algorithms.eaSimple(

12
pop, toolbox,
cxpb=params['cxpb'],
mutpb=params['mutpb'],
ngen=params['ngen'],
stats=stats,
halloffame=hof,
verbose=False
)
return hof[0], hof[0].fitness.values[0], log
def plot_route(coords, route, priorities, Dmax=5.0):
colors = {1: 'green', 2: 'yellow', 3: 'orange', 4: 'red',
5: 'black'}
plt.figure(figsize=(7, 7))
for i, (x, y) in enumerate(coords):
plt.scatter(x, y, color=colors[priorities[i]], s=80,
edgecolor='black')
plt.text(x + 0.3, y + 0.3, str(i), fontsize=9)
for i in range(len(route)):
a, b = route[i], route[(i + 1) % len(route)]
xa, ya = coords[a]
xb, yb = coords[b]
dist = np.hypot(xa - xb, ya - yb)
color = 'red' if dist > Dmax else 'green'
plt.plot([xa, xb], [ya, yb], color=color, linestyle='', linewidth=1.5)
plt.title("Оптимальный маршрут почтальона")
plt.xlabel("X (км)")
plt.ylabel("Y (км)")
plt.axis('equal')
plt.grid()
plt.show()
N = 30 # число городов
PARAMS = {
'cxpb': 0.63,
'mutpb': 0.22,
'penalty_coef': 4.4,
'tour_size': 4,
'ngen': 200,
'pop_size': 100
}

13
coords = [(random.uniform(0, 30), random.uniform(0, 30)) for _
in range(N)]
priorities = [random.randint(1, 5) for _ in range(N)]
best_route, best_score, log = GA(coords, priorities, PARAMS)
print("Лучший маршрут:", best_route)
print("Длина маршрута с учетом штрафов:", best_score)
plot_route(coords, best_route, priorities)
Листинг 2.3.2 – Результат ГА
Лучший маршрут: [19, 29, 11, 5, 18, 12, 14, 20, 16, 1, 23, 0,
13, 8, 25, 9, 2, 21, 3, 26, 6, 22, 15, 4, 7, 27, 10, 17, 24,
28]
Длина маршрута с учетом штрафов: 470.3076746873411
Рисунок 2.3.3 – Визуализация маршрута

14
Как можно заметить, ограничение на длину перелета часто нарушается.
Это связано с тем, что и сами города находятся на большом удалении друг от
друга. Кроме того, ограничение по приоритетности доставки также заставляет
нарушать это мягкое ограничение.
2.4. Построить график зависимости лучшей и средней
приспособленности в зависимости от поколения.
Сначала из логов алгоритма извлекаются данные о поколениях, среднем и
минимальном значениях функции приспособленности. Затем строится график,
где отображается, как изменялась средняя и лучшая приспособленность от
поколения к поколению. Это позволяет наглядно проследить, как алгоритм
улучшал решения в процессе эволюции. Реализация представлена в Листинге
2.4.1. Результат представлен на Рисунке 2.4.2.
Листинг 2.4.1 – Построение графика приспособленности
def plot_fitness_stats(log):
gen = [entry["gen"] for entry in log]
avg = [entry["avg"] for entry in log]
min_ = [entry["min"] for entry in log]
plt.figure(figsize=(10, 6))
plt.plot(gen, avg, label="Средняя приспособленность",
color="blue")
plt.plot(gen, min_, label="Лучшая приспособленность",
color="green")
plt.xlabel("Поколение")
plt.ylabel("Значение функции приспособленности")
plt.title("Эволюция приспособленности")
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
plot_fitness_stats(log)

15
Рисунок 2.4.2 – График приспособленности
Как можно заметить, у начального поколения (0-25) идет резкое снижение
значений функции. Это означает, что генетический алгоритм быстро находит
хорошие начальные решения, улучшая маршрут и снижая число длинных
перелетов. У среднего поколения (25–75) улучшения становятся более
плавными. Алгоритм находит все более оптимальные маршруты, но прирост
качества замедляется. У позднего поколения (после ~75) зеленая линия
(лучшее решение) стабилизируется – достигается локальный минимум,
который сохраняется до конца. Синяя линия (среднее по популяции)
продолжает колебаться, что говорит о сохраняющемся разнообразии в
популяции.
Вывод.
В ходе лабораторной работы была изучена и реализована методика
решения задачи оптимизации маршрута доставки с помощью генетического

16
алгоритма. Были сформированы входные данные (координаты городов и
приоритеты доставки), построена функция оценки, учитывающая как длину
маршрута, так и штрафы за превышение допустимого расстояния между
городами.
На основе генетического алгоритма были подобраны параметры
(вероятность скрещивания, мутации, размер популяции, количество
поколений), обеспечивающие стабильное нахождение хороших решений.
Были выбраны подходящие операции: турнирный отбор, упорядоченное
скрещивание и инверсионная мутация, которые позволяют корректно
обрабатывать перестановочные хромосомы.
Полученное оптимальное решение было визуализировано и был построен
график приспособленности, что позволило оценить качество маршрута и
соблюдение ограничений.
Соседние файлы в папке Лабы по ОМО 2025
