Starting to add notebook about tsp

This commit is contained in:
Francesc Verdugo 2023-07-28 09:06:19 +02:00
parent 5b47a090a5
commit ffcd31c482

260
notebooks/tsp.ipynb Normal file
View File

@ -0,0 +1,260 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "8850d90e",
"metadata": {},
"outputs": [],
"source": [
"using Distributed"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "5d4935ee",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4-element Vector{Int64}:\n",
" 2\n",
" 3\n",
" 4\n",
" 5"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"if procs() == workers()\n",
" addprocs(4)\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "4a2756ae",
"metadata": {},
"outputs": [],
"source": [
"@everywhere function visited(city,hops,path)\n",
" for i = 1:hops\n",
" if path[i] == city\n",
" return true\n",
" end\n",
" end\n",
" return false\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "39e9e667",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"tsp_serial_impl (generic function with 1 method)"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function tsp_serial_impl(connections,hops,path,current_distance,min_distance)\n",
" num_cities = length(connections)\n",
" if hops == num_cities\n",
" if current_distance < min_distance\n",
" return current_distance\n",
" end\n",
" else\n",
" current_city = path[hops]\n",
" next_hops = hops + 1\n",
" for (next_city,distance_increment) in connections[current_city]\n",
" if !visited(next_city,hops,path)\n",
" path[next_hops] = next_city\n",
" next_distance = current_distance + distance_increment\n",
" if next_distance < min_distance\n",
" return tsp_serial_impl(connections,next_hops,path,next_distance,min_distance)\n",
" end\n",
" end\n",
" end \n",
" end\n",
" min_distance\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "83b58881",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"tsp_serial (generic function with 1 method)"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function tsp_serial(connections,city)\n",
" num_cities = length(connections)\n",
" path=zeros(Int,num_cities)\n",
" hops = 1\n",
" path[hops] = city\n",
" current_distance = 0\n",
" min_distance = typemax(Int)\n",
" min_distance = tsp_serial_impl(connections,hops,path,current_distance,min_distance)\n",
" (;path=path,distance=min_distance)\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "78095098",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(path = [1, 4, 5, 2, 3, 6], distance = 222)"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"connections = [\n",
" [(1,0),(4,39),(5,76), (6,78),(3,94),(2,97)],\n",
" [(2,0),(5,25),(4,58),(3,62),(1,97),(6,109)],\n",
" [(3,0),(6,58),(2,62),(4,68),(5,70),(1,94)],\n",
" [(4,0),(5,38),(1,39),(2,58),(3,68),(6,78)],\n",
" [(5,0),(2,25),(4,38),(3,70),(1,76),(6,104)],\n",
" [(6,0),(3,58),(1,78),(4,78),(5,104),(2,109)]\n",
"]\n",
"city = 1\n",
"tsp_serial(connections,city)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "03f0dd8e",
"metadata": {},
"outputs": [],
"source": [
"@everywhere function tsp_dist_impl(connections,hops,path,current_distance,min_distance,max_hops,jobs_chnl,ftr_result)\n",
" num_cities = length(connections)\n",
" if hops == num_cities\n",
" if current_distance < min_distance\n",
" if ftr_result !== nothing\n",
" @spawnat 1 begin\n",
" result = fetch(ftr_result)\n",
" result.path .= path\n",
" result.min_distance_ref[] = current_distance\n",
" end |> wait\n",
" end\n",
" return current_distance\n",
" end\n",
" elseif hops <= max_hops\n",
" current_city = path[hops]\n",
" next_hops = hops + 1\n",
" for (next_city,distance_increment) in connections[current_city]\n",
" if !visited(next_city,hops,path)\n",
" path[next_hops] = next_city\n",
" next_distance = current_distance + distance_increment\n",
" if next_distance < min_distance\n",
" return tsp_dist_impl(connections,next_hops,path,next_distance,min_distance,max_hops,jobs_chnl,ftr_result)\n",
" end\n",
" end\n",
" end \n",
" else\n",
" if jobs_channel !== nothing\n",
" put!(jobs_chnl,(;hops,path,current_distance))\n",
" end\n",
" end\n",
" min_distance\n",
"end\n",
"\n",
"function tsp_dist(connections,city)\n",
" max_hops = 2\n",
" num_cities = length(connections)\n",
" path=zeros(Int,num_cities)\n",
" hops = 1\n",
" path[hops] = city\n",
" current_distance = 0\n",
" min_distance = typemax(Int)\n",
" jobs_chnl = RemoteChannel(()->Channel{Any}(10))\n",
" ftr_result = @spawnat 1 (;path,min_distance_ref=Ref(min_distance))\n",
" task = @async begin\n",
" tsp_dist_impl(connections,hops,path,current_distance,min_distance,max_hops,jobs_chnl,nothing)\n",
" for w in workers()\n",
" put!(job_chnl,nothing)\n",
" end\n",
" end\n",
" @sync for w in workers()\n",
" @spawnat w begin\n",
" max_hops = typemax(Int)\n",
" jobs_channel = nothing\n",
" while true\n",
" job = take!(jobs_chnl)\n",
" if job == nothing\n",
" break\n",
" end\n",
" hobs = job.hobs\n",
" path = job.path\n",
" current_distance = job.current_distance\n",
" tsp_dist_impl(connections,hops,path,current_distance,min_distance,max_hops,jobs_chnl,ftr_result)\n",
" end\n",
" end\n",
" end \n",
" (;path=path,distance=min_distance)\n",
"end\n",
"city = 1\n",
"tsp_dist(connections,city)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "370a1205",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.9.0",
"language": "julia",
"name": "julia-1.9"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.9.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}