From 046d9e39ac5f3c795dc846d3fe241fcba5982e60 Mon Sep 17 00:00:00 2001 From: Rafael Martinelli Date: Thu, 2 Jun 2022 16:04:42 -0300 Subject: [PATCH] Closes #2: Read large ORLib instances. --- README.md | 8 +++++++- src/Loader.jl | 32 ++++++++++++++++++-------------- test/runtests.jl | 27 +++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 0b7321f..7c3d913 100644 --- a/README.md +++ b/README.md @@ -51,10 +51,16 @@ data = loadCFLP(:cap41) See the [full list](https://github.com/rafaelmartinelli/CFLPLib.jl/tree/main/data). +Optionally, it is possible to set the facilities' capacity (mandatory for instances `capa`, `capb`, and `capc`): + +```julia +data = loadCFLP(:capa, 8000) +``` + CFLPLib also loads custom CFLP instances (following [ORLib format](http://people.brunel.ac.uk/~mastjjb/jeb/orlib/capinfo.html)): ```julia -data = loadCFLP("/path/to/your/CFLP/instance.txt") +data = loadCFLP("/path/to/your/CFLP/instance.txt", optional_facilities_capacity) ``` ## Installation diff --git a/src/Loader.jl b/src/Loader.jl index a7ea7c5..405b35d 100644 --- a/src/Loader.jl +++ b/src/Loader.jl @@ -1,44 +1,48 @@ -function loadCFLP(instance::Symbol) +function loadCFLP(instance::Symbol, capacity::Int64 = 0) file_name = joinpath(data_path, string(instance) * ".zip") if !isfile(file_name) println("File $(string(instance)) not found!") return nothing end - name = splitext(basename(file_name))[1] + name = splitext(basename(file_name))[1] * (capacity == 0 ? "" : "-$capacity") file = ZipFile.Reader(file_name) - values = parse.(Float64, split(read(file.files[1], String))) + values = split(read(file.files[1], String)) close(file) - return load(values, name) + return load(values, name, capacity) end -function loadCFLP(file_name::String) +function loadCFLP(file_name::String, capacity::Int64 = 0) if !isfile(file_name) println("File $file_name not found!") return nothing end - name = splitext(basename(file_name))[1] - values = parse.(Float64, split(read(file_name, String))) + name = splitext(basename(file_name))[1] * (capacity == 0 ? "" : "-$capacity") + values = split(read(file_name, String)) - return load(values, name) + return load(values, name, capacity) end -function load(values::Array{Float64}, name::String) - n_facilities = convert(Int64, values[1]) - n_customers = convert(Int64, values[2]) +function load(values::Array{SubString{String}}, name::String, capacity::Int64 = 0) + n_facilities = parse(Int64, values[1]) + n_customers = parse(Int64, values[2]) counter = 3 - capacities = convert.(Int64, values[counter:2:counter + 2 * n_facilities - 1]) - fixed_costs = values[counter + 1:2:counter + 2 * n_facilities - 1] + if capacity == 0 + capacities = parse.(Int64, values[counter:2:counter + 2 * n_facilities - 1]) + else + capacities = fill(capacity, n_facilities) + end + fixed_costs = parse.(Float64, values[counter + 1:2:counter + 2 * n_facilities - 1]) counter += 2 * n_facilities customers = CFLPCustomer[] for j in 1:n_customers - push!(customers, CFLPCustomer(j, convert(Int64, values[counter]), values[counter + 1:counter + n_facilities])) + push!(customers, CFLPCustomer(j, parse(Int64, values[counter]), parse.(Float64, values[counter + 1:counter + n_facilities]))) counter += n_facilities + 1 end diff --git a/test/runtests.jl b/test/runtests.jl index 3389f16..4ae16ee 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -40,3 +40,30 @@ end data = loadCFLP("notaninstance") @test data === nothing end + +@testset "DifferentCapacity" begin + data = loadCFLP(:cap41, 1000) + @test data.name == "cap41-1000" + @test data.facilities[3].capacity == 1000 + @test data.facilities[5].capacity == 1000 + @test data.lb == -Inf + @test data.ub == Inf + @test_nowarn println(data) + @test_nowarn println(data.facilities[2]) + @test_nowarn println(data.customers[6]) +end + +@testset "LargeInstances" begin + data = loadCFLP(:capa, 8000) + @test data.name == "capa-8000" + @test data.facilities[3].capacity == 8000 + @test data.facilities[5].fixed_cost == 2164343.000 + @test data.customers[7].demand == 14 + @test length(data.facilities) == 100 + @test length(data.customers) == 1000 + @test data.lb == 19240822.449 + @test data.ub == 19240822.449 + @test_nowarn println(data) + @test_nowarn println(data.facilities[2]) + @test_nowarn println(data.customers[6]) +end