In [1]:
using Distributed
In [2]:
if procs() == workers()
    addprocs(4)
end
Out[2]:
4-element Vector{Int64}:
 2
 3
 4
 5
In [3]:
@everywhere function visited(city,hops,path)
    for i = 1:hops
        if path[i] == city
            return true
        end
    end
    return false
end
In [4]:
function tsp_serial_impl(connections,hops,path,current_distance,min_distance)
    num_cities = length(connections)
    if hops == num_cities
        if current_distance < min_distance
            return current_distance
        end
    else
        current_city = path[hops]
        next_hops = hops + 1
        for (next_city,distance_increment) in connections[current_city]
            if !visited(next_city,hops,path)
                path[next_hops] = next_city
                next_distance = current_distance + distance_increment
                if next_distance < min_distance
                    return tsp_serial_impl(connections,next_hops,path,next_distance,min_distance)
                end
            end
        end        
    end
    min_distance
end
Out[4]:
tsp_serial_impl (generic function with 1 method)
In [5]:
function tsp_serial(connections,city)
    num_cities = length(connections)
    path=zeros(Int,num_cities)
    hops = 1
    path[hops] = city
    current_distance = 0
    min_distance = typemax(Int)
    min_distance = tsp_serial_impl(connections,hops,path,current_distance,min_distance)
    (;path=path,distance=min_distance)
end
Out[5]:
tsp_serial (generic function with 1 method)
In [6]:
connections = [
    [(1,0),(4,39),(5,76), (6,78),(3,94),(2,97)],
    [(2,0),(5,25),(4,58),(3,62),(1,97),(6,109)],
    [(3,0),(6,58),(2,62),(4,68),(5,70),(1,94)],
    [(4,0),(5,38),(1,39),(2,58),(3,68),(6,78)],
    [(5,0),(2,25),(4,38),(3,70),(1,76),(6,104)],
    [(6,0),(3,58),(1,78),(4,78),(5,104),(2,109)]
]
city = 1
tsp_serial(connections,city)
Out[6]:
(path = [1, 4, 5, 2, 3, 6], distance = 222)
In [ ]:
@everywhere function tsp_dist_impl(connections,hops,path,current_distance,min_distance,max_hops,jobs_chnl,ftr_result)
    num_cities = length(connections)
    if hops == num_cities
        if current_distance < min_distance
            if ftr_result !== nothing
                @spawnat 1 begin
                    result = fetch(ftr_result)
                    result.path .= path
                    result.min_distance_ref[] = current_distance
                end |> wait
            end
            return current_distance
        end
    elseif hops <= max_hops
        current_city = path[hops]
        next_hops = hops + 1
        for (next_city,distance_increment) in connections[current_city]
            if !visited(next_city,hops,path)
                path[next_hops] = next_city
                next_distance = current_distance + distance_increment
                if next_distance < min_distance
                    return tsp_dist_impl(connections,next_hops,path,next_distance,min_distance,max_hops,jobs_chnl,ftr_result)
                end
            end
        end 
    else
        if jobs_channel !== nothing
            put!(jobs_chnl,(;hops,path,current_distance))
        end
    end
    min_distance
end

function tsp_dist(connections,city)
    max_hops = 2
    num_cities = length(connections)
    path=zeros(Int,num_cities)
    hops = 1
    path[hops] = city
    current_distance = 0
    min_distance = typemax(Int)
    jobs_chnl = RemoteChannel(()->Channel{Any}(10))
    ftr_result = @spawnat 1 (;path,min_distance_ref=Ref(min_distance))
    task = @async begin
        tsp_dist_impl(connections,hops,path,current_distance,min_distance,max_hops,jobs_chnl,nothing)
        for w in workers()
            put!(job_chnl,nothing)
        end
    end
    @sync for w in workers()
        @spawnat w begin
            max_hops = typemax(Int)
            jobs_channel = nothing
            while true
                job = take!(jobs_chnl)
                if job == nothing
                    break
                end
                hobs = job.hobs
                path = job.path
                current_distance = job.current_distance
                tsp_dist_impl(connections,hops,path,current_distance,min_distance,max_hops,jobs_chnl,ftr_result)
            end
        end
    end 
    (;path=path,distance=min_distance)
end
city = 1
tsp_dist(connections,city)
In [ ]: