Hopfield神经网络是以美国物理学家约翰·霍普菲尔德(John Hopfield)的名字命名的。他在1982年提出了这种类型的神经网络模型,因此通常被称为Hopfield网络。Hopfield网络是一种早期的人工神经网络,具有以下特点:
-
递归连接:网络中的每个神经元都与其他所有神经元相连,形成一个高度耦合的网络。
-
单层网络:尽管Hopfield网络通常被视为单层网络,但它通过递归连接实现了类似于多层网络的功能。
-
能量函数:Hopfield网络定义了一个能量函数,网络的动态演化过程可以看作是能量函数的最小化过程。网络状态的稳定性与能量函数的局部极小值相关联。
-
稳定性:Hopfield网络具有稳定的吸引子状态,网络会收敛到这些状态之一。这些吸引子状态可以看作是网络的记忆或存储的模式。
-
联想记忆:Hopfield网络能够存储和回忆模式,即使在输入模式不完全或有噪声的情况下也能做到这一点。
-
优化问题:Hopfield网络可以用于解决优化问题,如旅行商问题(TSP),通过将问题的解决方案映射到网络的能量状态中,并寻找能量函数的最小值。
-
异步更新:在Hopfield网络中,神经元的状态更新通常是异步进行的,即在任何给定的时间步,只有一个神经元的状态会更新。
-
局部计算:每个神经元的状态更新只依赖于其当前的输入和网络的当前状态,不需要全局信息。
Hopfield神经网络主要用于优化问题和联想记忆。在旅行商问题(TSP)中,Hopfield网络通过能量函数的最小化来寻找问题的近似最优解。
原理介绍:
- 模型结构:Hopfield神经网络通常由神经元组成的二维网格构成,每个神经元对应一个城市和一个旅行顺序位置。
- 激活状态:神经元的激活值表示当前城市在特定位置的可能性,初始时随机设置,运行中不断调整。
- 能量函数:定义一个能量函数来衡量当前网络状态与最优解的差距,包括路径长度、城市的唯一性和顺序的合理性。
- 更新规则:使用更新规则来调整神经元的激活值,如基于梯度下降的方法或竞争机制。
- 求解过程:初始化网络,迭代更新,判断收敛,提取解。最终的神经元激活状态表示旅行商的路径。
完整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
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6116ab2c6e6f4cbfa11e31355aa7817d.png)