%参数同上
file2 = uigetfile('*.txt'); if ~isequal(file2, 0) read2(file2); end
% --- Executes on button press in pushbutton3.
function pushbutton3_Callback(hObject, eventdata, handles) %参数同上 TSPsom;
% --- Executes on button press in pushbutton4.
function pushbutton4_Callback(hObject, eventdata, handles) %参数同上 open('result.txt');
% --- Executes on button press in pushbutton4.
function pushbutton5_Callback(hObject, eventdata, handles) %参数同上 cla;
function pushbutton6_Callback(hObject, eventdata, handles) %参数同上 close(gcbf);
%-------------------------------------------------------------------------- function read1(file)
fidin=fopen(file); % 打开.txt文件 fidout=fopen('coordinates.txt','w'); % 创建coordinates.txt文件
while ~feof(fidin) % 判断是否为文件末尾 tline=fgetl(fidin); % 从文件读行
if double(tline(1))>=48&&double(tline(1))<=57 % 判断首字符是否是数值
fprintf(fidout,'%s\\n\\n',tline); % 如果是数字行,把此行数据写入文件coordinates.txt continue % 如果是非数字继续下一次循环 end end
fclose(fidout);
%-------------------------------------------------------------------------- function read2(file)
fidin=fopen(file); % 打开.txt文件 fidout=fopen('distance.txt','w'); % 创建distance.txt文件
while ~feof(fidin) % 判断是否为文件末尾 tline=fgetl(fidin); % 从文件读行
if double(tline(1))>=48&&double(tline(1))<=57 % 判断首字符是否是数值
fprintf(fidout,'%s\\n\\n',tline); % 如果是数字行,把此行数据写入文件distance.txt continue % 如果是非数字继续下一次循环 end end
fclose(fidout);
%-------------------------------------------------------------------------- function TSPsom()
%TSP问题,使用自组织特征映射神经网络SOFM解决 %把经纬度转换成了直角坐标后进行计算 clear all;
city_name=str2mat('哈尔滨' ,'长春', '乌鲁木齐', '沈阳' ,'呼和浩特', '北京' ,'天津', '银川', '太原', '济南', '西宁', '青岛', '兰州', '郑州', '西安', '南京', '合肥', '上海', '成都', '武汉' ,'杭州', '拉萨' ,'重庆' ,'长沙' ,'贵阳' ,'福州', '桂林', '昆明' ,'广州', '南宁');
distanc = importdata('distance.txt'); % 将生成的distance.txt文件导入工作空间,变量名为distanc,实际上它不显示出来
org1 = importdata('coordinates.txt'); %将生成的coordinates.txt文件导入工作空间,变量为org1,实际上它不显示出来 [m,n] = size(distanc);
city_num = m; %设置城市数目
neuron_num = city_num*3; %设置神经元数目,这里神经元为城市数目的3倍,经验公式为1.5~2.5倍
neurons = rand(neuron_num,2)*1000;%随机产生一组神经元,为了和城市分布一致,将产生的0~1范围的数都乘以100
cities = org1(:,2:3); %获取城市坐标(org1矩阵的2~3列) %下面是参数: t1=1000; t2=1000; delta=10; alpha=0.9;
times=1000;%迭代次数,经验为城市数目的20~50倍,这里取的更多一些,使得网络更加收敛
n = -1;
h = waitbar(0,'正在计算,请稍候……');%创建一个计算进度条 while (n < times)%开始进行迭代
waitbar(n/times,h)%显示进度条
n = n + 1;
for i = 1:city_num%计算获胜神经元———————————————— dist = 100000; ix = 0;
for j = 1:city_num
tmp=(cities(i,:)-neurons(j,:))*(cities(i,:)-neurons(j,:))';%计算城市和每个神经元的距离,找到最小的
if (tmp < dist) dist = tmp; ix = j; end end
% 调整神经元的权值
rate = alpha*exp(-n/t2);%alpha(n)
width = delta*exp(-n/(t1/log(10)));%theta(n) for j = 1:city_num
d = min(abs(ix-j),city_num-abs(j-ix));%d(j,i) %d = distance(ix,j);
neurons(j,:)=neurons(j,:)+rate*exp(-d*d/(2*width*width))*(cities(i,:) - neurons(j,:)); end
end % ———————————— end % while
close(h)%关闭进度条
for i=1:neuron_num%将神经元矩阵加上序号,放在第一列,坐标放在第2和第3列———————————— tmp=0;
tmp = neurons(i,1);
neurons(i,3) = neurons(i,2); neurons(i,2) = tmp; neurons(i,1) = i;
end%————————————
for i=1:city_num%城市矩阵加上序号,放在第一列,坐标放在第2和第3列————————————
tmp = cities(i,1);
cities(i,3) = cities(i,2); cities(i,2) = tmp; cities(i,1) = i; end
for i = 1:city_num %按城市寻找离该城市最近的神经元,把结果放到result矩阵中,result矩阵第1列为城市序号,第2,3列为城市坐标,第4列为找到的神经元编号,第5列为距离 dist = 100000; ix = 0;
for j = 1:city_num
tmp=(cities(i,2:3)-neurons(j,2:3))*(cities(i,2:3)-neurons(j,2:3))';
if (tmp < dist) dist = tmp; ix = j; end end
result(i,1) = cities(i,1); result(i,2) = cities(i,2); result(i,3) = cities(i,3); result(i,4) = ix; result(i,5) = dist;
end%————————————
result2=sortrows(result,4);%按result矩阵的第4列升序排列,结果放到result2矩阵中
%这么做是由于神经元序列可以连成一条环路,现在要找离神经元最近的城市,把城市连起来
p = 1:city_num;
p = [p 1]; %P为一个从1,2,……,城市数目,1的向量 grid on;
plot(neurons(p,2),neurons(p,3),'ro','MarkerSize',5); %在图中画出最终的神经元,用红色圆圈表示,只画出和城市数目相等的神经元,否则……太乱 hold on;
%plot(neurons(p,1),neurons(p,2)); %画出最终的城市编号 plot(result2(p,2),result2(p,3));%画出最终的城市路径 %hold on;
plot(cities(p,2),cities(p,3),'go','Markersize',10);%画出城市点,用绿色圆圈表示 % plot(result(p,1),result(p,2)); for i=1:city_num
text(result2(i,2)-0.1,result2(i,3)-0.9,city_name(result2(i,1),:))%标出城市的名称 end
dist=0;%计算得到的城市路径的总长度———————————— for i=1:city_num-1
dist = dist + distanc(result2(i,1),result2(i+1,1)); end
dist = dist + distanc(result2(city_num,1),result2(1,1)); %—————————————— dist
str=strcat('城市数目:',int2str(city_num)); str=strcat(str,' 神经元数目:'); str=strcat(str,int2str(neuron_num)); str=strcat(str,' 迭代次数:'); str=strcat(str,int2str(times));
str=strcat(str,' 学习步长参数α:'); str=strcat(str,int2str(alpha));
str=strcat(str,' 宽度参数σ:'); str=strcat(str,int2str(delta));
title(str);
xlabel(strcat('路径长度:',int2str(dist)));
%完成输出文件
%file3 = uigetfile('*.txt'); %if ~isequal(file3, 0)
%fidin1=fopen(file3); fid1 = fopen('result.txt','w'); % for i=1:4
% tline1=fgetl(fidin1);
% fprintf(fid1,'%s\\n',tline1); % end
fprintf(fid1,'TOUR_SECTION\\n'); fprintf(fid1,'%i,',result2(:,1));
fprintf(fid1,'\\ndistance = %f\\n',dist); fclose(fid1);