Skip to content

Commit

Permalink
Merge pull request #7 from chkwon/refactor
Browse files Browse the repository at this point in the history
Refactor
  • Loading branch information
chkwon authored Feb 25, 2021
2 parents 9b7fbe7 + e2c43b8 commit 0b2435c
Show file tree
Hide file tree
Showing 8 changed files with 194 additions and 201 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ jobs:
${{ runner.os }}-test-${{ env.cache-name }}-
${{ runner.os }}-test-
${{ runner.os }}-
- name: Install dependencies
run: julia --project=. -e 'using Pkg; Pkg.add(url="""https://github.com/matago/TSPLIB.jl"""); Pkg.instantiate()'
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
- uses: julia-actions/julia-processcoverage@v1
Expand Down
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ version = "0.1.0"
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
TSPLIB = "b1c258e7-59ae-4b06-a547-f10871db1548"

[compat]
julia = "1"
Expand Down
1 change: 1 addition & 0 deletions deps/build.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Libdl


const QSOPT_LOCATION = Dict(
"Darwin" => [
"https://www.math.uwaterloo.ca/~bico/qsopt/beta/codes/mac64/qsopt.a",
Expand Down
148 changes: 4 additions & 144 deletions src/Concorde.jl
Original file line number Diff line number Diff line change
@@ -1,153 +1,13 @@
module Concorde

using Random, LinearAlgebra
using TSPLIB


include("../deps/deps.jl")
include("dist.jl")
# Write your package code here.

function read_solution(filepath)
sol = readlines(filepath)
n_nodes = sol[1]
tour = parse.(Int, split(join(sol[2:end]))) .+ 1
return tour
end

function tour_length(tour, M)
n_nodes = length(tour)
len = 0
for i in 1:n_nodes
j = i + 1
if i == n_nodes
j = 1
end

len += M[tour[i], tour[j]]
end
return len
end


function cleanup(name)
exts = ["mas", "pul", "sav", "sol", "tsp"]
for ext in exts
file = "$(name).$(ext)"
rm(file, force=true)
file = "O$(name).$(ext)"
rm(file, force=true)
end
end

function solve_tsp(dist_mtx::Matrix{Int})
if !issymmetric(dist_mtx)
error("Asymmetric TSP is not supported.")
end

n_nodes = size(dist_mtx, 1)
name = randstring(10)
filepath = name * ".tsp"
lower_diag_row = Int[]
for i in 1:n_nodes
for j in 1:i
push!(lower_diag_row, dist_mtx[i, j])
end
end
buf = 10
n_rows = length(lower_diag_row) / buf |> ceil |> Int
rows = String[]
for i in 1:n_rows
s = buf * (i-1) + 1
t = min(buf * i, length(lower_diag_row))
push!(rows, join(lower_diag_row[s:t], " "))
end

open(filepath, "w") do io
write(io, "NAME: $(name)\n")
write(io, "TYPE: TSP\n")
write(io, "COMMENT: $(name)\n")
write(io, "DIMENSION: $(n_nodes)\n")
write(io, "EDGE_WEIGHT_TYPE: EXPLICIT\n")
write(io, "EDGE_WEIGHT_FORMAT: LOWER_DIAG_ROW \n")
write(io, "EDGE_WEIGHT_SECTION\n")
for r in rows
write(io, "$r\n")
end
write(io, "EOF\n")
end

status = run(`$(Concorde.CONCORDE_EXECUTABLE) $(filepath)`, wait=false)
while !success(status)
#
end

sol_filepath = name * ".sol"
opt_tour = read_solution(sol_filepath)
opt_len = tour_length(opt_tour, dist_mtx)

cleanup(name)

return opt_tour, opt_len
end


function solve_tsp(x::Vector{Float64}, y::Vector{Float64}; dist="EUC_2D")
n_nodes = length(x)
@assert length(x) == length(y)

name = randstring(10)
filepath = name * ".tsp"

open(filepath, "w") do io
write(io, "NAME: $(name)\n")
write(io, "TYPE: TSP\n")
write(io, "COMMENT: $(name)\n")
write(io, "DIMENSION: $(n_nodes)\n")
write(io, "EDGE_WEIGHT_TYPE: $(dist)\n")
write(io, "EDGE_WEIGHT_FORMAT: FUNCTION \n")
write(io, "NODE_COORD_TYPE: TWOD_COORDS \n")
write(io, "NODE_COORD_SECTION\n")
for i in 1:n_nodes
write(io, "$i $(x[i]) $(y[i])\n")
end
write(io, "EOF\n")
end

status = run(`$(Concorde.CONCORDE_EXECUTABLE) $(filepath)`, wait=false)
while !success(status)
#
end

sol_filepath = name * ".sol"
opt_tour = read_solution(sol_filepath)
opt_len = tour_length(opt_tour, dist_matrix(x, y, dist=dist))

cleanup(name)

return opt_tour, opt_len
end

function solve_tsp(tsp_file::String)
if !isfile(tsp_file)
error("$(tsp_file) is not a file.")
end

name = randstring(10)
filepath = name * ".tsp"
cp(tsp_file, filepath)

status = run(`$(Concorde.CONCORDE_EXECUTABLE) $(filepath)`, wait=false)
while !success(status)
#
end

sol_filepath = name * ".sol"
opt_tour = read_solution(sol_filepath)
opt_len = - 1 # Need to implement the calculation of the obj function

cleanup(name)

return opt_tour, opt_len
end
include("util.jl")
include("solver.jl")


export solve_tsp
Expand Down
110 changes: 55 additions & 55 deletions src/dist.jl
Original file line number Diff line number Diff line change
@@ -1,63 +1,63 @@
function nint(x::Float64)
return round(Int, x)
end
# function nint(x::Float64)
# return round(Int, x)
# end

function geo_coordinate(x, y)
PI = 3.141592
# function geo_coordinate(x, y)
# PI = 3.141592

deg = nint(x)
m = x - deg
latitude = PI * (deg + 5.0 * m / 3.0) / 180.0
# deg = nint(x)
# m = x - deg
# latitude = PI * (deg + 5.0 * m / 3.0) / 180.0

deg = nint(y)
m = y - deg
longitude = PI * (deg + 5.0 * m / 3.0) / 180.0
# deg = nint(y)
# m = y - deg
# longitude = PI * (deg + 5.0 * m / 3.0) / 180.0

return latitude, longitude
end
# return latitude, longitude
# end

function distance2D(xi, yi, xj, yj; dist="EUC_2D")
if dist == "EUC_2D"
xd = xi - xj
yd = yi - yj
return nint(sqrt(xd*xd + yd*yd))
elseif dist == "MAN_2D"
xd = abs(xi - xj)
yd = abs(yi - yj)
return nint(xd + yd)
elseif dist == "MAX_2D"
xd = abs(xi - xj)
yd = abs(yi - yj)
return max(nint(xd), nint(yd))
elseif dist == "GEO"
lat_i, long_i = geo_coordinate(xi, yi)
lat_j, long_j = geo_coordinate(xj, yj)
RRR = 6378.388
q1 = cos(long_i - long_j)
q2 = cos(lat_i - lat_j)
q3 = cos(lat_i + lat_j)
dij = RRR * acos( 0.5*((1.0+q1)*q2 - (1.0-q1)*q3) ) + 1.0
return floor(Int, dij)
else
error("Distance function $dist is not supported.")
end
end
# function distance2D(xi, yi, xj, yj; dist="EUC_2D")
# if dist == "EUC_2D"
# xd = xi - xj
# yd = yi - yj
# return nint(sqrt(xd*xd + yd*yd))
# elseif dist == "MAN_2D"
# xd = abs(xi - xj)
# yd = abs(yi - yj)
# return nint(xd + yd)
# elseif dist == "MAX_2D"
# xd = abs(xi - xj)
# yd = abs(yi - yj)
# return max(nint(xd), nint(yd))
# elseif dist == "GEO"
# lat_i, long_i = geo_coordinate(xi, yi)
# lat_j, long_j = geo_coordinate(xj, yj)
# RRR = 6378.388
# q1 = cos(long_i - long_j)
# q2 = cos(lat_i - lat_j)
# q3 = cos(lat_i + lat_j)
# dij = RRR * acos( 0.5*((1.0+q1)*q2 - (1.0-q1)*q3) ) + 1.0
# return floor(Int, dij)
# else
# error("Distance function $dist is not supported.")
# end
# end

function dist_matrix(x::Vector{Float64}, y::Vector{Float64}; dist="EUC_2D")
n_nodes = length(x)
@assert length(x) == length(y)
# function dist_matrix(x::Vector{Float64}, y::Vector{Float64}; dist="EUC_2D")
# n_nodes = length(x)
# @assert length(x) == length(y)

M = Matrix{Int}(undef, n_nodes, n_nodes)
# M = Matrix{Int}(undef, n_nodes, n_nodes)

for i in 1:n_nodes
for j in i:n_nodes
if i == j
M[i, j] = 0
else
M[i, j] = distance2D(x[i], y[i], x[j], y[j]; dist=dist)
M[j, i] = M[i, j]
end
end
end
return M
end
# for i in 1:n_nodes
# for j in i:n_nodes
# if i == j
# M[i, j] = 0
# else
# M[i, j] = distance2D(x[i], y[i], x[j], y[j]; dist=dist)
# M[j, i] = M[i, j]
# end
# end
# end
# return M
# end
Loading

0 comments on commit 0b2435c

Please sign in to comment.