Skip to content

Commit

Permalink
Merge pull request #16 from rafaelmartinelli/new-loader
Browse files Browse the repository at this point in the history
New Loader
  • Loading branch information
rafaelmartinelli authored May 17, 2023
2 parents e7044e6 + 5f41fe2 commit 034bf83
Show file tree
Hide file tree
Showing 61 changed files with 428 additions and 122 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ version = "1.2.0"

[deps]
Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
ZipFile = "a5390f91-8eb1-5f08-bee0-b1d1ffed6cea"

[compat]
ZipFile = "0.9, 0.10"
julia = "1"
32 changes: 21 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@

This package reads data files for different location problems instances:

- Capacitated Facility Location Problems
- (Capacitated) P-Median Problems
- (Capacitated) Facility Location Problems
- ~~(~~Capacitated~~)~~ P-Median Problems
- Maximum Coverage Problems

## Usage

### Capacitated Facility Location Problems

The type used by Capacitated Facility Location Problems is `FacilityLocationProblem`, defined as follows:
The type used by (Capacitated) Facility Location Problems is `FacilityLocationProblem`, defined as follows:

```julia
struct FacilityLocationProblem
Expand All @@ -32,21 +32,23 @@ struct FacilityLocationProblem
end
```

Some classical CFLP instances from the literature are preloaded. For example, to load instance `cap41`:
Some classical instances from the literature can be downloaded on demand from [ORLib page](http://people.brunel.ac.uk/~mastjjb/jeb/info.html). For example, to download and load instance `cap41`:

```julia
data = loadFacilityLocationProblem(:cap41)
```

See the full list on [ORLib UFLP page](http://people.brunel.ac.uk/~mastjjb/jeb/orlib/uncapinfo.html), [ORLib CFLP page](http://people.brunel.ac.uk/~mastjjb/jeb/orlib/capinfo.html) or call the function `getFacilityLocationInstances`.

Optionally, it is possible to set the facilities' capacity (mandatory for instances `capa`, `capb`, and `capc`):

```julia
data = loadFacilityLocationProblem(:capa, 8000)
```

### (Capacitated) P-Median Problems
### ~~(~~Capacitated~~)~~ P-Median Problems

The type used by (Capacitated) P-Median Problems is `FacilityLocationProblem`, defined as follows:
The type used by ~~(~~Capacitated~~)~~ P-Median Problems is `PMedianProblem`, defined as follows:

```julia
struct PMedianProblem
Expand All @@ -58,6 +60,9 @@ struct PMedianProblem
demands::Vector{Int64} # Customers demands
costs::Matrix{Float64} # Costs matrix (distances)

x::Vector{Int64} # Customers x coordinates
y::Vector{Int64} # Customers y coordinates

lb::Float64 # Lower bound (-Inf if not known)
ub::Float64 # Upper bound ( Inf if not known)
end
Expand All @@ -69,6 +74,8 @@ Some classical (Capacitated) P-Median instances from the literature are preloade
data = loadPMedianProblem(:pmedcap01)
```

See the [full list](https://github.com/rafaelmartinelli/FacilityLocationProblems.jl/tree/main/data) or call the function `getPMedianInstances`.

### Maximum Coverage Problems

The type used by Maximum Coverage Problems is `MaximumCoverageProblem`, defined as follows:
Expand All @@ -83,6 +90,9 @@ struct MaximumCoverageProblem
demands::Vector{Int64} # Customers demands
coverage::Vector{Vector{Int64}} # Coverage sets

x::Vector{Int64} # Customers x coordinates
y::Vector{Int64} # Customers y coordinates

lb::Float64 # Lower bound (-Inf if not known)
ub::Float64 # Upper bound ( Inf if not known)
end
Expand All @@ -98,8 +108,6 @@ The medians capacities are ignored, and the coverage sets are built using calcul

### Other Features

See the [full list](https://github.com/rafaelmartinelli/FacilityLocationProblems.jl/tree/main/data) of preloaded instances.

This package also loads custom instances (following [ORLib format](http://people.brunel.ac.uk/~mastjjb/jeb/info.html)):

```julia
Expand All @@ -118,18 +126,20 @@ Open Julia's interactive session (REPL) and type:

## Related links

- [ORLib's Uncapacitated Facility Location page](http://people.brunel.ac.uk/~mastjjb/jeb/orlib/uncapinfo.html)
- [ORLib's Capacitated Facility Location page](http://people.brunel.ac.uk/~mastjjb/jeb/orlib/capinfo.html)
- [ORLib's Uncapacitated P-Median page](http://people.brunel.ac.uk/~mastjjb/jeb/orlib/pmedinfo.html)
- [ORLib's Uncapacitated P-Median page](http://people.brunel.ac.uk/~mastjjb/jeb/orlib/pmedinfo.html) (this package does not read those instances)
- [ORLib's Capacitated P-Median page](http://people.brunel.ac.uk/~mastjjb/jeb/orlib/pmedcapinfo.html)
- [Sobolev Institute of Mathematics' CFLP Page](http://www.math.nsc.ru/AP/benchmarks/CFLP/cflp_tabl-eng.html) (this package does not read those instances)
- [Instituto Nacional de Pesquisas Espaciais' P-Median and Max Cover Page](http://www.lac.inpe.br/~lorena/instancias.html) (this package does not read those instances)

## Other packages

- [KnapsackLib.jl](https://github.com/rafaelmartinelli/Knapsacks.jl): Knapsack algorithms in Julia
- [LotSizingProblems.jl](https://github.com/rafaelmartinelli/LotSizingProblems.jl): Lot Sizing Problems Lib
- [AssignmentProblems.jl](https://github.com/rafaelmartinelli/AssignmentProblems.jl): Assignment Problems Lib
- [InventoryRoutingProblems.jl](https://github.com/rafaelmartinelli/InventoryRoutingProblems.jl): Assignment Problems Lib
- [BPPLib.jl](https://github.com/rafaelmartinelli/BPPLib.jl): Bin Packing and Cutting Stock Lib
- [InventoryRoutingProblems.jl](https://github.com/rafaelmartinelli/InventoryRoutingProblems.jl): Inventory Routing Problems Lib
- [BPPLib.jl](https://github.com/rafaelmartinelli/BPPLib.jl): Bin Packing and Cutting Stock Problems Lib
- [CARPData.jl](https://github.com/rafaelmartinelli/CARPData.jl): Capacitated Arc Routing Problem Lib
- [MDVSP.jl](https://github.com/rafaelmartinelli/MDVSP.jl): Multiple-Depot Vehicle Scheduling Problem Lib
- [CVRPLIB.jl](https://github.com/chkwon/CVRPLIB.jl): Capacitated Vehicle Routing Problem Lib
Expand Down
64 changes: 52 additions & 12 deletions data/bounds.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,55 @@ cap131 793439.562 793439.562
cap132 851495.325 851495.325
cap133 893076.712 893076.712
cap134 928941.750 928941.750
capa-8000 19240822.449 19240822.449
capa-10000 18438046.543 18438046.543
capa-12000 17765201.949 17765201.949
capa-14000 17160439.012 17160439.012
capb-5000 13656379.578 13656379.578
capb-6000 13361927.449 13361927.449
capb-7000 13198556.434 13198556.434
capb-8000 13082516.496 13082516.496
capc-5000 11646596.974 11646596.974
capc-5750 11570340.289 11570340.289
capc-6500 11518743.744 11518743.744
capc-7250 11505767.394 11505767.394
capa_8000 19240822.449 19240822.449
capa_10000 18438046.543 18438046.543
capa_12000 17765201.949 17765201.949
capa_14000 17160439.012 17160439.012
capb_5000 13656379.578 13656379.578
capb_6000 13361927.449 13361927.449
capb_7000 13198556.434 13198556.434
capb_8000 13082516.496 13082516.496
capc_5000 11646596.974 11646596.974
capc_5750 11570340.289 11570340.289
capc_6500 11518743.744 11518743.744
capc_7250 11505767.394 11505767.394
pmed1 5819 5819
pmed2 4093 4093
pmed3 4250 4250
pmed4 3034 3034
pmed5 1355 1355
pmed6 7824 7824
pmed7 5631 5631
pmed8 4445 4445
pmed9 2734 2734
pmed10 1255 1255
pmed11 7696 7696
pmed12 6634 6634
pmed13 4374 4374
pmed14 2968 2968
pmed15 1729 1729
pmed16 8162 8162
pmed17 6999 6999
pmed18 4809 4809
pmed19 2845 2845
pmed20 1789 1789
pmed21 9138 9138
pmed22 8579 8579
pmed23 4619 4619
pmed24 2961 2961
pmed25 1828 1828
pmed26 9917 9917
pmed27 8307 8307
pmed28 4498 4498
pmed29 3033 3033
pmed30 1989 1989
pmed31 10086 10086
pmed32 9297 9297
pmed33 4700 4700
pmed34 3013 3013
pmed35 10400 10400
pmed36 9934 9934
pmed37 5057 5057
pmed38 11060 11060
pmed39 9423 9423
pmed40 5128 5128
Binary file removed data/cap101.zip
Binary file not shown.
Binary file removed data/cap102.zip
Binary file not shown.
Binary file removed data/cap103.zip
Binary file not shown.
Binary file removed data/cap104.zip
Binary file not shown.
Binary file removed data/cap111.zip
Binary file not shown.
Binary file removed data/cap112.zip
Binary file not shown.
Binary file removed data/cap113.zip
Binary file not shown.
Binary file removed data/cap114.zip
Binary file not shown.
Binary file removed data/cap121.zip
Binary file not shown.
Binary file removed data/cap122.zip
Binary file not shown.
Binary file removed data/cap123.zip
Binary file not shown.
Binary file removed data/cap124.zip
Binary file not shown.
Binary file removed data/cap131.zip
Binary file not shown.
Binary file removed data/cap132.zip
Binary file not shown.
Binary file removed data/cap133.zip
Binary file not shown.
Binary file removed data/cap134.zip
Binary file not shown.
Binary file removed data/cap41.zip
Binary file not shown.
Binary file removed data/cap42.zip
Binary file not shown.
Binary file removed data/cap43.zip
Binary file not shown.
Binary file removed data/cap44.zip
Binary file not shown.
Binary file removed data/cap51.zip
Binary file not shown.
Binary file removed data/cap61.zip
Binary file not shown.
Binary file removed data/cap62.zip
Binary file not shown.
Binary file removed data/cap63.zip
Binary file not shown.
Binary file removed data/cap64.zip
Binary file not shown.
Binary file removed data/cap71.zip
Binary file not shown.
Binary file removed data/cap72.zip
Binary file not shown.
Binary file removed data/cap73.zip
Binary file not shown.
Binary file removed data/cap74.zip
Binary file not shown.
Binary file removed data/cap81.zip
Binary file not shown.
Binary file removed data/cap82.zip
Binary file not shown.
Binary file removed data/cap83.zip
Binary file not shown.
Binary file removed data/cap84.zip
Binary file not shown.
Binary file removed data/cap91.zip
Binary file not shown.
Binary file removed data/cap92.zip
Binary file not shown.
Binary file removed data/cap93.zip
Binary file not shown.
Binary file removed data/cap94.zip
Binary file not shown.
Binary file removed data/capa.zip
Binary file not shown.
Binary file removed data/capb.zip
Binary file not shown.
Binary file removed data/capc.zip
Binary file not shown.
Binary file added data/pmedcap05.zip
Binary file not shown.
21 changes: 14 additions & 7 deletions src/FacilityLocationProblems.jl
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
module FacilityLocationProblems

export loadFacilityLocationProblem, FacilityLocationProblem
export loadPMedianProblem, PMedianProblem
export loadMaximumCoverageProblem, MaximumCoverageProblem
export loadFacilityLocationProblem, FacilityLocationProblem, getFacilityLocationInstances
export loadPMedianProblem, PMedianProblem, getPMedianInstances
export loadMaximumCoverageProblem, MaximumCoverageProblem, getMaximumCoverageInstances
export nf, nc

const data_path = joinpath(pkgdir(FacilityLocationProblems), "data")

const orlib_url = "http://people.brunel.ac.uk/~mastjjb/jeb/orlib/files/"

using Distances
using Downloads
using ZipFile
using Printf

include("util/Download.jl")
include("util/Bounds.jl")

include("facility-location/Instances.jl")
include("facility-location/Data.jl")
include("facility-location/Loader.jl")

include("maximum-coverage/Data.jl")
include("maximum-coverage/Loader.jl")

include("p-median/Instances.jl")
include("p-median/Data.jl")
include("p-median/Loader.jl")

include("Util.jl")
include("maximum-coverage/Instances.jl")
include("maximum-coverage/Data.jl")
include("maximum-coverage/Loader.jl")

end
4 changes: 2 additions & 2 deletions src/facility-location/Data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ nc(data::FacilityLocationProblem)::Int64 = length(data.demands)

function Base.show(io::IO, data::FacilityLocationProblem)
@printf(io, "CFLP Data %s", data.name)
@printf(io, " (%d facilities,", nf(data))
@printf(io, " %d customers)", nc(data))
@printf(io, " (nf = %d,", nf(data))
@printf(io, " nc = %d)", nc(data))
@printf(io, " [%.3f, %.3f]", data.lb, data.ub)
end
50 changes: 50 additions & 0 deletions src/facility-location/Instances.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@enum FacilityLocationInstances begin
cap41
cap42
cap43
cap44
cap51
cap61
cap62
cap63
cap64
cap71
cap72
cap73
cap74
cap81
cap82
cap83
cap84
cap91
cap92
cap93
cap94
cap101
cap102
cap103
cap104
cap111
cap112
cap113
cap114
cap121
cap122
cap123
cap124
cap131
cap132
cap133
cap134
capa
capb
capc
end

for inst in instances(FacilityLocationInstances)
@eval export $(Symbol(inst))
end

function getFacilityLocationInstances()
return [ Symbol(inst) for inst in instances(FacilityLocationInstances) ]
end
29 changes: 11 additions & 18 deletions src/facility-location/Loader.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
function loadFacilityLocationProblem(instance::Symbol, capacity::Int64 = 0)::Union{FacilityLocationProblem, Nothing}
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] * (capacity == 0 ? "" : "-$capacity")
file = ZipFile.Reader(file_name)
values = split(read(file.files[1], String))
close(file)

return loadFacilityLocationProblem(values, name, capacity)
name = string(instance)
values = readInstance(name)
if values === nothing return nothing end
name = name * (capacity == 0 ? "" : "_$capacity")
return doLoadFacilityLocationProblem(values, name, capacity)
end

function loadFacilityLocationProblem(file_name::String, capacity::Int64 = 0)::Union{FacilityLocationProblem, Nothing}
Expand All @@ -19,13 +12,12 @@ function loadFacilityLocationProblem(file_name::String, capacity::Int64 = 0)::Un
return nothing
end

name = splitext(basename(file_name))[1] * (capacity == 0 ? "" : "-$capacity")
values = split(read(file_name, String))

return loadFacilityLocationProblem(values, name, capacity)
name = splitext(basename(file_name))[1] * (capacity == 0 ? "" : "_$capacity")
return doLoadFacilityLocationProblem(values, name, capacity)
end

function loadFacilityLocationProblem(values::Array{SubString{String}}, name::String, capacity::Int64 = 0)::Union{FacilityLocationProblem, Nothing}
function doLoadFacilityLocationProblem(values::Vector{SubString{String}}, name::String, capacity::Int64)::Union{FacilityLocationProblem, Nothing}
n_facilities = parse(Int64, values[1])
n_customers = parse(Int64, values[2])

Expand All @@ -35,7 +27,8 @@ function loadFacilityLocationProblem(values::Array{SubString{String}}, name::Str
if capacity == 0
capacities = tryparse.(Int64, values[counter:2:counter + 2 * n_facilities - 1])
if capacities[1] === nothing
error("Instance $name does not have capacities. Please load with loadFacilityLocationProblem(instance, capacity).")
@error("Instance $name does not have capacities. Please load with loadFacilityLocationProblem(instance, capacity).")
return nothing
end
else
capacities = fill(capacity, n_facilities)
Expand All @@ -52,5 +45,5 @@ function loadFacilityLocationProblem(values::Array{SubString{String}}, name::Str
counter += n_facilities + 1
end

return FacilityLocationProblem(name, capacities, demands, fixed_costs, costs, loadBounds(name)...)
return FacilityLocationProblem(name, capacities, demands, fixed_costs, costs, loadBounds(name, capacity)...)
end
3 changes: 3 additions & 0 deletions src/maximum-coverage/Data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ struct MaximumCoverageProblem
demands::Vector{Int64}
coverage::Vector{Vector{Int64}}

x::Vector{Int64}
y::Vector{Int64}

lb::Float64
ub::Float64
end
Expand Down
3 changes: 3 additions & 0 deletions src/maximum-coverage/Instances.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function getMaximumCoverageInstances()
return [ Symbol(inst) for inst in instances(PMedianInstances) ]
end
8 changes: 4 additions & 4 deletions src/maximum-coverage/Loader.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function loadMaximumCoverageProblem(instance::Symbol, distance::Int64)::Union{Ma
values = split(read(file.files[1], String))
close(file)

return loadMaximumCoverageProblem(values, distance, name)
return doLoadMaximumCoverageProblem(values, distance, name)
end

function loadMaximumCoverageProblem(file_name::String, distance::Int64)::Union{MaximumCoverageProblem, Nothing}
Expand All @@ -22,10 +22,10 @@ function loadMaximumCoverageProblem(file_name::String, distance::Int64)::Union{M
name = splitext(basename(file_name))[1]
values = split(read(file_name, String))

return loadMaximumCoverageProblem(values, distance, name)
return doLoadMaximumCoverageProblem(values, distance, name)
end

function loadMaximumCoverageProblem(values::Array{SubString{String}}, distance::Int64, name::String)::Union{MaximumCoverageProblem, Nothing}
function doLoadMaximumCoverageProblem(values::Array{SubString{String}}, distance::Int64, name::String)::Union{MaximumCoverageProblem, Nothing}
n = parse(Int64, values[3])
medians = parse(Int64, values[4])

Expand All @@ -38,5 +38,5 @@ function loadMaximumCoverageProblem(values::Array{SubString{String}}, distance::
costs = [ floor(Int64, euclidean([x[i], y[i]], [x[j], y[j]])) for i in 1:n, j in 1:n ]
coverage = [ [ j for j in 1:n if costs[i, j] <= distance ] for i in 1:n ]

return MaximumCoverageProblem(name, medians, distance, demands, coverage, -Inf64, Inf64)
return MaximumCoverageProblem(name, medians, distance, demands, coverage, x, y, -Inf64, Inf64)
end
2 changes: 1 addition & 1 deletion src/p-median/Data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ struct PMedianProblem
capacity::Int64

demands::Vector{Int64}
costs::Matrix{Float64}
costs::Matrix{Int64}

x::Vector{Int64}
y::Vector{Int64}
Expand Down
Loading

0 comments on commit 034bf83

Please sign in to comment.