Вы находитесь на странице: 1из 6

ГУАП

КАФЕДРА № 43

ОТЧЕТ
ЗАЩИЩЕН С ОЦЕНКОЙ
ПРЕПОДАВАТЕЛЬ
Профессор Ю.А. Скобцов
должность, уч. степень, звание подпись, дата инициалы, фамилия

ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ №3

Решение задачи коммивояжера с помощью генетических


алгоритмов

по курсу: ЭВОЛЮЦИОННЫЕ МЕТОДЫ ПРОЕКТИРОВАНИЯ


ПРОГРАММНО-ИНФОРМАЦИОННЫХ СИСТЕМ

РАБОТУ ВЫПОЛНИЛА

4631 Д.А. Попова


СТУДЕНТКА ГР.
подпись, дата инициалы, фамилия

Санкт-Петербург 2019
1. Индивидуальное задание по варианту

2. Листинг программы на языке высокого уровня с


комментариями
close all
clc
clear
load('ANS'); % загрузка ответа
load('City');% загрузка списка городов(координаты)
CitySize=size(City, 1); % число городов
n=1000; % кол-во поколений
N=50; % размер популяции
Pc=0.5; % вероятность скрещивания
Pm=0.01; % вероятность мутации

%Матрица растояний
for i = 1:CitySize
for t = 1:CitySize
Rast(i,t) = sqrt((City(i,2)-City(t,2))^2+(City(i,3)-City(t,3))^2);
end
end

%Начальная популяция
for i=1:N
pop(i,:)=randperm(CitySize);
end

%% Цикл

for w=1:n
%Сортировка популяции по целевой функции
[cost, pop] = Cost(pop, Rast);

%Уменьшение популяции до первоночальных размеров-Выживает сильнейший


pop=pop([1:N],:);
cost=cost([1:N],:);
pr=pop;
%pr=Circle (cost,pop,N); % свормируем пак родителей при помощи колеса рулетки

%Кроссинговер
for i=1:2:(N-1)
if rand<=Pc
[child1,child2]=Cross(pr(i,:),pr(i+1,:)); % создаем пару потомков
pop = [pop; child1; child2];% рассширяем популяцию добавлением потомков
end
end
%Мутация
pop=Mutation(pop,Pm);

end

%Сортировка популяции по целевой функции


[cost, pop] = Cost(pop, Rast);

%Выделим лучшего
WIN=pop(1,:);
R_WIN=cost(1); % Длина маршрута у лучшего
for i=1:(size(ANS,1)-1)
f(i)=Rast(ANS(i),ANS(i+1)); % расстояния между соседними городами в маршруте
end
R_ANS=sum(f)+Rast(ANS(1),ANS(end)); % длина маршрута у ответа
figure (3)
hold on
plot(City([ANS;ANS(1)], 2),City([ANS;ANS(1)], 3),'-o','LineWidth',3,'Color',[0 0 1])
plot(City([WIN,WIN(1)], 2),City([WIN,WIN(1)], 3),'--o','LineWidth',2,'Color',[1 0 0])

fprintf ('Относительная погрешность: %g %% ',((R_WIN-R_ANS)/R_ANS)*100);


disp(' ');

%% Функции

%Функция для целефой функции и сортировки популяции


function [cost, pop]= Cost(pop, Rast)
%в качесве целевой функции выступает суммарное расстояние в марштуре
for j=1:size(pop,1)
for i=1:(size(pop,2)-1)
f(i)=Rast(pop(j,i),pop(j,i+1)); % расстояния между соседними городами в маршруте
end
cost(j,1)=sum(f)+Rast(pop(j,1),pop(j,end)); % полное расстояние в маршруте
end

[cost,ind] = sort(cost); % сортировка значений целевой функции в порядке возрастания


pop =(pop(ind,:));% сортировка популяции

end

%Функция кроссинговера
function [child1,child2]=Cross(pr1, pr2)
child1=zeros(1,size(pr1,2));
child2=zeros(1,size(pr1,2));
r=randi([2,size(pr1,2)-1],1,2); % две точки кроссинговера
lo=min(r); % левая точка
up=max(r); % правая точка
% lo=2;
% up=7;

% Штука для формирования матрицы преобразований K


A=[pr1(lo:up);pr2(lo:up)];
i=1;
while isempty(A)~=1
B=A(:,1);
q=1;
while q~=0
C=A(:,~any(ismember(A,B),1));
B=A(:,any(ismember(A,B),1));
q=sum(sum(ismember(C,B)));
end
[n,x]=hist([B(1,:),B(2,:)],unique(B));
if isempty(find(1==n))==0 % в случае циклической перестановки
K(:,i)=x(find(1==n));
else
K(:,i)=B(:,1);
end
i=i+1;
A=C;
end

%обмен серединками
child1(lo:up)= pr2(lo:up);
child2(lo:up)= pr1(lo:up);

% заменяем оставшиеся элементы согласно закону преобразования К

for i= 1:size(K,2) % двигаемся по столбцам


a=K(1,i);
b=K(2,i);

Z=find(a==pr1); % z-место где a находится в pr1


if child1(Z)==0 % если это место в child1=0, то есть не в центре
child1(Z)=b; % заменить соответсвенно
end
Z=find(a==pr2);
if child2(Z)==0
child2(Z)=b;
end
Z=find(b==pr1);
if child1(Z)==0
child1(Z)=a;
end
Z=find(b==pr2);
if child2(Z)==0
child2(Z)=a;
end
end

% сносим элементы, которым не нашлось правила преобразования


d=find(child1==0);
for i=1:size(d,2)
child1(d(i))=pr1(d(i));
end
d=find(child2==0);
for i=1:size(d,2)
child2(d(i))=pr2(d(i));
end

end

%Функиця мутации
function pop=Mutation(pop,Pm)

for i=1:size(pop,1)
if rand<=Pm % проверка вероятности мутации

pm1=randi([1,size(pop,2)]); % первая точка мутации


pm2=randi([1,size(pop,2)]); % вторая точка мутации
pop(i,[pm1 pm2])= pop(i,[pm2 pm1]); % замена гена

end
end
end

%Функция Колесо рулетки


function pr=Circle (cost,pop,N)
prob=fliplr(round(N*([1:N]/sum([1:N])))); % Весовые функции
prob1=cumsum(prob);
% Копируем марштуры согласно prob
i=1; j=1;
while i<=N
if j<=prob1(i)
pr(j,:)=pop(i,:);
j=j+1;
else
i=i+1;
end
end
idx=randperm(N); % случайным образом перемешаем, что бы одинаковые родители не
шли друг за другом
pr=pr(idx,:);

end

Результат выполнения программы