基于连续Hopfield神经网络优化——旅行商问题优化计算

        大家好,我是带我去滑雪!

        利用神经网络解决组合优化问题是神经网络应用的一个重要方面。所谓组合优化问题,就是在给定约束条件下,使目标函数极小(或极大)的变量组合问题。将Hopfield网络应用于求解组合优化问题,把目标函数转化为网络的能量函数,把问题的变量对应到网络的状态,这样,当网络的能量函数收敛于极小值时,问题的最优解也随之求出。由于神经网络是并行计算的,其计算量不随维数的增加而发生指数性“爆炸”,因而对于组合优化问题的高速计算特别有效。典型的组合优化问题有旅行商问题、0-1背包问题、装箱问题、图着色问题、聚类问题等问题。这些问题的描述都非常简单,但优化求解很困难,其主要原因是求解这些问题的算法运行时,需要极长的运行时间和极大的存储空间。

        本期使用连续Hopfield神经网络实现旅行商问题优化计算。

一、问题与模型设计 

(1)问题描述

       旅行商问题,(Traveling Saleman Problem,TSP)是VRP的特例,由于Gaery[1]已证明TSP问题是NP难题,因此,VRP也属于NP难题。旅行商问题(TSP)又译为旅行推销员问题、货郎担问题,简称为TSP问题,是最基本的路线问题,该问题是在寻求单一旅行者由起点出发,通过所有给定的需求点之后,最后再回到原点的最小路径成本。

        现对于一个城市数量为10的TSP问题,要求设计一个可以对其组合优化的连续型Hopfield神经网络模型,利用改模型可以快速地找到最优(或者近似最优)的一条路线。

(2)模型建立思路

        由于连续型Hopfield神经网络具有优化计算的特性,因此将TSP问题的目标函数(即最短路径)与网络的能量函数相对应,将经过的城市顺序与网络的神经元状态相对应。这样,由连续型Hopfield神经网络的稳定性定理知,当网络的能量函数趋于最小值时,网络的神经元状态也趋于平衡点,此时对应的城市顺序即为最佳的路线。

(3)设计步骤

       模型映射:为了将TSP问题映射为一个神经网络的动态过程,Hopfield神经网络采取换位矩阵的表示方式,用NxN的矩阵表示商人访问N个城市。对于N个城市TSP问题,使用NxN个神经元来实现,而每行每列只能有一个1,其余都是0,矩阵中1的和为N,该矩阵成为换位矩阵。

        构造网络能量函数和动态方程:设计的Hopfield神经网络的能量函数与目标函数(即最短路径)相对应的。同时,考虑到有效解的实际意义,即换位矩阵的每行每列都只能有一个1。因此,网络的能量函数包含目标项和约束项两部分。

        初始化网络:Hopfield神经网络迭代过程对网络的能量函数及动态方程的系数十分敏感,在总结前人经验及多次实验的基础上,网络输入初始化选取如下:A=200,D=100,采样时间设置为0.0001,迭代次数为10000。

       优化计算:当网络的结果及参数设计完成后,迭代优化计算的过程就变得非常简单,具体步骤:

步骤1:导入N个城市的位置坐标并计算城市之间的距离;

步骤2:网络初始化;

步骤3:计算能量函数;

步骤4:判断迭代次数是否结束,若迭代次数大于10000,则终止。

二、代码实现

(1)清空环境变量、声明全局变量

clear all
clc
global A D

(2)城市位置导入并计算城市间距离

load city_location
distance = dist(citys,citys');

(3)初始化网络

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);

 (4)寻优迭代

        寻优迭代过程包括动态方程计算、输入神经元状态更新、输出神经元状态更新、能量函数计算四个步骤。 

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

(5)动态方程计算

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;

(6)能量函数计算

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);

(7)主函数

[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));

%% 结果显示
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-')
   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('最优路径矩阵');V1
   % 绘制最优路径
   figure(2)
   plot([citys_end(:,1);citys_end(1,1)],...
       [citys_end(:,2);citys_end(1,2)],'o-')
   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);
   ylim([0 2000])
   title(['能量函数变化曲线(最优能量:' num2str(E(end)) ')']);
   xlabel('迭代次数');
   ylabel('能量函数');
else
   disp('寻优路径无效');
end

(8)结果输出

       优化前的路径:

      优化后的路径图:

      优化后的路径距离相比于没有优化的路径距离更短。

      能量函数变化曲线:

       结果表明:利用Hopfield神经网络 ,可以快速准确地解决TSP问题。同理,对于其他利用枚举法会产生“组合爆炸”的组合优化问题,利用连续型Hopfield神经网络也可以进行优化计算。

需要数据集的家人们可以去百度网盘(永久有效)获取:

链接:
提取码:2138 


更多优质内容持续发布中,请移步主页查看。

   点赞+关注,下次不迷路!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/140669.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

c++四种类型转换

首先我们要先引入上行转换和下行转换的概念 所谓上行转换,即将原来的子类指针转换成父类指针; 下行转换即将原来的父类指针转换成子类指针 由于子类对象的空间较大,所以把子类强制转换父类给父类指针赋值时,父类指针对象能读取…

Android图形系统之X11、Weston、Wayland、Mesa3D、ANGLE、SwiftShader介绍(十五)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…

力扣刷题-二叉树-翻转二叉树

226.翻转二叉树 翻转一棵二叉树。 思路 参考: https://www.programmercarl.com/0226.%E7%BF%BB%E8%BD%AC%E4%BA%8C%E5%8F%89%E6%A0%91.html#%E6%80%9D%E8%B7%AF 如果要从整个树来看,翻转还真的挺复杂,整个树以中间分割线进行翻转&#xf…

基于springboot+vue健身管理系统

基于springbootvue健身管理系统 摘要 健身管理系统是一款基于Spring Boot和Vue.js的全栈应用,致力于为用户提供全面、个性化的健身管理体验。通过Spring Boot构建的后端,系统提供了强大的RESTful API支持,包括用户管理、健身计划制定和健康数…

深度学习_12_softmax_图片识别优化版代码

因为图片识别很多代码都包装在d2l库里了,直接调用就行了 完整代码: import torch from torch import nn from d2l import torch as d2l"获取训练集&获取检测集" batch_size 256 train_iter, test_iter d2l.load_data_fashion_mnist(ba…

msvcp71.dll,msvcr71.dll丢失的最简单的解决方法

在计算机使用过程中,我们常常会遇到一些错误提示,其中之一就是MSVCR71.dll缺失。这个问题可能会导致某些应用程序无法正常运行,给用户带来困扰。本文将介绍5个修复MSVCR71.dll缺失的方案,帮助用户解决这一问题。 一、重新安装相关…

2756基于微信小程序的图书商城系统

摘要 本文将详细介绍基于微信小程序的图书商城系统的设计和实现。该系统包括服务器端和客户端两部分,能够满足管理员和普通用户的需求。通过对用户需求和功能的分析,本文将详细阐述系统设计的关键环节,包括数据库设计和界面设计。最后&#…

安全框架SpringSecurity-2(集成thymeleaf集成验证码JWT)

一、SpringSecurity 集成thymeleaf ①&#xff1a;复制并修改工程 复制04_spring_security并重命名为05_spring_security_thymeleaf ②&#xff1a;添加配置和依赖 添加thymeleaf依赖 <dependency><groupId>org.springframework.boot</groupId><artif…

C++--二叉树经典例题

本文&#xff0c;我们主要讲解一些适合用C的数据结构来求解的二叉树问题&#xff0c;其中涉及了二叉树的遍历&#xff0c;栈和队列等数据结构&#xff0c;递归与回溯等知识&#xff0c;希望可以帮助你进一步理解二叉树。 目录​​​​​​​ 1.二叉树的层序遍历 2.二叉树的公…

【STM32 CAN】STM32G47x 单片机FDCAN作为普通CAN外设使用教程

STM32G47x 单片机FDCAN作为普通CAN外设使用教程 控制器局域网总线&#xff08;CAN&#xff0c;Controller Area Network&#xff09;是一种用于实时应用的串行通讯协议总线&#xff0c;它可以使用双绞线来传输信号&#xff0c;是世界上应用最广泛的现场总线之一。CAN协议用于汽…

Swift爬虫程序

以下是一个简单的Swift爬虫程序&#xff0c;用于从前程无忧深圳地区招聘财务、会计的数据爬取数据&#xff1a; import Foundation import SwiftSoup// 创建一个请求对象&#xff0c;指定代理信息 var request URLRequest(url: URL(string: "https://www.51job.com/zh/c…

【Redis】Zset有序集合

上一篇&#xff1a; Hash哈希类型 https://blog.csdn.net/m0_67930426/article/details/134382507?spm1001.2014.3001.5502 目录 Zadd Zrange Zcard Zcount Zrem set是一个无序且元素不可重复的集合 而Zset是一个有序的集合,集合里的每个元素都有一个评分&#xff08;…

性能爆炸!Python多进程模式实现多核CPU并行计算

文章目录 前言一、.Python中的多进程模式二、提高程序执行效率的方法1.多进程并发执行任务2.进程池 3.消息队列4.共享内存5.异步IO 总结关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具…

深度学习之基于Pytorch服装图像分类识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介系统组成1. 数据集准备2. 数据预处理3. 模型构建4. 模型训练5. 模型评估 PyTorch的优势 二、功能三、系统四. 总结 一项目简介 深度学习在计算机视觉领域的…

测试面试越自信越好吗?

前几天面试了一位小伙子&#xff0c;我觉得比较有代表性&#xff0c;所以拿出来跟大家分享一下。 我们公司的招聘流程是首先HR主动寻找或者挑选投简历者中比较合适的人来公司应聘&#xff0c;先是笔试&#xff0c;笔试包括英文部分和专业知识部分&#xff0c;根据做题的结果再…

关于ruoyi(若依)框架的介绍,若依项目的入门,ruoyi(若依)框架的优缺点

一&#xff0c;关于ruoyi&#xff08;若依&#xff09;框架的介绍 若依&#xff08;Ruoyi&#xff09;框架是一款基于 Spring Boot 2.5.5、Spring Cloud 2020.0、OAuth2 与 JWT 鉴权等核心技术&#xff0c;同时也支持Spring Security、Apache Shiro 等多种安全框架&#xff0c;…

利用角色roles上线wordpress项目

角色订制&#xff1a;roles ① 简介 对于以上所有的方式有个弊端就是无法实现复用假设在同时部署Web、db、ha 时或不同服务器组合不同的应用就需要写多个yml文件。很难实现灵活的调用。   roles 用于层次性、结构化地组织playbook。roles 能够根据层次型结构自动装载变量文…

RK3568笔记五:基于Yolov5的训练及部署

若该文为原创文章&#xff0c;转载请注明原文出处。 一. 部署概述 环境&#xff1a;Ubuntu20.04、python3.8 芯片&#xff1a;RK3568 芯片系统&#xff1a;buildroot 开发板&#xff1a;ATK-DLRK3568 开发主要参考文档&#xff1a;《Rockchip_Quick_Start_RKNN_Toolkit2_C…

mysql的主从复制,读写分离

主从复制&#xff1a;主mysql的数据&#xff0c;新增&#xff0c;修改&#xff0c;表里的数据都会同步到从mysql上 主从复制的模式&#xff1a; 1 异步复制 mysql 的最常用的复制&#xff0c;只要执行完&#xff0c;客户端提交事务&#xff0c;主mysql 会立即把结果返回给从…

◢Django 自写分页与使用

目录 1、设置分页样式,并展示到浏览器 2、模拟页码 3、生成分页 4、数据显示 5、上一页下一页 6、数据库的数据分页 7、封装分页 8、使用封装好的分页 建立好app后&#xff0c;设置路径path(in2/,views.in2)&#xff0c;视图def in2(request): &#xff0c;HTML: in2.html…