mirror of
https://github.com/fverdugo/XM_40017.git
synced 2025-11-08 23:14:23 +01:00
Fix TSP serial and parallel implementation
This commit is contained in:
parent
aa26119f34
commit
1202cf41a9
117
notebooks/tsp-paralllel.jl
Normal file
117
notebooks/tsp-paralllel.jl
Normal file
@ -0,0 +1,117 @@
|
||||
using Distributed
|
||||
|
||||
if procs() == workers()
|
||||
addprocs(4)
|
||||
end
|
||||
|
||||
@everywhere function visited(city,hops,path)
|
||||
for i = 1:hops
|
||||
if path[i] == city
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
# solution [1, 4, 5, 2, 3, 6], distance = 222
|
||||
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)]
|
||||
]
|
||||
|
||||
# Shortest route with start 1: 1-3-2-4 (distance: 7)
|
||||
con2 = [
|
||||
[(1,0), (2,2), (3,3), (4,4)],
|
||||
[(2,0), (4,1), (1,2), (3,3)],
|
||||
[(3,0), (1,3), (2,3), (4,10)],
|
||||
[(4,0), (2,1), (1,4), (3,10)]
|
||||
]
|
||||
|
||||
|
||||
## TSP distributed
|
||||
@everywhere function tsp_dist_impl(connections,hops,path,current_distance,min_dist_chnl, max_hops,jobs_chnl,ftr_result)
|
||||
num_cities = length(connections)
|
||||
if hops == num_cities
|
||||
min_distance = fetch(min_dist_chnl)
|
||||
if current_distance < min_distance
|
||||
take!(min_dist_chnl)
|
||||
# Wait until results are written to future
|
||||
if ftr_result !== nothing
|
||||
@spawnat 1 begin
|
||||
result = fetch(ftr_result)
|
||||
result.path .= path
|
||||
result.min_distance_ref[] = current_distance
|
||||
end |> wait
|
||||
end
|
||||
# Unblock waiting processes
|
||||
put!(min_dist_chnl, 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
|
||||
min_distance = fetch(min_dist_chnl)
|
||||
if next_distance < min_distance
|
||||
tsp_dist_impl(connections,next_hops,path,next_distance,min_dist_chnl,max_hops,jobs_chnl,ftr_result)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if jobs_chnl !== nothing
|
||||
# Allocate new memory so paths are not overwritten in queue
|
||||
path_copy = copy(path)
|
||||
put!(jobs_chnl,(;hops,path=path_copy,current_distance))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function tsp_dist(connections,city)
|
||||
max_hops = 2
|
||||
num_cities = length(connections)
|
||||
path=zeros(Int,num_cities)
|
||||
result_path=zeros(Int, num_cities)
|
||||
hops = 1
|
||||
path[hops] = city
|
||||
current_distance = 0
|
||||
min_distance = typemax(Int)
|
||||
jobs_chnl = RemoteChannel(()->Channel{Any}(10))
|
||||
# Initialize min distance channel with Intmax
|
||||
min_dist_chnl = RemoteChannel(()->Channel{Int}(1))
|
||||
put!(min_dist_chnl, min_distance)
|
||||
# Future to store overall result
|
||||
ftr_result = @spawnat 1 (;path=result_path,min_distance_ref=Ref(min_distance))
|
||||
@async begin
|
||||
tsp_dist_impl(connections,hops,path,current_distance,min_dist_chnl,max_hops,jobs_chnl,nothing)
|
||||
for w in workers()
|
||||
put!(jobs_chnl,nothing)
|
||||
end
|
||||
end
|
||||
@sync for w in workers()
|
||||
@spawnat w begin
|
||||
path = zeros(Int, num_cities)
|
||||
max_hops = typemax(Int)
|
||||
jobs_channel = nothing
|
||||
while true
|
||||
job = take!(jobs_chnl)
|
||||
if job == nothing
|
||||
break
|
||||
end
|
||||
hops = job.hops
|
||||
path = job.path
|
||||
current_distance = job.current_distance
|
||||
tsp_dist_impl(connections,hops,path,current_distance,min_dist_chnl,max_hops,jobs_channel,ftr_result)
|
||||
end
|
||||
end
|
||||
end
|
||||
result = fetch(ftr_result)
|
||||
(;path = result.path, distance = result.min_distance_ref[])
|
||||
end
|
||||
city = 1
|
||||
tsp_dist(con2,city)
|
||||
66
notebooks/tsp-serial.jl
Normal file
66
notebooks/tsp-serial.jl
Normal file
@ -0,0 +1,66 @@
|
||||
using Distributed
|
||||
|
||||
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)]
|
||||
]
|
||||
|
||||
# Shortest route with start 1: 1-3-2-4 (distance: 7)
|
||||
con2 = [
|
||||
[(1,0), (2,2), (3,3), (4,4)],
|
||||
[(2,0), (4,1), (1,2), (3,3)],
|
||||
[(3,0), (1,3), (2,3), (4,10)],
|
||||
[(4,0), (2,1), (1,4), (3,10)]
|
||||
]
|
||||
|
||||
@everywhere function visited(city,hops,path)
|
||||
for i = 1:hops
|
||||
if path[i] == city
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
## TSP serial
|
||||
function tsp_serial_impl(connections,hops,path,current_distance, min_path, min_distance)
|
||||
num_cities = length(connections)
|
||||
if hops == num_cities
|
||||
if current_distance < min_distance
|
||||
min_path .= path
|
||||
return min_path, 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
|
||||
min_path, min_distance = tsp_serial_impl(connections,next_hops,path,next_distance,min_path,min_distance)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return min_path, min_distance
|
||||
end
|
||||
|
||||
function tsp_serial(connections,city)
|
||||
num_cities = length(connections)
|
||||
path=zeros(Int,num_cities)
|
||||
hops = 1
|
||||
path[hops] = city
|
||||
min_path = zeros(Int, num_cities)
|
||||
current_distance = 0
|
||||
min_distance = typemax(Int)
|
||||
min_path, min_distance = tsp_serial_impl(connections,hops,path,current_distance, min_path, min_distance)
|
||||
(;path=min_path,distance=min_distance)
|
||||
end
|
||||
|
||||
city = 1
|
||||
tsp_serial(connections,city)
|
||||
Loading…
x
Reference in New Issue
Block a user