今天为大家分享一个java语言编写的图形化蚁群算法,目前系统功能已经很全面,后续会进一步完善。整个系统界面漂亮,有完整得源码,希望大家可以喜欢。喜欢的帮忙点赞和关注。一起编程、一起进步
开发环境
开发语言为Java,开发环境Eclipse或者IDEA都可以,数据为MySQL。运行主程序,或者执行打开JAR文件即可以运行本程序。
系统框架
利用JDK自带的SWING框架开发,下载。纯窗体模式,直接运行Main文件即可以。同时带有详细得设计文档。
系统主要功能
蚁群算法简介
蚁群算法是受到对真实蚂蚁群觅食行为研究的启发而提出。生物学研究表明:一群相互协作的蚂蚁能够找到食物和巢穴之间的最短路径,而单只蚂蚁则不能。生物学家经过大量细致观察研究发现,蚂蚁个体之间的行为是相互作用相互影响的。蚂蚁在运动过程中,能够在它所经过的路径上留下一种称之为信息素的物质,而此物质恰恰是蚂蚁个体之间信息传递交流的载体。蚂蚁在运动时能够感知这种物质,并且习惯于追踪此物质爬行,当然爬行过程中还会释放信息素。一条路上的信息素踪迹越浓,其它蚂蚁将以越高的概率跟随爬行此路径,从而该路径上的信息素踪迹会被加强,因此,由大量蚂蚁组成的蚁群的集体行为便表现出一种信息正反馈现象。某一路径上走过的蚂蚁越多,则后来者选择该路径的可能性就越大。蚂蚁个体之间就是通过这种间接的通信机制实现协同搜索最短路径的目标的。
假设m只蚂蚁在图的相邻节点间移动,从而协作异步地得到问题的解。每只蚂蚁的一步转移概率由图中的每条边上的两类参数决定:1. 信息素值也称信息素痕迹。2.可见度,即先验值。
2.信息素的更新方式有2种,一是挥发,也就是所有路径上的信息素以一定的比率进行减少,模拟自然蚁群的信息素随时间挥发的过程;二是增强,给评价值“好”(有蚂蚁走过)的边增加信息素。
3.蚂蚁向下一个目标的运动是通过一个随机原则来实现的,也就是运用当前所在节点存储的信息,计算出下一步可达节点的概率,并按此概率实现一步移动,逐此往复,越来越接近最优解。
4.蚂蚁在寻找过程中,或者找到一个解后,会评估该解或解的一部分的优化程度,并把评价信息保存在相关连接的信息素中。
设置参数
运行本蚁群算法,需要设置一些参数,这些参数是在Java 窗体里面根据需要进行动态的设置。
private Ant[] ants; // 蚂蚁
private int cityNum; // 城市数量
private int[] x; // X坐标矩阵
private int[] y; // Y坐标矩阵
private double[][] distance; // 距离矩阵
private double[][] pheromone; // 信息素矩阵
private int bestLength; // 最佳长度
private int[] bestTour; // 最佳路径
private int antNum; // 蚂蚁数量
private int generation; // 迭代次数
private double alpha; // 信息素重要程度系数
private double beta; // 城市间距离重要程度系数
private double rho; // 信息素残留系数
private int Q; // 蚂蚁循环一周在经过的路径上所释放的信息素总量
private int deltaType; // 信息素更新方式模型,0: Ant-quantity; 1: Ant-density; 2: Ant-cycle
运行方法和原理
1 下载压缩包后进行解压,把项目源码导入的IDEA或者EClIPSE中,运行Main.Java文件,启动应用程序
2 在界面上设置相关的参数
3 点击相关的参数,点击开始。
4 程序运行完成后,弹窗除计算出来的最佳的路径,并且展示程序运行时间
5 程序所有点都经过,而且避开障碍物。
系统运行效果
![](https://img-blog.csdnimg.cn/img_convert/fd32699a8205560feace96abb1400843.png)
![](https://img-blog.csdnimg.cn/img_convert/133d63dff34c24b9d18516af95dcd625.png)
关键代码
package com.aco;
import java.io.IOException;
public class ACO {
private Ant[] ants; // 蚂蚁
private int cityNum; // 城市数量
private int[] x; // X坐标矩阵
private int[] y; // Y坐标矩阵
private double[][] distance; // 距离矩阵
private double[][] pheromone; // 信息素矩阵
private int bestLength; // 最佳长度
private int[] bestTour; // 最佳路径
private int antNum; // 蚂蚁数量
private int generation; // 迭代次数
private double alpha; // 信息素重要程度系数
private double beta; // 城市间距离重要程度系数
private double rho; // 信息素残留系数
private int Q; // 蚂蚁循环一周在经过的路径上所释放的信息素总量
private int deltaType; // 信息素更新方式模型,0: Ant-quantity; 1: Ant-density; 2: Ant-cycle
/**
* 构造方法
* @param cityNum
* @param antNum
* @param generation
* @param alpha
* @param beta
* @param rho
* @param Q
*/
public ACO(int cityNum, int antNum, int generation, double alpha, double beta, double rho, int Q, int deltaType) {
this.cityNum = cityNum;
this.antNum = antNum;
this.generation = generation;
this.alpha = alpha;
this.beta = beta;
this.rho = rho;
this.Q = Q;
this.deltaType = deltaType;
ants = new Ant[antNum];
}
/**
* 初始化
* @param filename
* @throws IOException
*/
public void init(String filename) throws IOException {
// 从文件中获取X坐标矩阵、Y坐标矩阵
x = ReadFile.getX(cityNum, filename);
y = ReadFile.getY(cityNum, filename);
// 计算距离矩阵
getDistance(x, y);
// 初始化信息素矩阵
pheromone = new double[cityNum][cityNum];
double start = 1.0 / ((cityNum - 1) * antNum); // 计算初始信息素数值
for (int i = 0; i < cityNum; i++) {
for (int j = 0; j < cityNum; j++) {
pheromone[i][j] = start;
}
}
// 初始化最佳长度及最佳路径
bestLength = Integer.MAX_VALUE;
bestTour = new int[cityNum + 1];
// 初始化antNum个蚂蚁
for (int i = 0; i < antNum; i++) {
ants[i] = new Ant(cityNum);
ants[i].init(distance, alpha, beta);
}
}
/**
* 计算距离矩阵
* @param x
* @param y
* @throws IOException
*/
private void getDistance (int[] x, int[] y) throws IOException {
// 计算距离矩阵
distance = new double[cityNum][cityNum];
for (int i = 0; i < cityNum - 1; i++) {
distance[i][i] = 0; // 对角线为0
for (int j = i + 1; j < cityNum; j++) {
distance[i][j] = Math.sqrt(((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j])) / 10.0);
distance[j][i] = distance[i][j];
}
}
distance[cityNum - 1][cityNum - 1] = 0;
}
/**
* 解决TSP问题
*/
public void solve() {
// 迭代generation次
for (int g = 0; g < generation; g++) {
// 对antNum只蚂蚁分别进行操作
for (int ant = 0; ant < antNum; ant++) {
// 为每只蚂蚁分别选择一条路径
for (int i = 1; i < cityNum; i++) {
ants[ant].selectNextCity(pheromone);
}
// 把这只蚂蚁起始城市再次加入其禁忌表中,使禁忌表中的城市最终形成一个循环
ants[ant].getTabu().add(ants[ant].getFirstCity());
// 若这只蚂蚁走过所有路径的距离比当前的最佳距离小,则覆盖最佳距离及最佳路径
if (ants[ant].getTourLength() < bestLength) {
bestLength = ants[ant].getTourLength();
for (int k = 0; k < cityNum + 1; k++) {
bestTour[k] = ants[ant].getTabu().get(k).intValue();
}
}
// 更新这只蚂蚁信息素增量矩阵
double[][] delta = ants[ant].getDelta();
for (int i = 0; i < cityNum; i++) {
for (int j : ants[ant].getTabu()) {
if (deltaType == 0) {
delta[i][j] = Q; // Ant-quantity System
}
if (deltaType == 1) {
delta[i][j] = Q / distance[i][j]; // Ant-density System
}
if (deltaType == 2) {
delta[i][j] = Q / ants[ant].getTourLength(); // Ant-cycle System
}
}
}
ants[ant].setDelta(delta);
}
// 更新信息素
updatePheromone();
// 重新初始化蚂蚁
for (int i = 0; i < antNum; i++) {
ants[i].init(distance, alpha, beta);
}
}
// 打印最佳结果
print();
}
/**
* 更新信息素
*/
private void updatePheromone() {
// 按照rho系数保留原有信息素
for (int i = 0; i < cityNum; i++) {
for (int j = 0; j < cityNum; j++) {
pheromone[i][j] = pheromone[i][j] * rho;
}
}
// 按照蚂蚁留下的信息素增量矩阵更新信息素
for (int i = 0; i < cityNum; i++) {
for (int j = 0; j < cityNum; j++) {
for (int ant = 0; ant < antNum; ant++) {
pheromone[i][j] += ants[ant].getDelta()[i][j];
}
}
}
}
/**
* 在控制台中输出最佳长度及最佳路径
*/
private void print() {
System.out.println("最佳长度: " + bestLength);
System.out.print("最佳路径: ");
for (int i = 0; i < cityNum - 1; i++) {
System.out.print(bestTour[i] + 1 + "-");
}
System.out.println(bestTour[cityNum - 1] + 1);
}
/**
* 输出最佳路径
* @return
*/
public int[] getBestTour() {
return bestTour;
}
/**
* 输出最佳长度
* @return
*/
public int getBestLength() {
return bestLength;
}
/**
* 输出X坐标矩阵
* @return
*/
public int[] getX() {
return x;
}
/**
* 输出Y坐标矩阵
* @return
*/
public int[] getY() {
return y;
}
}