Hopfield神经网络是以美国物理学家约翰·霍普菲尔德(John Hopfield)的名字命名的。他在1982年提出了这种类型的神经网络模型,因此通常被称为Hopfield网络。旅行商问题(Traveling Salesman Problem,TSP)是一个经典的组合优化问题,即在给定一组城市及城市之间的距离,找到一条遍历所有城市且每个城市仅被访问一次的最短路径。Holified 神经网络是一种用于解决 TSP 的方法,其原理如下:
一、神经网络模型结构
Holified 神经网络通常由神经元组成的二维网格构成。每个神经元对应一个城市和一个旅行顺序位置。例如,如果有个城市,那么就有个神经元,分别表示每个城市在不同位置的可能性。
二、神经元的激活状态
神经元的激活值表示当前城市在特定位置的可能性。初始时,激活值可以随机设置或根据一些启发式方法初始化。
随着网络的运行,激活值会不断调整,以趋向于表示最优的旅行路径。
三、能量函数
定义一个能量函数来衡量当前网络状态与最优解的差距。这个能量函数通常考虑以下几个因素:
路径长度:即旅行商走过的总距离。这是最重要的因素之一,因为 TSP 的目标就是最小化路径长度。
城市的唯## 标题一性:确保每个城市在路径中只出现一次。
顺序的合理性:保证旅行路径的连续性和合理性。
能量函数的值越低,表示网络状态越接近最优解。通过不断调整神经元的激活值,使能量函数逐渐减小。
四、更新规则
使用一些更新规则来调整神经元的激活值。常见的更新规则包括:
基于梯度下降的方法:根据能量函数的梯度来更新激活值,使网络朝着能量降低的方向发展。
竞争机制:神经元之间相互竞争,激活值高的神经元会抑制激活值低的神经元,以突出更有可能的路径。
更新过程通常是迭代进行的,直到满足一定的收敛条件,例如能量函数的值不再显著变化或达到预设的迭代次数。
五、求解过程
初始化网络:设置神经元的初始激活值和参数。
迭代更新:根据更新规则不断调整神经元的激活值,同时计算能量函数的值。
收敛判断:检查能量函数是否满足收敛条件。如果满足,则停止迭代;否则,继续更新。
提取解:从最终的神经元激活状态中提取出旅行商的路径。通常选择激活值最高的神经元组合作为最优路径。
总之,Holified 神经网络通过构建一个神经元网络模型,利用能量函数和更新规则来不断调整神经元的激活值,以找到旅行商问题的最优解或近似最优解。这种方法在一定程度上可以有效地解决 TSP 问题,但可能需要较长的计算时间和适当的参数调整。
六、完整MATLAB代码
复制粘贴到MATLAB运行即可得出结果图
%% 连续Hopfield神经网络的优化—旅行商问题优化计算
%% 清空环境变量、定义全局变量
clear all
clc
global A D
%% 城市位置
citys=rand(10,2);
%% 计算相互城市间距离
distance = dist(citys,citys');
%% 初始化网络
N = size(citys,1);
A = 200;
D = 100;
U0 = 0.1;
step = 0.0001;
delta = 2 * rand(N,N) - 1;
U = U0 * log(N-1) + delta;
V = (1 + tansig(U/U0))/2;
iter_num = 10000;
E = zeros(1,iter_num);
%% 寻优迭代
for k = 1:iter_num
% 动态方程计算
dU = diff_u(V,distance);
% 输入神经元状态更新
U = U + dU*step;
% 输出神经元状态更新
V = (1 + tansig(U/U0))/2;
% 能量函数计算
e = energy(V,distance);
E(k) = e;
end
%% 判断路径有效性
[rows,cols] = size(V);
V1 = zeros(rows,cols);
[V_max,V_ind] = max(V);
for j = 1:cols
V1(V_ind(j),j) = 1;
end
C = sum(V1,1);
R = sum(V1,2);
flag = isequal(C,ones(1,N)) & isequal(R',ones(1,N));
% flag=1;
%% 结果显示
if flag == 1
% 计算初始路径长度
sort_rand = randperm(N);
citys_rand = citys(sort_rand,:);
Length_init = dist(citys_rand(1,:),citys_rand(end,:)');
for i = 2:size(citys_rand,1)
Length_init = Length_init+dist(citys_rand(i-1,:),citys_rand(i,:)');
end
% 绘制初始路径
figure(1)
plot([citys_rand(:,1);citys_rand(1,1)],[citys_rand(:,2);citys_rand(1,2)],'o-','LineWidth',2);
for i = 1:length(citys)
text(citys(i,1),citys(i,2),[' ' num2str(i)])
end
text(citys_rand(1,1),citys_rand(1,2),[' 起点' ])
text(citys_rand(end,1),citys_rand(end,2),[' 终点' ])
title(['优化前路径(长度:' num2str(Length_init) ')'])
axis([0 1 0 1])
grid on
xlabel('城市位置横坐标')
ylabel('城市位置纵坐标')
% 计算最优路径长度
[V1_max,V1_ind] = max(V1);
citys_end = citys(V1_ind,:);
Length_end = dist(citys_end(1,:),citys_end(end,:)');
for i = 2:size(citys_end,1)
Length_end = Length_end+dist(citys_end(i-1,:),citys_end(i,:)');
end
disp('最优路径矩阵');
% 绘制最优路径
figure(2)
plot([citys_end(:,1);citys_end(1,1)],...
[citys_end(:,2);citys_end(1,2)],'o-','LineWidth',2);
for i = 1:length(citys)
text(citys(i,1),citys(i,2),[' ' num2str(i)])
end
text(citys_end(1,1),citys_end(1,2),[' 起点' ])
text(citys_end(end,1),citys_end(end,2),[' 终点' ])
title(['优化后路径(长度:' num2str(Length_end) ')'])
axis([0 1 0 1])
grid on
xlabel('城市位置横坐标')
ylabel('城市位置纵坐标')
% 绘制能量函数变化曲线
figure(3)
plot(1:iter_num,E,'LineWidth',2);
ylim([0 2000])
title(['能量函数变化曲线(最优能量:' num2str(E(end)) ')']);
xlabel('迭代次数');
ylabel('能量函数');
else
disp('寻优路径无效');
end
function du=diff_u(V,d)
global A D
n=size(V,1);
sum_x=repmat(sum(V,2)-1,1,n);
sum_i=repmat(sum(V,1)-1,n,1);
V_temp=V(:,2:n);
V_temp=[V_temp V(:,1)];
sum_d=d*V_temp;
du=-A*sum_x-A*sum_i-D*sum_d;
end
function E=energy(V,d)
global A D
n=size(V,1);
sum_x=sumsqr(sum(V,2)-1);
sum_i=sumsqr(sum(V,1)-1);
V_temp=V(:,2:n);
V_temp=[V_temp V(:,1)];
sum_d=d*V_temp;
sum_d=sum(sum(V.*sum_d));
E=0.5*(A*sum_x+A*sum_i+D*sum_d);
end
七、部分效果