AGV小车、机械臂协同作业实战06-任务分配算法(图解蚁群算法)代码示例java

本文主要是介绍AGV小车、机械臂协同作业实战06-任务分配算法(图解蚁群算法)代码示例java,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

什么是蚁群算法?

蚁群系统(Ant System(AS)或Ant Colony
System(ACS))是由意大利学者Dorigo、Maniezzo等人于20世纪90年代首先提出来的。他们在研究蚂蚁觅食的过程中,发现蚁群整体会体现一些智能的行为,例如蚁群可以在不同的环境下,寻找最短到达食物源的路径。

后经进一步研究发现,这是因为蚂蚁会在其经过的路径上释放一种可以称之为“信息素(pheromone)”的物质,蚁群内的蚂蚁对“信息素”具有感知能力,它们会沿着“信息素”浓度较高路径行走,而每只路过的蚂蚁都会在路上留下“信息素”,这就形成一种类似正反馈的机制,这样经过一段时间后,整个蚁群就会沿着最短路径到达食物源了。

在这里插入图片描述
简单来说,就是走捷径!!!

上面的不太具体,看到另外一个博客说的挺 明了的,分享给同学们看看

话说 有2个蚂蚁(分别叫小黄和大黄吧)出来找食物了。从洞穴出来,有两条路可以走,选择哪条路的概率是一致的,因为两条路目前都没有信息素。我们假设结果是大黄走了直线路,小黄走了曲线路。如下图:
在这里插入图片描述

两个蚂蚁在行走过程中分泌信息素,用于标识路线。接着,过了一段时间,大黄 找到了奶酪,此时小黄还在行走中。如下图

在这里插入图片描述

接着大黄要回去的时候,由于直线路含有信息素而曲线路没有信息素(因为当前小黄还没走到奶酪附近),于是大黄选择走有信息素的道路也就是直线路。又过了一段时间,大黄回到了路的起点,而小黄刚走到奶酪附近。可以看出现在两条路的信息素浓度是2: 1。如图

在这里插入图片描述
接着小黄要回去的时候,由于直线路含有的信息素浓度比曲线路高,于是小黄选择走有信息素浓度高的道路也就是直线路。最终当小黄也回到路的起点的时候,两条路的信息素浓度比例是3: 1,如下图

在这里插入图片描述

以后,每当有蚂蚁遇到起点岔路的时候,都会优先选择信息素浓度高的道路。这样,一大批的蚂蚁就能够准确的找到最短路径了。

蚁群算法演练

蚁群算法应用广泛,如旅行商问题(traveling salesman problem,简称TSP)、指派问题、Job-shop调度问题、车辆路径问题(vehicle routing problem)、图着色问题(graph coloring problem)和网络路由问题(network routing problem)等等,下面我们同之前推文一样,以TSP的求解为例演练蚁群算法的应用。

TSP问题描述

蚁群算法最早用来求解TSP问题,并且表现出了很大的优越性,因为它分布式特性,鲁棒性强并且容易与其它算法结合,但是同时也存在这收敛速度慢,容易陷入局部最优(local optimal)等缺点

TSP问题(Travel Salesperson Problem,即旅行商问题或者称为中国邮递员问题),是一种,是一种NP-hard问题,此类问题用一般的算法是很大得到最优解的,所以一般需要借助一些启发式算法求解,例如遗传算法(GA),蚁群算法(ACO),微粒群算法(PSO)等等。

TSP问题可以分为两类,一类是对称TSP问题(Symmetric TSP),另一类是非对称问题(Asymmetric TSP)。所有的TSP问题都可以用一个图(Graph)来描述:

V = { c 1 , c 2 , … , c i , … , c n } , i = 1 , 2 , … , n V=\{c_1,c_2,\ldots,c_i,\ldots,c_n\},i=1,2,\ldots,n V={c1,c2,,ci,,cn},i=1,2,,n是所有城市的集合.
c i c_i ci表示第i个城市, n n n为城市的数目;

E = { ( r , s ) : r , s ∈ V } E=\{(r,s):r,s \in V\} E={(r,s):r,sV}是所有城市之间连接的集合;

C = { c r s : r , s ∈ V } C=\{c_{rs}:r,s \in V\} C={crs:r,sV}是所有城市之间连接的成本度量(一般为城市之间的距离);

如果 c r s = c s r c_{rs} = c_{sr} crs=csr, 那么该TSP问题为对称的,否则为非对称的。

一个TSP问题可以表达为:

求解遍历图 G = ( V , E , C ) G=(V,E,C) G=(V,E,C),所有的节点一次并且回到起始节点,使得连接这些节点的路径成本最低。

蚁群算法原理

假如蚁群中所有蚂蚁的数量为m,所有城市之间的信息素用矩阵pheromone表示,最短路径为bestLength,最佳路径为bestTour。每只蚂蚁都有自己的内存,内存中用一个禁忌表(Tabu)来存储该蚂蚁已经访问过的城市,表示其在以后的搜索中将不能访问这些城市;还有用另外一个允许访问的城市表(Allowed)来存储它还可以访问的城市;另外还用一个矩阵(Delta)来存储它在一个循环(或者迭代)中给所经过的路径释放的信息素;还有另外一些数据,例如一些控制参数 ( α , β , ρ , Q ) (\alpha,\beta,\rho,Q) (αβρQ),该蚂蚁行走玩全程的总成本或距离(tourLength),等等。假定算法总共运行MAX_GEN次,运行时间为t。

蚁群算法计算过程如下:

(1)初始化

设t=0,初始化bestLength为一个非常大的数(正无穷),bestTour为空。初始化所有的蚂蚁的Delt矩阵所有元素初始化为0,Tabu表清空,Allowed表中加入所有的城市节点。随机选择它们的起始位置(也可以人工指定)。在Tabu中加入起始节点,Allowed中去掉该起始节点。

(2)为每只蚂蚁选择下一个节点。

为每只蚂蚁选择下一个节点,该节点只能从Allowed中以某种概率(公式1)搜索到,每搜到一个,就将该节点加入到Tabu中,并且从Allowed中删除该节点。该过程重复n-1次,直到所有的城市都遍历过一次。遍历完所有节点后,将起始节点加入到Tabu中。此时Tabu表元素数量为n+1(n为城市数量),Allowed元素数量为0。接下来按照(公式2)计算每个蚂蚁的Delta矩阵值。最后计算最佳路径,比较每个蚂蚁的路径成本,然后和bestLength比较,若它的路径成本比bestLength小,则将该值赋予bestLength,并且将其Tabu赋予BestTour。

其中 p i j ( t ) p_{ij}^{(t)} pij(t)表示选择城市j的概率, k k k表示第 k k k个蚂蚁, τ i j ( t ) \tau_{ij}^{(t)} τij(t)表示城市 i , j i,j i,j在第 t t t时刻的信息素浓度, η i j \eta_{ij} ηij表示从城市i到城市j的可见度,

η i j = 1 d i j \eta_{ij} = \frac 1 {d_{ij}} ηij=dij1 d i j d_{ij} dij表示城市 i , j i,j i,j之间的成本(或距离)。由此可见 d i j d_{ij} dij越小, η i j \eta_{ij} ηij越大,也就是从城市 i i i j j j的可见性就越大。 Δ τ i j k \Delta \tau_{ij}^k Δτijk表示蚂蚁 k k k在城市 i i i j j j之间留下的信息素。

L k L_k Lk表示蚂蚁 k k k经过一个循环(或迭代)锁经过路径的总成本(或距离),即tourLength. α , β , Q \alpha, \beta, Q α,β,Q 均为控制参数。

(3)更新信息素矩阵

t = t + n t=t+n t=t+nt,按照(公式3)更新信息素矩阵phermone。

[ \tau_{ij}(t+n) = \rho \cdot \tau_{ij}(t) + \Delta \tau_{ij} ]

(公式3)

τ i j ( t + n ) \tau_{ij}(t+n) τij(t+n) t + n t+n t+n时刻城市 i i i j j j之间的信息素浓度。 ρ \rho ρ为控制参数, D e l t a i j Delta_ij Deltaij为城市 i i i j j j之间信息素经过一个迭代后的增量。并且有

[ \Delta \tau_{ij} = \sum_{k=1}^m \Delta \tau_{ij}^k]

(公式4)

其中 Δ τ i j k \Delta \tau_{ij}^k Δτijk由公式计算得到。

(4)检查终止条件

如果达到最大代数MAX_GEN,算法终止,转到第(5)步;否则,重新初始化所有的蚂蚁的Delt矩阵所有元素初始化为0,Tabu表清空,Allowed表中加入所有的城市节点。随机选择它们的起始位置(也可以人工指定)。在Tabu中加入起始节点,Allowed中去掉该起始节点,重复执行(2),(3),(4)步。

(5)输出最优值

java 代码实现

//创建一个蚂蚁类 Ant.java
public class Ant {private List<Integer> route = new ArrayList<Integer>(); //路线:记录蚂蚁行走的路线private Integer currentCity; //当前城市:记录蚂蚁当前所在城市的IDprivate List<Integer> citys = new ArrayList<Integer>(); //城市:记录需要行走的城市IDprivate double[][] pheromoneMatrix; //信息素矩阵private int[][] distanceMatrix; //距离矩阵(整型方便查看)//构造器public Ant(List<Integer> citys, double[][] pheromoneMatrix, int[][] distanceMatrix) {this.citys = citys;this.pheromoneMatrix = pheromoneMatrix;this.distanceMatrix = distanceMatrix;}/*** 添加路线* @param cityId*/private void addRoute(Integer cityId) {route.add(cityId); //路线中添加城市IDcurrentCity = cityId; //当前城市修改为城市IDcitys.remove(cityId); //需要行走的城市移除当前城市ID}/*** 随机选择初始城市*/private void randomSelectCity() {Random random = new Random();Integer cityId = random.nextInt(citys.size())+1;addRoute(cityId);}/*** 选择下一个城市*/private void selectNextCity() {if(citys.size() == 1) {addRoute(citys.get(0));addRoute(route.get(0)); //路线添加最开始的城市return;}Double alpha = 1.0; //信息素因子权重Double beta  = 2.0; //路线距离权重Map<Integer, Double> molecules = new HashMap<Integer, Double>();//计算选路概率公式中的分子for (Integer city : citys) {//城市从1开始数,数组从0开始数,所以涉及数组都要‘-1’Double molecule = Math.pow(pheromoneMatrix[currentCity-1][city-1], alpha) * Math.pow(1.0 / distanceMatrix[currentCity-1][city-1], beta);molecules.put(city, molecule);}//计算选路概率公式中的分母Double totalMolecule = 0.0;for(Integer city : molecules.keySet()) {totalMolecule += molecules.get(city);}//轮盘赌选择下一个城市double random = Math.random();Double temp = 0.0;for(Integer city : molecules.keySet()) {temp += molecules.get(city) / totalMolecule;if(temp >= random) {addRoute(city);break;}}}/*** 蚂蚁开始旅行所有城市*/public void tour() {int cityQuantity = citys.size();randomSelectCity();for(int i=0; i<cityQuantity; i++) {selectNextCity();}}/*** 获取路线* @return*/public List<Integer> getRoute() {return route;}/*** 计算路线总距离* @return*/public Integer getRouteLength() {Integer length = 0;for(int i=0; i<route.size()-1; i++) {length += distanceMatrix[route.get(i)-1][route.get(i+1)-1];}return length;}
}
//创建一个AOC类:是蚁群优化算法主要实现类
public class ACO {List<Integer> citys = new ArrayList<Integer>(); //城市集合private double[][] pheromoneMatrix; //信息素矩阵private int[][] distanceMatrix; //距离矩阵private int times; //运行次数private int antQuantity; // 蚂蚁数量private List<Integer> bestRoute; //最佳路线private Integer bestLength = -1; //最佳距离//构造器public ACO(List<Integer> citys, double[][] pheromoneMatrix, int[][] distanceMatrix, int times, int antQuantity) {this.citys = citys;this.pheromoneMatrix = pheromoneMatrix;this.distanceMatrix = distanceMatrix;this.times = times;this.antQuantity = antQuantity;}/*** 更新信息素* @param ants 蚂蚁群*/private void update(List<Ant> ants) {//信息素挥发double volatilizationRate = 0.5; //挥发率for(int i=0; i<citys.size(); i++) {for(int j=0; j<citys.size(); j++) {pheromoneMatrix[i][j] = pheromoneMatrix[i][j] * (1.0-volatilizationRate);}}//信息素新增for(Ant ant : ants) {List<Integer> route = ant.getRoute();for(int i=0; i<route.size()-1; i++){pheromoneMatrix[route.get(i)-1][route.get(i+1)-1] += 1.0 / ant.getRouteLength();}}}/*** 记录最佳路径和最佳距离*/private void recordBest(List<Ant> ants) {//给bestLength赋予初始值if(bestLength == -1.0) {bestLength = ants.get(0).getRouteLength();bestRoute = ants.get(0).getRoute();}//遍历比较最佳for(Ant ant : ants) {if(bestLength > ant.getRouteLength()) {bestLength = ant.getRouteLength();bestRoute = ant.getRoute();}}}/*** 运行蚁群优化算法*/private void runAlgorithm(){//创建蚂蚁集合存储蚂蚁List<Ant> ants = new ArrayList<Ant>();for(int i=0; i<antQuantity; i++){//复制城市集合(集合为地址引用,为了不影响原参数,复制一个新集合)List<Integer> cityCopy = new ArrayList<Integer>();for (Integer city : citys) {cityCopy.add(city);}//创建蚂蚁,并开始旅行所有城市Ant ant = new Ant(cityCopy, pheromoneMatrix, distanceMatrix);ant.tour();ants.add(ant);}update(ants); //更新信息素recordBest(ants); //记录最佳路线与距离}/*** 多次运行蚁群优化算法(蚂蚁算法的运行入口)*/public void run() {for(int i=0; i<times; i++){runAlgorithm();}}/*** 获取最佳路线*/public List<Integer> getBestRoute() {return bestRoute;}/*** 获取最佳距离*/public Integer getBestLength() {return bestLength;}
}
  • 针对TSP问题的蚂蚁优化算法就写好了,只要创建AOC,传入对应的参数,运行run()方法就会跑起来,通过getXxxx获取路线以及路线长度
//主程序代码演示
public class Main {public static void main(String[] args) {//自定义距离矩阵int[][] distanceMatrix = new int[][]{{0, 1, 3, 1}, {1, 0, 3, 2}, {3, 3, 0, 2}, {1, 2, 2, 0}};//创建信息素矩阵并赋初值double[][] pheromoneMatrix = new double[4][4];for(int i=0; i<distanceMatrix.length; i++) {for(int j=0; j<distanceMatrix.length; j++) {pheromoneMatrix[i][j] = 0.1;}}//创建城市集合List<Integer> citys = new ArrayList<Integer>();for(int i=0; i<4; i++) {citys.add(i+1);}//运行蚁群优化算法ACO aco = new ACO(citys, pheromoneMatrix, distanceMatrix, 50, 6);aco.run();System.out.println(aco.getBestRoute());System.out.println(aco.getBestLength());}
}
2.3 自定义工具类
  • 由于自己定义距离矩阵,信息素矩阵觉得麻烦,就创建一个工具类实现创建

  • (1)将城市信息存储在一个txt文件中

    • 城市ID X轴 Y轴

1 6734 1453
2 2233 10
3 5530 1424
4 401 841
5 3082 1644
6 7608 4458
7 7573 3716
8 7265 1268
9 6898 1885
10 1112 2049
11 5468 2606
12 5989 2873
13 4706 2674
14 4612 2035
15 6347 2683
16 6107 669
17 7611 5184
18 7462 3590
19 7732 4723
20 5900 3561
21 4483 3369
22 6101 1110
23 5199 2182
24 1633 2809
25 4307 2322
26 675 1006
27 7555 4819
28 7541 3981
29 3177 756
30 7352 4506
31 7545 2801
32 3245 3305
33 6426 3173
34 4608 1198
35 23 2216
36 7248 3779
37 7762 4595
38 7392 2244
39 3484 2829
40 6271 2135
41 4985 140
42 1916 1569
43 7280 4899
44 7509 3239
45 10 2676
46 6807 2993
47 5185 3258
48 3023 1942
  • (2)创建工具类来读取txt信息
public class Utils {/*** 读取文件内容,将每一行文本封装为字符串集合* @return* @throws Exception*/private static List<String> readFile(){//文件路径,按照自己情况进行修改String filePath = "D://data//position.txt";List<String> texts = null;BufferedReader br = null;//异常处理try {br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath))); //创建读取文件流texts = new ArrayList<String>(); //创建集合存储字符串while(true) {String text = br.readLine();if(text == null) { //直到下一行没有内容,退出循环break;}texts.add(text);}} catch (IOException e) {e.printStackTrace();} finally {try {br.close();} catch (IOException e) {e.printStackTrace();}}return texts;}/*** 创建城市Id集合* @return*/public static List<Integer> getCitys() {Integer cityQuantity = Integer.valueOf(readFile().get(0));List<Integer> citys = new ArrayList<Integer>();for(int i=0; i<cityQuantity; i++) {citys.add(i+1);}return citys;}/*** 创建距离矩阵* @return*/public static int[][] getDistanceMatrix() {List<String> texts = readFile();Integer cityQuantity = Integer.valueOf(texts.get(0));int[][] distanceMatrix = new int[cityQuantity][cityQuantity];for(int i=0; i<cityQuantity; i++) {distanceMatrix[i][i] = 0;for (int j=i+1; j<cityQuantity; j++) {//按空格分割字符串String[] city1 = texts.get(i + 1).split(" ");String[] city2 = texts.get(j + 1).split(" ");//两点距离公式(整数方便查看)double distance = Math.pow((Integer.valueOf(city1[1]) - Integer.valueOf(city2[1])), 2) + Math.pow((Integer.valueOf(city1[2]) - Integer.valueOf(city2[2])), 2);distanceMatrix[i][j] = (int) Math.sqrt(distance);distanceMatrix[j][i] = distanceMatrix[i][j];}}return distanceMatrix;}/*** 初始化信息素矩阵* @param value 初始值* @return*/public static double[][] getPheromoneMatrix(double value) {Integer cityQuantity = Integer.valueOf(readFile().get(0));double[][] pheromoneMatrix = new double[cityQuantity][cityQuantity];for(int i=0; i<cityQuantity; i++) {for(int j=0; j<cityQuantity; j++) {pheromoneMatrix[i][j] = value; //赋予初始信息素值}}return pheromoneMatrix;}
}
  • (3)通过使用工具类的主程序
public class Main {public static void main(String[] args) {List<Integer> citys = Utils.getCitys(); //城市集合double[][] pheromoneMatrix = Utils.getPheromoneMatrix(1.0); //信息素矩阵int[][] distanceMatrix = Utils.getDistanceMatrix(); //距离矩阵ACO aco = new ACO(citys, pheromoneMatrix, distanceMatrix, 150, 72);aco.run();System.out.println(aco.getBestRoute());System.out.println(aco.getBestLength());}
}

运行结果:

// 获取最佳路线
[25, 14, 23, 11, 12, 15, 40, 9, 1, 8, 38, 31, 44, 18, 7, 28, 36, 30, 6, 37, 19, 27, 43, 17, 46, 33, 20, 47, 21, 13, 3, 22, 16, 41, 34, 5, 48, 29, 2, 42, 10, 26, 4, 35, 45, 24, 32, 39, 25]
//获取最佳距离
35700

这篇关于AGV小车、机械臂协同作业实战06-任务分配算法(图解蚁群算法)代码示例java的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/653011

相关文章

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll

Java中的工具类命名方法

《Java中的工具类命名方法》:本文主要介绍Java中的工具类究竟如何命名,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java中的工具类究竟如何命名?先来几个例子几种命名方式的比较到底如何命名 ?总结Java中的工具类究竟如何命名?先来几个例子JD

Java Stream流使用案例深入详解

《JavaStream流使用案例深入详解》:本文主要介绍JavaStream流使用案例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录前言1. Lambda1.1 语法1.2 没参数只有一条语句或者多条语句1.3 一个参数只有一条语句或者多

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依

SpringBoot整合OpenFeign的完整指南

《SpringBoot整合OpenFeign的完整指南》OpenFeign是由Netflix开发的一个声明式Web服务客户端,它使得编写HTTP客户端变得更加简单,本文为大家介绍了SpringBoot... 目录什么是OpenFeign环境准备创建 Spring Boot 项目添加依赖启用 OpenFeig

Java Spring 中 @PostConstruct 注解使用原理及常见场景

《JavaSpring中@PostConstruct注解使用原理及常见场景》在JavaSpring中,@PostConstruct注解是一个非常实用的功能,它允许开发者在Spring容器完全初... 目录一、@PostConstruct 注解概述二、@PostConstruct 注解的基本使用2.1 基本代

springboot使用Scheduling实现动态增删启停定时任务教程

《springboot使用Scheduling实现动态增删启停定时任务教程》:本文主要介绍springboot使用Scheduling实现动态增删启停定时任务教程,具有很好的参考价值,希望对大家有... 目录1、配置定时任务需要的线程池2、创建ScheduledFuture的包装类3、注册定时任务,增加、删

SpringBoot整合mybatisPlus实现批量插入并获取ID详解

《SpringBoot整合mybatisPlus实现批量插入并获取ID详解》这篇文章主要为大家详细介绍了SpringBoot如何整合mybatisPlus实现批量插入并获取ID,文中的示例代码讲解详细... 目录【1】saveBATch(一万条数据总耗时:2478ms)【2】集合方式foreach(一万条数