Jason Pekos

General strategy:

Consider a graph, e.g.

In general, we're going to use the :circular method for displaying graphs. This is because the other methods, e.g. :stress are stochastic, and they mess up the hack we're using to visualize walks on graphs. So the above graph changes to:

This looks a little odd, but it's still the same graph we looked at yesterday. We can easily sample a random walk on this graph from a fixed starting point, e.g. a random walk of length 4 is shown below:

We're going to sample a random walk of length n for n large, e.g. 100000100'000 or whatever. From this, we're going to get out a vector of visited nodes, e.g. [1 2 3 2 1 ...]. We're going to loop over this vector, returning every primitive even walk that is a subset of this larger walk. Explicitly:

function extractevenwalks(walk::Vector{Int64})
    # This set will store all of our simple even walks. 
    finalset = Set()
    # This set is used for validation because I'm lazy
    validation = Set()

    # Loop over every node in the walk, except for the last one
    for (i1, v1) in enumerate(walk[1:end-1])

        # Wipe set we use to store edges
        edges = Set()

        # For every node, loop over every node after that node in the walk. 
        for (i2, v2) in enumerate(walk[i1 + 1:end])

            # record edge
            edge = Set([walk[i1 + i2 - 1], walk[i1 + i2]])

            # If we've already traversed along this edge, break.
            if edge ∈ edges
                break;
            else
                push!(edges, edge)
            end

            # Check if we've completed a loop.
            if v1 == v2

                # Propose this as a candidate.
                candidate = walk[i1:i2 + i1]

                # If it's even, continue. 
                if length(candidate) % 2 != 0
                    # If it's new, add it to our set
                    if Set(candidate[1:end-1]) ∈ validation
                        break
                    else
                        push!(finalset, candidate)
                        push!(validation, Set(candidate[1:end-1]))
                    end
                    break;
                end
            end
        end
    end
    # Return our set of walks
    return finalset
end

This code doesn't accept walks which traverse back along edges we've already visited. We can test this out on the above graph with a walk of length 40:

n = 40000
rw = randomwalk(simple_graph_1, 1, n) # start at node 1, walk of length n
ewset = extractevenwalks(rw) = Set(Any[[1, 3, 4, 5, 3, 2, 1]])

Which can be plotted as:

Which is the desired result.

JasonPekos. Last modified: July 22, 2024. Website built with Franklin.jl.