8

I developed an aco algorithm. I think it is not working properly... it will be hard to explain, but I will try.

The problem is pheromone level is floating. I assume, that pheromone level on the best path must be increased more and more, but in my programm it is not.

Optimal path is a path, which is built by finding maximum pheromone level on edges between start vertex and goal vertex.

Example:

1 5 3
4 5 10
0 0 0

Optimal path will be 1 -> 2 -> 3.

Weight matrix:

 0 3 10
 0 0 3
 0 0 0

Best path is: 1 -> 2 -> 3 (length: 6) Another path (not optimal): 1 -> 3 (length: 10)


Pheromone levels after 10 ants:

0 5 1 
0 0 3
0 0 0

Optimal path: 1 -> 2 -> 3


Pheromone levels after 20 ants (10 more):

0 1 5 
0 0 1
0 0 0

Optimal path: 1 -> 3


Pheromone levels after 30 ants:

0 4 1 
0 0 3
0 0 0

Optimal path: 1 -> 2 -> 3


Pheromone levels after 30 ants:

0 4 6 
0 0 2
0 0 0

Optimal path: 1 -> 3

This is just an example, but it represents what the pheromones matrix in my program look like.


Pseudocode of my programm:

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
}

So, why are pheromone levels in my program floating? Why doesn't the best path have most pheromone levels? I understand that there is probability factor in this algorithm, but it have to show correct result anyway.


What I am doing in my program? Here you can find full main loop source of my program.

1) Main cycle is a cycle, which will until there are any ants available for current iteration.

1.1) In this cycle I have another cycle (inner cycle), which will be fired until current ant have vertexes to go to them (vertexes mustn't be visited by current ant).

In inner cycle I do this:

1.1.1) Calculating denominator of the equation below

main formula

This formula will calculate probability of selecting ij path (i is current node, j is next node).

Code:

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);
    }
}

1.1.2) Calculating numerator of the formula above and getting probability of selecting each vertex available from current

Also, there I adding all probabilites to an interval, which will help me to decide what vertex to choose.

Code:

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;
    }
}

1.1.3) Creating random number from 0 to 1 and selecting vertex based on intervals array, defined in previous part of the code

Code:

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

If yes (that means, that ant found goal vertex) I am doing this:

1.1.5.1) Getting length of current ant path

Code:

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

Code:

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:

Code:

for(row in pheromone)
{
    for(col in pheromone[row])
    {
        var oldPheromone = pheromone[row][col];

        // обновление феромона формула 3
        var newPheromone = (1-ktau)*oldPheromone;

        pheromone[row][col] = newPheromone;
    }
}
Kyte
  • 834
  • 2
  • 12
  • 27
Sharikov Vladislav
  • 7,049
  • 9
  • 50
  • 87
  • 8
    You clearly know what you're doing, but *in this question* you've jumped right into the middle of your detailed problem and I suspect very few people are going to take the time to get up to speed with what you're doing. You might find [the hints here](http://tinyurl.com/so-hints) useful - in particular, the **Sample code and data** section. I bet if you reduce your problem to a minimal reproducible example, you'll solve it yourself... – AakashM May 14 '14 at 08:01
  • 1
    @AakashM Thank you for your answer! I red article about how to write good question few times. I understand that you said, thats why I am asking if somebody knows factors that can cause my problem. I understand, that it **nobody** will spend more then 5 minutes to my question :) But same for me: I am wasting time reviewing this code and it looks like working one. What about sample data... it depends. I am not sure in what part of code I have error, so just give all code of aco (I tried to remove initializations etc). – Sharikov Vladislav May 14 '14 at 09:35
  • @AakashM First of all, I wanted people to notice, screenshots of pheromones matrix. – Sharikov Vladislav May 14 '14 at 09:38
  • @SharikovVladislav You're getting float-point in the matrix because of float-point division of indivisible numbers and then these float-point numbers are used to calculate what goes in the matrix, `var probability = nom/denom;` and `var deltaTau = 1/length;` – Khaled.K May 22 '14 at 05:14
  • @KhaledAKhunaifer wait I am not asking about it :) I am asking why pheromones of the best matrix are not maximizing :) – Sharikov Vladislav May 22 '14 at 07:05
  • @SharikovVladislav Fix your question to be clearer, also add info how matrix maximization is related to pheromone matrix – Khaled.K May 22 '14 at 08:05
  • What exactly is not clarified? If I will simplify it it will be simplified too much. Sure, I may fail with english translation... With what part you got problems? Floating? Float not means only `float` type or value ([click me](http://www.oxforddictionaries.com/definition/english/float)) – Sharikov Vladislav May 22 '14 at 08:27
  • @SharikovVladislav you are paradoxical, you provided how using terms loosely can make your post ambiguous. Before you reply to this, read your last comment well – Khaled.K May 22 '14 at 09:54
  • @Khaled I updated my question. Is it more clearer now? – Sharikov Vladislav May 22 '14 at 14:14
  • I'm getting lost pretty early in your question. When you give a matrix, and then say "Selected path is 1->2->3" (or "1->3"), what does that mean? – Teepeemm May 22 '14 at 15:56
  • @Teepeemm I said about it: "`Selected path` is a path, which is build by finding maximum pheromone level on edges between start vertex and goal vertex." – Sharikov Vladislav May 22 '14 at 15:59
  • @Teepeemm Updated again. Now it is called `optimal path`. It is path, which is founded by finding edges with maximum pheromone level between start vertex and goal vertex. – Sharikov Vladislav May 22 '14 at 16:01
  • I'm still having trouble. I'm envisioning your matrix as laying on a table, and ants walking across it. Each number represents the strength of the pheromone at that location. Is that correct? If so, a path should be coordinates that get me through the matrix. "1->2->3" could be interpreted as a sequence of pheromone values, which would not define the path but probably give enough information to reconstruct it. But that doesn't appear to be the case, because 1, 2, and 3 don't occur in that sequence in your matrices, and you only ever have 1->2->3 or 1->3 as your paths. – Teepeemm May 22 '14 at 16:07
  • @Teepeemm Nope. Pheromone matrix MxN (as weigh matrix with weights) represents pheromone level from 1 edge to another edge. First line is from 1 to 1, from 1 to 2, from 1 to 3. Second line is from 2 to 1, from 2 to 2, from 2 to 3 etc. Weights matrix represent what weight is between 1 and 2, 1 and 3 etc... – Sharikov Vladislav May 22 '14 at 16:11
  • @Teepeemm to build optimal path, using matrix you have to know what is start path. In example (1st matrix) start is 1 vertex (start will be 1). So we watching first line, finding max value in this line. For example it is 2nd value — that fact means, that 2nd vertex is 2. Now we are looking for max value in 2 line (2nd vertex). It is 3rd value. So last vertex is 3. [This functions](https://github.com/sharikovvladislav/aco/blob/master/algorithms.js#L261-L273) doing this. – Sharikov Vladislav May 22 '14 at 16:15
  • So you've got a directed graph on N vertices, which is represented by an NxN matrix, where the row i column j entry is the reward for going from i to j (and the diagonal entries should all be 0). At each vertex, the ant randomly chooses from all vertices in proportion to the weights. In your second example, why is 1->3 not optimal? In your last example, aren't 1->2->3 and 1->3 equally optimal? At a fundamental level, I'm having trouble seeing how your examples relate to your pseudocode relate to your code snippets. – Teepeemm May 22 '14 at 20:55
  • Do you know ant colony? Pheromones level is not weights. – Sharikov Vladislav May 22 '14 at 20:57
  • 1
    This sounds like it could be a very interesting question, if only I could make any sense of it. What I'm getting out of it is that you have an ant colony optimizer (for some problem, I'm not sure what; looks like shortest path on a small graph, but I might be wrong), it's not working as you expect, you've dumped a bunch of code snippets on us, and you suspect the bug *might* be in one of them. I'm sorry to say this, but I doubt you're going to get much useful help here unless you can turn you code into something a little closer to an [MCVE](http://stackoverflow.com/help/mcve). – Ilmari Karonen May 23 '14 at 12:42
  • @IlmariKaronen I am tired to repat it: I am not asking to find mistake in my code, I am trying to understand what can cause it? I am wrong in calc probabilities? Or I am wrong somewhere else? Now all ppl here wasn't talking about ACO, but about question style... How to simplify complicated problem? – Sharikov Vladislav May 23 '14 at 14:41
  • I know random walks very well, and got the idea of ACO after about five minutes on the Wikipedia article (yes, weights is the correct term). That being said, I’m rapidly losing interest in this question. You’ve pasted six code snippets and said something is wrong somewhere (but we don't need to find the mistake in your code?). Find the smallest number of vertices that reproduce this problem. After each code snippets, look all of your variables. Find where they first disagree with what they should be. That being said, your p_ij has `(t+1/w)` where Wikipedia has `t*1/w`. – Teepeemm May 24 '14 at 19:10
  • @Teepeem About formula: strange :) Yes, there is `+` in this formula, but I am using `*` :) – Sharikov Vladislav May 27 '14 at 19:44

1 Answers1

4

When picking the followed path, your code always select the first neighbouring vertex below a random threshold. I'm not sure how this is supposed to represent ants going towards vertices with more pheromone. This method will work to a degree in area where pheromone concentration is relatively low (below 0.5). However, in areas where pheromone concentration is high (near or above 1), because your random() number is between 0 and 1, you will be back to always picking the first available vertex. This is probably why you do not converge.

zeFrenchy
  • 6,541
  • 1
  • 27
  • 36
  • Thanks for your answer. Am I right, that we just build model of ant colony, not real colony? :) I am doing this: if ant found goal vertex, pheromones will be updated on path, which used ant to get to this path (you can see this [here](https://github.com/sharikovvladislav/aco/blob/master/algorithms1.js#L95-L99)), if ant doesn't found goal vertex, pheromone level on ant path wouldn't be increased. Pheromone will evaporate after each ant tried to found goal vertex. By this, I achieve that fact, that pheromone level is increased on path if using this path ant found food. Am I right? – Sharikov Vladislav May 22 '14 at 10:36
  • Pheromones will evaporate after each ant try to find vertex. Code is [here](https://github.com/sharikovvladislav/aco/blob/master/algorithms1.js#L105-L109). Do you meant this? – Sharikov Vladislav May 22 '14 at 10:40
  • I did not see the how pheromone is increased along the path. I'll be updating my answer accordingly. I think you need to explain better in your question how the next vertex selection works and how the probabilities are calculated. – zeFrenchy May 22 '14 at 10:49
  • It will be okay if I will explain in this way: "What I am doing after this — link to the git to the code"? Or should I copy do it here? – Sharikov Vladislav May 22 '14 at 10:58
  • @Sharikov ... little busy right now, will come back when I get time – zeFrenchy May 22 '14 at 12:34
  • Sure, no problems! I updated it again, all links are correct and code parts are looking correctly. – Sharikov Vladislav May 22 '14 at 14:12
  • is ther any things you can add? – Sharikov Vladislav May 26 '14 at 15:16
  • Not just now ... do you see what I mean regarding using random() for the selection threshold? once you have a saturated area of the matrix, you are no longer reinforcing the shortest path but just randomly picking. I think this is why you sort of converge but not completely. – zeFrenchy May 26 '14 at 15:36