介绍
一直想做一个matlab的可视化界面,可是GUIDE有点难,看了许久也做不出来,后来发现做APP挺简单的,同样是可视化界面。
这里由以前写的遗传算法解决TSP问题的文章修改而来。
Matlab遗传算法用于旅行商问题优化TSP
做出来的界面效果:
很朴素,作为初学者,能用就行了。
过程
新建APP
菜单新建那里有APP设计,打开后把组件库里需要的零件拖出来就行了
双击可以改名字。
加入回调函数
当按下确定时开始进行遗传算法的运算,结束后把结果显示在页面上。
新建回调函数,切换到代码视图页面。只能在白色框里编辑代码,灰色无法编辑。
把遗传算法计算作为函数运行。
画图函数中加入句柄:(第一个参数为句柄:app.UIAxes2)
plot(app.UIAxes2,time1,min_dis,‘k.’);
读取输入数据:(get(句柄,值变量))
city_num=str2num(get(app.ListBox,‘Value’));
显示数据在页面上:
set(app.TextArea,‘Value’,num2str(a));
honld on改为hold(ui,‘on’);
ui为句柄
s_num=get(app.EditField_num,'Value');
city_num=str2num(get(app.ListBox,'Value'));
pc=get(app.EditField_pc,'Value');
pm=get(app.EditField_pm,'Value');
[N,city_coordinate,time1,min_dis,pop_fit_aver,a]=genetic_TSP1(app.UIAxes4,s_num,city_num,pc,pm);
plot(app.UIAxes,city_coordinate(:,1),city_coordinate(:,2),'ro');%画平均适应度折线图
for i=1:N
test_t=num2str(i);
text(app.UIAxes,city_coordinate(i,1),city_coordinate(i,2),test_t);%标号
end
plot(app.UIAxes2,time1,min_dis,'k.');%最小值散点图
plot(app.UIAxes3,time1,pop_fit_aver);%画适应度折线图
set(app.TextArea,'Value',num2str(a));
运行结果
代码
function [N,city_coordinate,time1,min_dis,pop_fit_aver,a]=genetic_TSP1(ui,s,N,pc,pm)
%clc;close all;clear all;
%N=30;%城市数
city_coordinate=tsp(N);%城市位置
%s=100;%样本数
c=30;%替换个数
%pc=0.9;%交叉概率
%pm=0.2;%变异概率
times=5000; %最大迭代次数
time=0; %实际迭代次数
pop=zeros(s,N+1);%初始种群+适应度
pop_fit_aver=[];%总适应度
min_dis=[];%最短距离
pop_min=[];%最短距离的基因
for i=1:s %初始化
pop(i,1:N)=randperm(N);
end
city_distance=CityDistance(city_coordinate,N);%城市间距离
[individual_fit,sum,min1,min_index]=GroupFit(city_distance,N,pop,s);%适应度
sumP=sum;
pop_fit_aver=[pop_fit_aver;sum];
min_dis=[min_dis;min1];
pop(:,N+1)=individual_fit;
pop_min=[pop_min;pop(min_index,:)];
pop=ChooseParents(pop,N,s,c);%选择父代
for i=1:times
time=time+1;
E_new_new=[]; %子代
for j=1:s/2
a=rand(1);
b=rand(1);
if a>pc %交叉
;
else
crosspoint=rand(1,2);
crosspoint=floor(crosspoint*N)+1;
[pop(j,:),pop(j+s/2,:)]=CrossVariation(pop(j,:),pop(j+s/2,:),crosspoint,N);
end
if b>pm
;
else
pop(j,:)=Mutation(pop(j,:),N);
pop(j+s/2,:)=Mutation(pop(j+s/2,:),N);
end
E_new_new=[E_new_new;pop(j,:);pop(j+s/2,:)];
end
[individual_fit,sum,min1,min_index]=GroupFit(city_distance,N,E_new_new,s);
sumS=sum;
pop_fit_aver=[pop_fit_aver;sum];
min_dis=[min_dis;min1];
E_new_new(:,N+1)=individual_fit;
pop_min=[pop_min;E_new_new(min_index,:)];
if(abs(sumS-sumP)<0.001)%退出条件
break;
end
pop=ChooseParents(E_new_new,N,s,c);
end
[a,min_index]=min(min_dis);
time1=1:time+1;
DrawPath(ui,city_coordinate,pop_min,min_index,N)
end
function [city_distance] = CityDistance(city_coordinate,N)%城市距离矩阵
city_distance=zeros(N,N);
for i=1:N
for j=1:N
city_distance(i,j)=((city_coordinate(i,1)-city_coordinate(j,1))^2+...
(city_coordinate(i,2)-city_coordinate(j,2))^2)^0.5;
end
end
end
function [individual_fit,num,min_distance,a] = GroupFit(city_distance,N,pop,s)%种群适应度
individual_distance=zeros(s,1);
for j=1:s
sum_distance=0;
for i=1:N-1
sum_distance=sum_distance+city_distance(pop(j,i),pop(j,i+1));
end
sum_distance=sum_distance+city_distance(pop(j,N),pop(j,1));
individual_distance(j,1)=sum_distance;
end
[min_distance,a]=min(individual_distance);
individual_fit=1./individual_distance;
num=0;
for i=1:s
num=num+individual_fit(i,1);
end
end
function [pop_ok]=ChooseParents(pop,N,s,c)%选择父代
pop=sortrows(pop,N+1);
for i=1:c
pop(i,:)=pop(s+1-i,:);
end
randIndex=randperm(size(pop,1));
pop=pop(randIndex,:);
pop_ok=pop;
end
function [a,b]=SwapRepeat(tbl,pop1,pop2,c1,c2,N)%基因去重
i=100/N;
for k=1:(c1-1)
if tbl(pop1(k),3)>i
kk=find(pop1(c1:c2)==pop1(k))+c1-1;
kkk=pop1(k);
pop1(k)=pop2(kk);
pop2(kk)=kkk;
end
end
for k=c2+1:N
if tbl(pop1(k),3)>i
kk=find(pop1(c1:c2)==pop1(k))+c1-1;
kkk=pop1(k);
pop1(k)=pop2(kk);
pop2(kk)=kkk;
end
end
a=pop1;
b=pop2;
end
function [a,b]=CrossVariation(pop1,pop2,crosspoint,N)%交叉
A=pop1;
if(crosspoint(:,1)<crosspoint(:,2))
pop1(crosspoint(:,1):crosspoint(:,2))=pop2(crosspoint(:,1):crosspoint(:,2));
pop2(crosspoint(:,1):crosspoint(:,2))=A(1,crosspoint(:,1):crosspoint(:,2));
while 1
tbl = tabulate(pop1(1:N));
if (tbl(:,3)<=(100/N))
break;
end
[pop1,pop2]=SwapRepeat(tbl,pop1,pop2,crosspoint(:,1),crosspoint(:,2),N);
end
else
pop1(crosspoint(:,2):crosspoint(:,1))=pop2(crosspoint(:,2):crosspoint(:,1));
pop2(crosspoint(:,2):crosspoint(:,1))=A(1,crosspoint(:,2):crosspoint(:,1));
while 1
tbl = tabulate(pop1(1:N));
if (tbl(:,3)<=(100/N))
break;
end
[pop1,pop2]=SwapRepeat(tbl,pop1,pop2,crosspoint(:,2),crosspoint(:,1),N);
end
end
a=pop1;b=pop2;
end
function [a]=SwapGene(sub,c1,c2)%交换
kk=ceil((c2-c1)/2);
kkk=(c2-c1)+2;
for k=1:kk
kkkk=sub(k);
sub(k)=sub(kkk-k);
sub(kkk-k)=kkkk;
end
a=sub;
end
function [a]=Mutation(pop0,N)%变异
crosspoint=rand(1,2);
crosspoint=floor(crosspoint*N)+1;
if(crosspoint(:,1)<crosspoint(:,2))
sub=pop0(crosspoint(:,1):crosspoint(:,2));
sub=SwapGene(sub,crosspoint(:,1),crosspoint(:,2));
pop0(crosspoint(:,1):crosspoint(:,2))=sub;
else
sub=pop0(crosspoint(:,2):crosspoint(:,1));
sub=SwapGene(sub,crosspoint(:,2),crosspoint(:,1));
pop0(crosspoint(:,2):crosspoint(:,1))=sub;
end
a=pop0;
end
function DrawPath(ui,city_coordinate,E_new_new,min_index,N)%画路径图
k=E_new_new(min_index,1:N)
%plot(kkk(:,1),kkk(:,2),'b');%画平均适应度折线图
plot(ui,city_coordinate(:,1),city_coordinate(:,2),'bo');
hold(ui,'on');
for i=1:N-1
plot(ui,[city_coordinate(k(i),1),city_coordinate(k(i+1),1)],[city_coordinate(k(i),2),city_coordinate(k(i+1),2)],'r','LineWidth',2);
test_t=num2str(i);
text(ui,city_coordinate(k(i),1),city_coordinate(k(i),2),test_t);
hold(ui,'on');
end
test_t=[num2str(N)];
text(ui,city_coordinate(k(N),1),city_coordinate(k(N),2),test_t);
end
function [cityn]=tsp(n) %城市位置
cityn=[]
if n==8
city8=[0.1 0.1;
0.9 0.5;
0.9 0.1;
0.45 0.9;
0.9 0.8;
0.7 0.9;
0.1 0.45;
0.45 0.1];
cityn=city8;
elseif n==15
city15=[0.1 0.1;0.9 0.5;0.9 0.1;
0.45 0.9;
0.9 0.8;
0.7 0.9;
0.1 0.45;
0.45 0.1;
0.3 0.75;
0.2 0.1;
0.31 0.22;
0.35 0.25;
0.10 0.75;
0.80 0.35;
0.12 0.45];
cityn=city15;
elseif n==20
city20=[0.1 0.1;0.9 0.5;0.9 0.1;0.45 0.9;
0.9 0.8;0.7 0.9;0.1 0.45;0.45 0.1;0.3 0.75;
0.2 0.1;0.31 0.22;0.35 0.25;0.10 0.75;
0.80 0.35;0.12 0.45;0.67 0.17;0.85 0.32;
0.6 0.9;0.70 0.15;0.66 0.22];
cityn=city20;
elseif n==30
city30=[18 54;87 76;74 78;71 71;25 38;58 35;4 50;
13 40;18 40;24 42;71 44;64 60;68 58;83 69;58 69;54 62;51 67;37 84;
41 94;2 99;7 64;22 60;25 62;62 32;87 7;91 38;83 46;41 26;45 21;44 35];
cityn=city30;
end
end
classdef app1 < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
TSPUIFigure matlab.ui.Figure
UIAxes matlab.ui.control.UIAxes
Button matlab.ui.control.Button
UIAxes2 matlab.ui.control.UIAxes
UIAxes3 matlab.ui.control.UIAxes
UIAxes4 matlab.ui.control.UIAxes
EditField_2Label matlab.ui.control.Label
EditField_pc matlab.ui.control.NumericEditField
EditFieldLabel matlab.ui.control.Label
EditField_num matlab.ui.control.NumericEditField
Label matlab.ui.control.Label
ListBox matlab.ui.control.ListBox
Label_2 matlab.ui.control.Label
EditField_pm matlab.ui.control.NumericEditField
Label_3 matlab.ui.control.Label
TextArea matlab.ui.control.TextArea
end
methods (Access = private)
% Button pushed function: Button
function ButtonPushed(app, event)
s_num=get(app.EditField_num,'Value');
city_num=str2num(get(app.ListBox,'Value'));
pc=get(app.EditField_pc,'Value');
pm=get(app.EditField_pm,'Value');
[N,city_coordinate,time1,min_dis,pop_fit_aver,a]=genetic_TSP1(app.UIAxes4,s_num,city_num,pc,pm);
plot(app.UIAxes,city_coordinate(:,1),city_coordinate(:,2),'ro');%画平均适应度折线图
for i=1:N
test_t=num2str(i);
text(app.UIAxes,city_coordinate(i,1),city_coordinate(i,2),test_t);%标号
end
plot(app.UIAxes2,time1,min_dis,'k.');%最小值散点图
plot(app.UIAxes3,time1,pop_fit_aver);%画适应度折线图
set(app.TextArea,'Value',num2str(a));
end
% Value changed function: EditField_num
function EditField_numValueChanged(app, event)
value = app.EditField_num.Value;
end
end
% App initialization and construction
methods (Access = private)
% Create UIFigure and components
function createComponents(app)
% Create TSPUIFigure
app.TSPUIFigure = uifigure;
app.TSPUIFigure.Position = [100 100 640 480];
app.TSPUIFigure.Name = '遗传算法解决TSP问题';
% Create UIAxes
app.UIAxes = uiaxes(app.TSPUIFigure);
title(app.UIAxes, '城市位置分布图')
xlabel(app.UIAxes, 'X')
ylabel(app.UIAxes, 'Y')
app.UIAxes.PlotBoxAspectRatio = [1 0.511254019292605 0.511254019292605];
app.UIAxes.TitleFontWeight = 'bold';
app.UIAxes.Position = [14 204 300 185];
% Create Button
app.Button = uibutton(app.TSPUIFigure, 'push');
app.Button.ButtonPushedFcn = createCallbackFcn(app, @ButtonPushed, true);
app.Button.Position = [33 444 100 25];
app.Button.Text = '开始';
% Create UIAxes2
app.UIAxes2 = uiaxes(app.TSPUIFigure);
title(app.UIAxes2, '每代最小值散点图')
xlabel(app.UIAxes2, '迭代次数')
ylabel(app.UIAxes2, '最短距离')
app.UIAxes2.PlotBoxAspectRatio = [1 0.512903225806452 0.512903225806452];
app.UIAxes2.TitleFontWeight = 'bold';
app.UIAxes2.Position = [333 204 300 185];
% Create UIAxes3
app.UIAxes3 = uiaxes(app.TSPUIFigure);
title(app.UIAxes3, '总适应度折线图')
xlabel(app.UIAxes3, '迭代次数')
ylabel(app.UIAxes3, '总适应度')
app.UIAxes3.PlotBoxAspectRatio = [1 0.512903225806452 0.512903225806452];
app.UIAxes3.TitleFontWeight = 'bold';
app.UIAxes3.Position = [14 1 300 185];
% Create UIAxes4
app.UIAxes4 = uiaxes(app.TSPUIFigure);
title(app.UIAxes4, '最短路径图')
xlabel(app.UIAxes4, 'X')
ylabel(app.UIAxes4, 'Y')
app.UIAxes4.PlotBoxAspectRatio = [1 0.511254019292605 0.511254019292605];
app.UIAxes4.TitleFontWeight = 'bold';
app.UIAxes4.Position = [333 1 300 185];
% Create EditField_2Label
app.EditField_2Label = uilabel(app.TSPUIFigure);
app.EditField_2Label.HorizontalAlignment = 'right';
app.EditField_2Label.Position = [403 445 53 22];
app.EditField_2Label.Text = '交叉概率';
% Create EditField_pc
app.EditField_pc = uieditfield(app.TSPUIFigure, 'numeric');
app.EditField_pc.Limits = [0 1];
app.EditField_pc.Position = [471 445 100 22];
app.EditField_pc.Value = 0.9;
% Create EditFieldLabel
app.EditFieldLabel = uilabel(app.TSPUIFigure);
app.EditFieldLabel.HorizontalAlignment = 'right';
app.EditFieldLabel.Position = [180 445 53 22];
app.EditFieldLabel.Text = '种群数量';
% Create EditField_num
app.EditField_num = uieditfield(app.TSPUIFigure, 'numeric');
app.EditField_num.Limits = [0 Inf];
app.EditField_num.ValueDisplayFormat = '%.0f';
app.EditField_num.ValueChangedFcn = createCallbackFcn(app, @EditField_numValueChanged, true);
app.EditField_num.Position = [248 445 100 22];
app.EditField_num.Value = 100;
% Create Label
app.Label = uilabel(app.TSPUIFigure);
app.Label.HorizontalAlignment = 'right';
app.Label.Position = [192 398 41 22];
app.Label.Text = '城市数';
% Create ListBox
app.ListBox = uilistbox(app.TSPUIFigure);
app.ListBox.Items = {'8', '15', '20', '30'};
app.ListBox.Position = [248 348 100 74];
app.ListBox.Value = '8';
% Create Label_2
app.Label_2 = uilabel(app.TSPUIFigure);
app.Label_2.HorizontalAlignment = 'right';
app.Label_2.Position = [403 398 53 22];
app.Label_2.Text = '变异概率';
% Create EditField_pm
app.EditField_pm = uieditfield(app.TSPUIFigure, 'numeric');
app.EditField_pm.Limits = [0 1];
app.EditField_pm.Position = [471 398 100 22];
app.EditField_pm.Value = 0.2;
% Create Label_3
app.Label_3 = uilabel(app.TSPUIFigure);
app.Label_3.HorizontalAlignment = 'right';
app.Label_3.Position = [4 399 53 22];
app.Label_3.Text = '最短距离';
% Create TextArea
app.TextArea = uitextarea(app.TSPUIFigure);
app.TextArea.Editable = 'off';
app.TextArea.Position = [72 399 109 28];
end
end
methods (Access = public)
% Construct app
function app = app1
% Create and configure components
createComponents(app)
% Register the app with App Designer
registerApp(app, app.TSPUIFigure)
if nargout == 0
clear app
end
end
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.TSPUIFigure)
end
end
end