我开发了一个aco算法。我认为它不能正常工作......很难解释,但我会尝试。
问题是信息素水平是浮动的。我假设,最佳路径上的信息素水平必须越来越高,但在我的程序中它不是。
Optimal path
是一条路径,它是通过在起始顶点和目标顶点之间的边缘上找到最大信息素水平而构建的。
示例:
1 5 3
4 5 10
0 0 0
Optimal path
将为1 -> 2 -> 3
。
重量矩阵:
0 3 10
0 0 3
0 0 0
最佳途径是:1 -> 2 -> 3 (length: 6)
另一条路径(非最佳):1 -> 3 (length: 10)
10只蚂蚁后的信息素水平:
0 5 1
0 0 3
0 0 0
最佳路径:1 -> 2 -> 3
20只蚂蚁(10只以上)后的信息素水平:
0 1 5
0 0 1
0 0 0
最佳路径:1 -> 3
30只蚂蚁后的信息素水平:
0 4 1
0 0 3
0 0 0
最佳路径:1 -> 2 -> 3
30只蚂蚁后的信息素水平:
0 4 6
0 0 2
0 0 0
最佳路径:1 -> 3
这只是一个例子,但它代表了程序中信息素矩阵的样子。
我的程序的伪代码:
init alpha, beta and other coef's
while antCount do
{
current = start
// + init visited array for current ant, some others variables
while vertexAvailable(current) do
{
find probabilities to go to 1
or another vertex
generate random number, choose next
vertex depending on it,
defining nextVertex
current = nextVertex
if current == stop then
{
get path length
update pheromones on path of current
ant depending on path length
}
}
evaporation of pheromones
antCount = antCount - 1
}
那么,为什么程序中的信息素水平会浮动?为什么最好的路径没有最多的信息素水平?我知道这个算法中存在概率因子,但无论如何它必须显示正确的结果。
我在节目中做了什么? Here你可以找到我程序的完整主循环源。
1)Main cycle是一个循环,直到有任何蚂蚁可用于当前迭代。
1.1)在这个循环中我有another cycle(内循环),它将被触发,直到当前的蚂蚁有顶点去它们(当前蚂蚁不能访问顶点)。
在内循环中,我这样做:
1.1.1)Calculating denominator of the equation below
此公式将计算选择ij
路径的概率(i
是当前节点,j
是下一个节点。)
代码:
var denom = 0;
for(col in graph[currentVertex])
{
// этот цикл формирует знаменатель формулы
var weight = graph[currentVertex][col];
if(weight != 0 && visited[col] != true)
{
var tau = pheromone[currentVertex][col];
denom = denom + getAttractiveness(tau, weight);
}
}
此外,我将所有概率添加到一个区间,这将帮助我决定选择哪个顶点。
代码:
for(col in graph[currentVertex])
{
var weight = graph[currentVertex][col];
if(weight != 0 && visited[col] != true)
{
var tau = pheromone[currentVertex][col];
var nom = getAttractiveness(tau, weight);
var probability = nom/denom;
intervals[col] = probability+intervals.last;
intervals.last = probability+intervals.last;
}
}
代码:
var rand = Math.random();
var nextVertex = 0;
for(vertex in intervals)
{
if (rand < intervals[vertex])
{
nextVertex = parseInt(vertex,10);
break;
}
}
1.1.4)Some instructions, setting helpers (path helper, visited helped) etc
1.1.5)Next step, I am checking if founded vertex is goal vertex
如果是(这意味着,蚂蚁找到了目标顶点)我这样做:
1.1.5.1)Getting length of current ant path
代码:
var length = 0;
while(source = pathCopy.pop())
{
console.log("dest: " + dest + " source: " + source);
length = length + graph[source][dest];
dest = source;
}
1.1.5.2)Updating pheromone level on this path
代码:
var deltaTau = 5/length;
var dest = path.pop();
var source;
while(source = path.pop())
{
var oldPheromone = pheromone[source][dest];
// обновление феромона формула 3
var newPheromone = oldPheromone+deltaTau;
// console.log('pheromone levels: old =
// '+oldPheromone+' new = ' + newPheromone);
pheromone[source][dest] = newPheromone;
dest = source;
}
1.2)At the end of main cycle I am doing evaporation of pheromone levels:
代码:
for(row in pheromone)
{
for(col in pheromone[row])
{
var oldPheromone = pheromone[row][col];
// обновление феромона формула 3
var newPheromone = (1-ktau)*oldPheromone;
pheromone[row][col] = newPheromone;
}
}
答案 0 :(得分:4)
选择跟随路径时,代码始终选择随机阈值以下的第一个相邻顶点。我不确定这应该如何代表蚂蚁走向具有更多信息素的顶点。该方法将在信息素浓度相对较低(低于0.5)的区域中起作用。但是,<信息>在信息素浓度高(接近或高于1)的区域,因为您的random()
数字介于0和1之间,您将返回始终选择第一个可用信息素顶点即可。这可能就是你不收敛的原因。