目录

一、网络原理

二、算法步骤

三、代码实现 (Java)

四、所用jar包


一、网络原理

Hopfield神经网络(HNN)是一种全互联反馈神经网络,它的每一个神经元都和其他神经元连接。

Hopfield神经网络主要分为离散型Hopfield神经网络(DHNN)和连续型Hopfield神经网络(CHNN),离散型Hopfield神经网络中的神经元与生物神经元的差别较大,因为生物神经元的输入与输出是连续的,并且存在时滞,连续型Hopfield神经网络是一种连续时间神经网络模型,在这种网络中神经元的状态可以取0到1之间的任一实数值。因为Hopfield神经网络的网络联想记忆过程就是非线性动力学系统朝某个稳定状态运行的过程,按照动力学规则改变神经元的状态,最终会使神经网络处于某个稳定状态。

离散型Hopfield神经网络是一种多输入多输出代阈值的二态非线性动力学系统,连续型Hopfield神经网络在简化了生物神经元性质的同时,又准确的保留了生物神经网络的动态和非线性特征。根据其特性,离散型Hopfield神经网络通常被用来处理联想记忆问题,连续型Hopfield神经网络通常被用来处理组合优化问题。TSP问题为典型的组合优化问题,因此经过综合判定,选择连续型Hopfield神经网络作为本题算法模型。

利用神经网络解决优化问题的关键就是如何把待求解的优化问题映射为一个神经网络,一般可以将求解问题的每一个可行解用换位矩阵表示。另一个关键问题是构造能量函数,使其最小值对应问题的最优解,它决定了一个特定问题是否能用神经网络解决。通常采用优化理论中的拉格朗日函数和子乘法或者罚函数法来构造能量函数(公式(1))。

(1)

式中 是违背约束条件的惩罚函数,是优化的目标函数,  为平衡 在总能量函数中的作用的比例常数,且如果最小化 ,则;如果最大化 ,则;。

在TSP问题中能量函数往往要体现该路径的长度,若下标x,y表示城市,i表示第i次访问,则路径长度可以表示为下列一般形式:

(2)

式中 表示换位矩阵中第x行第i列的元素,且其值为1时表示第i步访问城市x,其值为0时表示第i步不访问城市x。

在换位矩阵中每行每列都只能有一个元素为1,其余都为0,否则它表示一条无效的路径。每列只有一个元素为1表示每次只经过一个城市(公式(3)),每行只有一个元素为1表示每个城市经过且只经过一次(公式(4))。

(3)

(4)

利用罚函数法,将上述约束优化问题表示为下列无约束优化问题:

(5)

此时Hopfield神经网络的动态方程为:

(6)

则=采用一阶欧拉法计算时刻的输入为:

(7)

为了保证收敛于正确解,即换位矩阵V每行每列只有一个元素为1,其余为0,应用Sigmoid函数计算

(8)

求解上式,直到收敛,即可得到神经网络的稳态解。

二、算法步骤

Hopfield神经网络解决TSP问题算法步骤如下:

Step 1:设置初始值,初始电压,罚参数A和D,迭代次数T;

Step 2:计算N个城市之间的距离

Step 3:在0附近设置神经网络输入 的初始化数值;

Step 4:根据动态方程(公式(6))计算

Step 5:采用一阶欧拉法计算

Step 6:计算输出换位矩阵

Step 7:应用公式(5),计算能量函数J

Step 8:路径合法性的检查,根据迭代次数判断是否结束,如果结束则终止,否则返回Step 4。

三、代码实现 (Java)

Hopfield类:主要用于模块和接口设计

package Hopfield;import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import jxl.NumberCell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;public class hopfield {private static final double R = 6371.004;private int cityNum;//城市数量private int MAX;//迭代次数//private double bestLength;private int[] bestTour;private double[][] distance;//距离矩阵//private double[][] time;//时间矩阵double[] xx;//用来输出最佳路径每个城市位置double[] yy;//用来输出最佳路径每个城市位置private String filepath;private double A,D;private double U0;//private double[][][][] W;//权值矩阵private double[][] deltaU;//动态结果private double[][] V;//换位矩阵private double[][] Ut;//下一刻输入private double[][] U;//初始值private double step;//步长,即delta tprivate double E;//能量值public hopfield(int MAX,int cityNum,double U0,double step,double A,double D,String filepath) {this.MAX = MAX;this.cityNum = cityNum;this.U0 = U0;this.step = step;this.A = A;this.D = D;this.filepath = filepath;bestTour = new int [cityNum];distance = new double[cityNum][cityNum];W = new double[cityNum][cityNum][cityNum][cityNum];V = new double[cityNum][cityNum];deltaU = new double[cityNum][cityNum];Ut = new double[cityNum][cityNum];U = new double[cityNum][cityNum];xx = new double[cityNum];yy = new double[cityNum];}private static double rad(double d) {return d * Math.PI / 180.0;}//计算距离矩阵public double[][] Distance() throws BiffException, IOException{double[] x = new double[cityNum];double[] y = new double[cityNum];distance = new double[cityNum][cityNum];//创建输入流InputStream stream = new FileInputStream(filepath);//获取Excel文件对象Workbook  rwb = Workbook.getWorkbook(stream);//获取文件的指定工作表 默认的第一个Sheet sheet = rwb.getSheet("Sheet2");for(int i=0;i<sheet.getRows();i++) {NumberCell cell = null;//解决了Cell只保留三位小数的问题cell = (NumberCell) sheet.getCell(0,i); x[i] = cell.getValue();xx[i] = x[i];cell = (NumberCell) sheet.getCell(1,i);y[i] = cell.getValue();yy[i] = y[i];}//计算每个城市间距离for (int i = 0; i < cityNum - 1; i++) {distance[i][i] = 0; // 对角线为0//将经纬度转换为平面距离for (int j = i + 1; j < cityNum; j++) {double rij = 2*R*Math.asin(Math.sqrt(Math.pow(Math.sin((rad(y[j])-rad(y[i]))/2), 2) + Math.cos(rad(y[j]))*Math.cos(rad(y[i]))*Math.pow(Math.sin((rad(x[j])-rad(x[i]))/2), 2)));distance[i][j] = rij;distance[j][i] = distance[i][j];}}distance[cityNum - 1][cityNum - 1] = 0;return distance;}//神经网络动态方程public double[][] calc_du(double[][] V,double[][] distance) {double[] a1 = new double[cityNum];double[] a2 = new double[cityNum];double[] b = new double[cityNum];double[][] t1 = new double[cityNum][cityNum];double[][] t2 = new double[cityNum][cityNum];double[][] d = new double[distance.length][V[0].length];               //按列相加for(int x=0;x<cityNum;x++) {for(int i=0;i<cityNum;i++) {a1[x] += V[x][i];}}for(int i=0;i<cityNum;i++) {for(int j=0;j<cityNum;j++) {t1[i][j] = a1[j];}}//按行相加for(int y=0;y<cityNum;y++) {for(int i=0;i<cityNum;i++) {a2[i] += V[i][y];}}for(int i=0;i<cityNum;i++) {for(int j=0;j<cityNum;j++) {t2[j][i] = a2[j];}}//将第一列放在最后一列for(int i=0;i<cityNum;i++) {b[i] = V[i][0];}for(int i=0;i<cityNum;i++) {for(int j=0;j<cityNum-1;j++) {V[i][j] = V[i][j+1];}}for(int i=0;i<cityNum;i++) {V[i][cityNum-1] = b[i];}double sum=0;for(int j=0;j<V[0].length;j++) {  for(int k=0;k<distance.length;k++) {  for(int i=0;i<distance[0].length;i++) {sum=sum+distance[k][i]*V[i][j];}d[k][j]=sum;sum=0;}}for(int i=0;i<cityNum;i++) {for(int j=0;j<cityNum;j++) {deltaU[i][j] = -1*A*((t1[i][j]-1)+(t2[i][j]-1))-D*d[i][j];}}return deltaU;}//计算输出方程public double[][] calc_V(double[][] U) {for(int x=0;x<cityNum;x++) {for(int i=0;i<cityNum;i++) {V[x][i] = (1+Math.tanh(U[x][i]/U0))/2;}}return V;}//状态更新:下一刻状态Uxi(t0+step)public double[][] calc_Ut(double[][] deltaU,double[][] U) {for(int x=0;x<cityNum;x++) {for(int i=0;i<cityNum;i++) {Ut[x][i] = deltaU[x][i]*step + U[x][i];}}return Ut;}//能量公式public double calc_E(double[][] V,double[][] dis) {double[] a1 = new double[cityNum];double[] a2 = new double[cityNum];double[] b = new double[cityNum];double J;double t1=0,t2=0,t3=0;double[][] V1 = new double[cityNum][cityNum];double[][] d = new double[distance.length][V[0].length];//按列相加for(int x=0;x<cityNum;x++) {for(int i=0;i<cityNum;i++) {a1[x] += V[x][i];}}for(int i=0;i<cityNum;i++) {t1 += (a1[i]-1)*(a1[i]-1);}//按行相加for(int y=0;y<cityNum;y++) {for(int i=0;i<cityNum;i++) {a2[i] += V[i][y];}}for(int i=0;i<cityNum;i++) {t2 += (a2[i]-1)*(a2[i]-1);}//将第一列放在最后一列for(int i=0;i<cityNum;i++) {b[i] = V[i][0];}for(int i=0;i<cityNum;i++) {for(int j=0;j<cityNum-1;j++) {V1[i][j] = V[i][j+1];}}for(int i=0;i<cityNum;i++) {V1[i][cityNum-1] = b[i];}double sum=0;for(int j=0;j<V[0].length;j++) {  for(int k=0;k<distance.length;k++) {  for(int i=0;i<distance[0].length;i++) {sum=sum+distance[k][i]*V1[i][j];}d[k][j]=sum;sum=0;}}for(int j=0;j<V[0].length;j++) {  for(int k=0;k<distance.length;k++) {  for(int i=0;i<distance[0].length;i++) {t3 += d[k][i]*V[i][j];}}}J = (A*t1+A*t2+D*t3)/2;return J;}public int[] getpath(double[][] V) {double[] max = new double[cityNum];//每列最大值for(int j=0;j<cityNum;j++) {double a=0;for(int i=0;i<cityNum;i++) {if(V[i][j] > a) {a = V[i][j];}}max[j] = a;//System.out.print(max[j]+",");}int j=0;for(int i=0;i<cityNum;i++) {if(max[j] == V[i][j]) {bestTour[j] = i;j++;break;}  }return bestTour;}public static Object[] szqc(int[] a) {List list = new ArrayList();//遍历数组往集合里存元素for(int i=0;i<a.length;i++){//如果集合里面没有相同的元素才往里存if(!list.contains(a[i])){list.add(a[i]);}}//toArray()方法会返回一个包含集合所有元素的Object类型数组Object[] newArr = list.toArray();return newArr;
}public void solve() throws BiffException, IOException {int tt[] = new int[cityNum];distance = Distance();//初始化UxiSystem.out.println("U");for(int x=0;x<cityNum;x++) {for(int i=0;i<cityNum;i++) {U[x][i] = 1/2*U0*Math.log(cityNum - 1) + (Math.random()*2-1)/10;System.out.print(U[x][i]+"\t");}System.out.println();}//初始化输出状态System.out.println("V");V = calc_V(U);for(int x=0;x<cityNum;x++) {for(int i=0;i<cityNum;i++) {System.out.print(V[x][i]+"\t");}System.out.println();}//开始迭代for(int i=0;i<MAX;i++) {deltaU = calc_du(V,distance);Ut = calc_Ut(deltaU, U);U = Ut;V = calc_V(U);for(int x=0;x<cityNum;x++) {for(int i1=0;i1<cityNum;i1++) {V[x][i1]=Math.round(V[x][i1]);}}E = calc_E(V,distance);bestTour = getpath(V);Object[] tour = szqc(bestTour);if(tour.length == bestTour.length) {for(int i1=0;i1<cityNum;i1++) {//int x = bestTour[i];System.out.print(bestTour[i1]+",");tt[i1] = bestTour[i1];}System.out.println();double sum1=0;for(int i1=0;i1<cityNum-1;i1++) {sum1 +=distance[bestTour[i1]][bestTour[i1+1]];}sum1 += distance[bestTour[0]][bestTour[cityNum-1]];System.out.println("距离:"+sum1);System.out.println("E:"+E);}}for(int i=0;i<cityNum;i++) {System.out.print(tt[i]+",");}}
}

hopmain类:调用启动程序

package Hopfield;import java.io.IOException;
import jxl.read.biff.BiffException;public class hopmain {public static void main(String[] args) throws BiffException, IOException {//依次输入迭代次数,城市数量,U0,步长,以及A、D参数值,文件路径hopfield hop =new hopfield(50000, 38, 0.02, 0.0001, 1.5, 0.5 ,"D:\\2.xls");hop.solve();}
}

四、所用jar包

jxl包是一款专门用来读取Excel文件的工具包,有需要的可以在maven官网直接下载使用。

Hopfield神经网络解决TSP问题(Java)相关推荐

  1. 学习使用hopfield神经网络解决TSP问题(毕业设计Day01)

    学习使用hopfield神经网络解决TSP问题(毕业设计Day01) 本篇文章主要是学习 <Hopfield神经网络在TSP问题中的应用_兰兆青>这篇文章,如有侵权,请联系删除. (这系列 ...

  2. Hopfield神经网络和TSP问题

    一.TSP问题 旅行商问题,又叫货郎担问题.它是指如下问题:在完全图中寻找一条最短的哈密尔顿回路. 哈密尔顿回路问题:给定一个图,判断图中是否存在哈密尔顿回路. 哈密尔顿回路:寻找一条回路,经过图中所 ...

  3. TSP问题—Hopfield神经网络算法实现

    ''' 连续型--Hopfield神经网络求解TSP 1.初始化权值(A,D,U0) 2.计算N个城市的距离矩阵dxy 3.初始化神经网络的输入电压Uxi和输出电压Vxi 4.利用动力微分方程计算:d ...

  4. 连续Hopfield神经网络的优化——旅行商问题优化计算

    连续Hopfield神经网络 连续Hopfield神经网络(Continuous Hopfield Network, CHN)是一种基于能量最小化原理的神经网络模型,与离散Hopfield网络相比,它 ...

  5. 【HNN TSP】基于matlab hopfield神经网络求解旅行商问题【含Matlab源码 408期】

    ⛄一.简介 1 Hopfield神经网络 2 离散Hopfield网络 3 连续Hopfield网络 CHNN用非线性微分方程描述,网络的稳定性通过构造其能量函数(又称李雅谱诺夫函数),并用李雅谱诺夫 ...

  6. 蚁群算法解决TSP问题(2#JAVA代码+详细注释+对比动态规划【JAVA】)

    第一部分:原理 TSP10cities.txt 1 2066 2333 2 935 1304 3 1270 200 4 1389 700 5 984 2810 6 2253 478 7 949 302 ...

  7. 领域搜索算法java_使用JAVA实现算法——禁忌搜索算法解决TSP问题

    packageBasePart;importjava.io.BufferedReader;importjava.io.FileInputStream;importjava.io.IOException ...

  8. 人工智能 -- 模拟退火算法解决TSP问题(JAVA版)

    计算由广州市出发走遍省内所有市的最短距离. 模拟退火算法:由两规则三函数组成. 两规则指:外层循环结束规则.内层循环结束规则. 三函数指:温度更新函数(控制温度的变化).状态产生函数(用于产生邻结点) ...

  9. TSP问题——Hopfield神经网络

    TSP问题--Hopfield神经网络 clear;clc; % hopfield神经网络 % 问题拟定为在网格上随机选取N个点作为城市,然后计算出TSP问题的最优解 %(1)初始化Hopfield神 ...

最新文章

  1. Asp.net(C#)给图片加上水印效果(转自园上的Seven Eleven)
  2. Sqoop数据迁移原理及基本框架
  3. Linux 操作系统原理 — 文件系统 —文件
  4. Matlab实用程序--图形应用-图形标注
  5. kmean之matlab
  6. 5 款可替代 du 命令的工具!
  7. Java基于springMVC的验证码案例
  8. P3527 [POI2011]MET-Meteors 整体二分 + 树状数组
  9. 每日一问:Android 滑动冲突,你们都是怎样处理的
  10. scala 高阶函数学习
  11. /usr/include/sys/stat.h文件属性
  12. 「Linux」VMware安装centos7(一)
  13. 晶振外匹配电容应该怎样选取
  14. 带妹入坑,她该怎样提高自己的编程能力?
  15. 淘宝直播数据丨食品行业研究报告2021年第一季度
  16. 逆向之制作扫雷外挂——003
  17. P1359 租用游艇 dfs/dp/floyd/dijk/spfa DAG(有向无环图)
  18. 玩转直播:如何从 0 到 1 构建简单直播系统
  19. java3D实现空间立方体,纯CSS3实现一个旋转的3D立方体盒子
  20. matlab中clock是什么,matlab中的clock

热门文章

  1. [办公软件教程] Excel迷你图在哪里?Excel迷你图怎么设置
  2. WinXP盗版的来龙去脉及微软承认的完美盗版方式
  3. 安防监控实现之控制命令下发(命令下发--html通过CGI与用户进程交互)
  4. h5页面中中关闭微信与支付宝窗口
  5. 程序员自己专研和考研或者是进大厂,哪个方法能学到更深层次的技术? 或者什么方法可以学到深层次的技术
  6. ASP.NET Core 配置和使用环境变量
  7. windows简单入侵排查
  8. PY爬虫 | 爬取下厨房的本周最受欢迎
  9. 自由浏览器 android,玩转浏览器 傲游口碑功能大点评
  10. 基于python对密立根油滴实验数据处理改进