Rand not being random?

Hey all,

I’m trying to do Ant Colony Optimization in Julia, and I’ve run into a problem that when using rand I always get the lowest value possible.
Most part of the function isn’t important I just didn’t want it to leave out.

Using Random

function selectNextNode(ant, possiblePaths, graph, pheoromoneExponent, desirabilityExponent)
    sum = 0
    probabilities = Float64[]
    for possibleNode in possiblePaths
        sum += (((graph.pheromoneMatrix[ant.currentLocation, possibleNode]) ^ pheromoneExponent) * (1/ graph.adjMatrix[ant.currentLocation, possibleNode]) ^ desirabilityExponent)
        push!(probabilities, ((graph.pheromoneMatrix[ant.currentLocation, possibleNode]) ^ pheromoneExponent ) * (1/graph.adjMatrix[ant.currentLocation, possibleNode]) ^ desirabilityExponent)
    rnd = rand(0:sum)
    println("Random number between 0 and $sum is $rnd")
    for i in 1:length(possiblePaths)
        if(rnd < probabilities[i])
            return possiblePaths[i]
        rnd -= probabilities[i]

How it looks when I compile it

Any suggestion what I did wrong?

The range object 0:sum creates an iterator that returns 0, 0+1, 0+2, etc., until it reaches a value greater than sum. Since sum is always less than 1 it will only return 0.


The trouble is that rand(S) returns a random element of the set S, and the set S you’re providing has only the element 0.0. For example, 0:0.3 is the set of Float64’s between 0.0 and 0.3 in default steps of 1.0. So 0:0.3 has only one element, 0.0.

Instead, use rnd = sum*rand(). The rand() will be a random Float64 between 0.0 and 1.0, which is then scaled to 0.0 to sum by the multiplication.

help?> rand(S)
  rand([rng=GLOBAL_RNG], [S], [dims...])

  Pick a random element or array of random elements from the set of values specified by S; S can be

    •  an indexable collection (for example 1:9 or ('x', "y", :z)),

    •  an AbstractDict or AbstractSet object,

    •  a string (considered as a collection of characters), or

    •  a type: the set of values to pick from is then equivalent to typemin(S):typemax(S) for integers (this is not applicable to BigInt), to
       [0, 1) for floating point numbers and to [0, 1)+i[0, 1) for complex floating point numbers;

  S defaults to Float64. When only one argument is passed besides the optional rng and is a Tuple, it is interpreted as a collection of values (S)
  and not as dims.
1 Like

Incidentally, I would advise against using common base function names as variable identifiers to prevent these types of problems:

julia> sum = 0

julia> sum([1, 2, 3])
ERROR: MethodError: objects of type Int64 are not callable
Maybe you forgot to use an operator such as *, ^, %, / etc. ?
 [1] top-level scope
   @ REPL[2]:1
1 Like