蚁群算法及蚂蚁系统的原理(js实现版)
蚁群算法
蚁群算法是著名的启发式算法,常用于解决最短路径问题
蚁群算法的来源
蚁群算法来源于对蚂蚁寻找食物行为的观察,蚂蚁个体并不存在太高的智慧,但蚁群整体却可以通过信息素来找到通往食物的最短路径
蚁群算法的原理
假设从a点到b点存在2条路径,而第一条路径l短,第二条路径m长。
刚开始时走l和m是随机的,但是由于l更短,所以重复频率也就更高,而留下的信息素浓度也就更高。
最终,大部分蚂蚁都会走l而不走m,这样也就是找到了最短路径。
旅行商问题
假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。路径的选择目标是要求得的路径路程为所有路径之中的最小值。这就是TSP,属于NPC问题。
使用图论来描述TSP问题
已知有n个点的完全图,每条边都有一个长度,求总长度最短的经过每个顶点正好一次的封闭回路
蚁群系统
蚁群系统
蚁群系统是第一个满足蚁群算法框架的算法
使用蚁群系统来解决TSP问题,其伪代码如下
function AntSystem () {
Init()// 初始化 蚂蚁、图、信息素
while(!isConvergence()) {
// 如果未收敛或不满足其他停止条件则继续
ContructSolution()// 对每个蚂蚁构造解
PheromoneUpdate()// 信息素更新
}
}
初始化
1.初始化节点与路径,并根据节点与路径生成图
2.初始化信息素,每条路径上的信息素都相等
3.随机化蚂蚁,使其分布于某一节点中,也可以不使用随机化。每个蚂蚁都会存储走过的路径与剩下可走的路径
蚂蚁抉择
对于每个蚂蚁,会从接下来可走的路径中进行选择,选择按照概率进行。
选择其中一条路径的计算公式为
p = 所选路径信息素*能见度 / 求和(每个路径的信息素*每个路径的能见度)
其中能见度为:
能见度 = 1/路径距离
选择其中一条路径后将该路径从未走路径加入到已走路径
信息素更新
在每个蚂蚁都走完后将更新信息素
每个路径上的信息素 = 原信息素*信息素挥发率 + 求和(1/每个经过该路径上的蚂蚁其行走总路径长度)
其中的信息素挥发率为0到1之间的常数,如果过低则难以收敛,过高则容易陷入局部最优解
终止条件
如果某一路径信息素要明显大于其余所有边的信息素的和则可以认定该路径满足收敛条件。
如果循环的次数超出最大则判断收敛失败。
代码实现
生成图代码
function Graph() {
}
Graph.prototype.setNode = (nodeArr, nodeMatrix) => {
this.nodeArr = nodeArr;
// 邻接矩阵
// 矩阵中为null则代表该方向没有边
this.nodeMatrix = nodeMatrix;
};
Graph.prototype.setValue = (start, end, value) => {
const startNodeIndex = getNodeIndex(start, this.nodeArr);
const endNodeIndex = getNodeIndex(end, this.nodeArr);
if (startNodeIndex === -1 || endNodeIndex === -1) return;
this.nodeMatrix[startNodeIndex][endNodeIndex] = value;
};
Graph.prototype.getValue = (start, end) => {
const startNodeIndex = getNodeIndex(start, this.nodeArr);
const endNodeIndex = getNodeIndex(end, this.nodeArr);
if (startNodeIndex === -1 || endNodeIndex === -1) {
debugger
return;
}
return this.nodeMatrix[startNodeIndex][endNodeIndex];
};
Graph.prototype.addValue = (start, end, value) => {
const startNodeIndex = getNodeIndex(start, this.nodeArr);
const endNodeIndex