Hopfield神经网络求解旅行商问题(Traveling Salesman Problem,TSP),提供完整MATLAB代码,复制粘贴即可运行

Hopfield神经网络是以美国物理学家约翰·霍普菲尔德(John Hopfield)的名字命名的。他在1982年提出了这种类型的神经网络模型,因此通常被称为Hopfield网络。Hopfield网络是一种早期的人工神经网络,具有以下特点:

  1. 递归连接:网络中的每个神经元都与其他所有神经元相连,形成一个高度耦合的网络。

  2. 单层网络:尽管Hopfield网络通常被视为单层网络,但它通过递归连接实现了类似于多层网络的功能。

  3. 能量函数:Hopfield网络定义了一个能量函数,网络的动态演化过程可以看作是能量函数的最小化过程。网络状态的稳定性与能量函数的局部极小值相关联。

  4. 稳定性:Hopfield网络具有稳定的吸引子状态,网络会收敛到这些状态之一。这些吸引子状态可以看作是网络的记忆或存储的模式。

  5. 联想记忆:Hopfield网络能够存储和回忆模式,即使在输入模式不完全或有噪声的情况下也能做到这一点。

  6. 优化问题:Hopfield网络可以用于解决优化问题,如旅行商问题(TSP),通过将问题的解决方案映射到网络的能量状态中,并寻找能量函数的最小值。

  7. 异步更新:在Hopfield网络中,神经元的状态更新通常是异步进行的,即在任何给定的时间步,只有一个神经元的状态会更新。

  8. 局部计算:每个神经元的状态更新只依赖于其当前的输入和网络的当前状态,不需要全局信息。

Hopfield神经网络主要用于优化问题和联想记忆。在旅行商问题(TSP)中,Hopfield网络通过能量函数的最小化来寻找问题的近似最优解。

原理介绍:

  1. 模型结构:Hopfield神经网络通常由神经元组成的二维网格构成,每个神经元对应一个城市和一个旅行顺序位置。
  2. 激活状态:神经元的激活值表示当前城市在特定位置的可能性,初始时随机设置,运行中不断调整。
  3. 能量函数:定义一个能量函数来衡量当前网络状态与最优解的差距,包括路径长度、城市的唯一性和顺序的合理性。
  4. 更新规则:使用更新规则来调整神经元的激活值,如基于梯度下降的方法或竞争机制。
  5. 求解过程:初始化网络,迭代更新,判断收敛,提取解。最终的神经元激活状态表示旅行商的路径。

完整MATLAB如下,复制粘贴即可运行:

bash 复制代码
%% 连续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)






相关推荐
zylyehuo14 小时前
Hilbert 矩阵的求解
matlab
ServBay2 天前
告别面条代码,PSL 5.0 重构 PHP 性能与安全天花板
后端·php
JaguarJack4 天前
FrankenPHP 原生支持 Windows 了
后端·php·服务端
BingoGo4 天前
FrankenPHP 原生支持 Windows 了
后端·php
JaguarJack5 天前
PHP 的异步编程 该怎么选择
后端·php·服务端
BingoGo5 天前
PHP 的异步编程 该怎么选择
后端·php
JaguarJack6 天前
为什么 PHP 闭包要加 static?
后端·php·服务端
ServBay7 天前
垃圾堆里编码?真的不要怪 PHP 不行
后端·php
用户962377954487 天前
CTF 伪协议
php
BingoGo9 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php