Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .github/workflows/Documenter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ jobs:
name: Documentation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: julia-actions/setup-julia@v1
with:
version: '1'
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-docdeploy@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4 changes: 4 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ makedocs(;
),
pages=[
"Home" => "index.md",
"Instance catalogue" => "instances.md",
"API reference" => "reference.md",
],
)

deploydocs(;
repo="github.com/rafaelmartinelli/AssignmentProblems.jl",
devbranch="main",
push_preview=true,
)
64 changes: 20 additions & 44 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,61 +4,37 @@ CurrentModule = AssignmentProblems

# AssignmentProblems.jl

AssignmentProblems reads data files in `gap` format for Generalized Assignmnent Problem (GAP) instances.
AssignmentProblems.jl is a lightweight utility for loading Generalized
Assignment Problem (GAP) instances. It ships with the classical benchmark
library and can parse custom files that follow the OR-Library format.

## Usage
## Installation

The main type used by the package is `AssignmentProblem`, defined as follows:
AssignmentProblems is not yet registered. Install it directly from GitHub
using Julia's package manager:

```julia
struct AssignmentProblem
name::String # Instance name

capacities::Vector{Int64} # Agents' capacities
costs::Matrix{Int64} # Assigments costs (agents x jobs)
consumptions::Matrix{Int64} # Assigments consumptions (agents x jobs)

lb::Int64 # Lower bound (typemin(Int64) if not known)
ub::Int64 # Upper bound (typemax(Int64) if not known)
end
pkg> add https://github.com/rafaelmartinelli/AssignmentProblems.jl
```

The package also defines the functions `na` and `nj` returning the number of agents and jobs, respectively.

Some classical GAP instances from the literature are preloaded. For example, to load GAP instance `a05100`:
## Quick start

```julia
data = loadAssignmentProblem(:a05100)
```
julia> using AssignmentProblems

There is a second optional parameter to set the objective function used (default `:Min` or `:Max`). This is only used to populate lb and ub fields.
julia> problem = loadAssignmentProblem(:a05100)
GAP Data a05100 (5 agents, 100 jobs) [-Inf, Inf]

See the [full instance list](https://github.com/rafaelmartinelli/AssignmentProblems.jl/tree/main/data).

AssignmentProblems also loads custom GAP instances (following [ORLib format](http://people.brunel.ac.uk/~mastjjb/jeb/orlib/gapinfo.html)):

```julia
data = loadAssignmentProblem("/path/to/your/GAP/instance.txt")
julia> (na(problem), nj(problem))
(5, 100)
```

## Installation
Supply a file path instead of a symbol to read external instances, and pass
`:Max` as the optional second argument to work with maximisation bounds.

AssignmentProblems is *not* yet a registered Julia Package.
You can install AssignmentProblems through the Julia package manager.
Open Julia's interactive session (REPL) and type:
## Next steps

```julia
] add https://github.com/rafaelmartinelli/AssignmentProblems.jl
```

## Related links

- [Mutsunori Yagiura's GAP Page](http://www.al.cm.is.nagoya-u.ac.jp/~yagiura/gap/)
- [ORLib's GAP page](http://people.brunel.ac.uk/~mastjjb/jeb/orlib/gapinfo.html)

```@index
```

```@autodocs
Modules = [AssignmentProblems]
```
- Learn more about the bundled benchmarks in the [Instance catalogue](@ref
instance-catalogue).
- Browse the exported types and functions in the [API reference](@ref
reference).
36 changes: 36 additions & 0 deletions docs/src/instances.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
```@meta
CurrentModule = AssignmentProblems
```

# Instance catalogue

```@id instance-catalogue
```

The package bundles the classical Generalized Assignment Problem benchmarks as
ZIP archives under the `data/` directory. Each file is exposed through the
[`Instance`](@ref) enumeration, enabling programmatic discovery and loading.

## Listing the available instances

Use the `instances` helper from Julia's `Base.Enums` to iterate over every
identifier:

```@example
using AssignmentProblems
collect(instances(Instance))[1:5]
```

The enumeration is grouped according to the original literature (families `a`
through `e`). The suffix hints at the problem size, e.g. `a05100` stands for an
instance with 5 agents and 100 jobs.

## Loading data files

Every enumerated value corresponds to a ZIP archive. When you call
[`loadAssignmentProblem`](@ref) with an `Instance` symbol, the archive is read
and converted into an [`AssignmentProblem`](@ref).

To work with files outside of the bundled catalogue, pass a file path instead.
The loader accepts raw text files as well as single-entry ZIP archives that
follow the OR-Library specification.
28 changes: 28 additions & 0 deletions docs/src/reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
```@meta
CurrentModule = AssignmentProblems
```

# API reference

```@id reference
```

```@contents
Pages = ["reference.md"]
Depth = 2
```

## Types
```@docs
AssignmentProblem
Instance
Objective
```

## Functions
```@docs
loadAssignmentProblem
na
nj
loadBounds
```
8 changes: 8 additions & 0 deletions src/AssignmentProblems.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
"""
AssignmentProblems

Utilities for reading benchmark instances of the Generalized Assignment
Problem (GAP). The module exports helpers to access the bundled data set
collection, parse custom files that follow the OR-Library GAP format, and
inspect the resulting `AssignmentProblem` structures.
"""
module AssignmentProblems

export AssignmentProblem, loadAssignmentProblem
Expand Down
28 changes: 28 additions & 0 deletions src/Data.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
"""
AssignmentProblem

Container for a Generalized Assignment Problem (GAP) instance.

# Fields
- `name::String`: Identifier for the instance, usually matching the source
file name.
- `capacities::Vector{Int64}`: Capacity available for each agent.
- `costs::Matrix{Int64}`: Assignment costs arranged as agents × jobs.
- `consumptions::Matrix{Int64}`: Resource consumption for each
agent/job combination.
- `lb::Int64`: Known lower bound for the configured objective direction, or
`typemin(Int64)` if no bound is published.
- `ub::Int64`: Known upper bound for the configured objective direction, or
`typemax(Int64)` if no bound is published.
"""
struct AssignmentProblem
name::String

Expand All @@ -9,7 +26,18 @@ struct AssignmentProblem
ub::Int64
end

"""
na(problem::AssignmentProblem) -> Int

Return the number of agents encoded in `problem`.
"""
na(data::AssignmentProblem) = length(data.capacities)

"""
nj(problem::AssignmentProblem) -> Int

Return the number of jobs encoded in `problem`.
"""
nj(data::AssignmentProblem) = size(data.costs, 2)

function Base.show(io::IO, data::AssignmentProblem)
Expand Down
16 changes: 15 additions & 1 deletion src/Enums.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
"""
Instance

Enumeration of the Generalized Assignment Problem instances bundled with the
package. The values correspond to ZIP files under the `data/` directory and
can be iterated with `instances(Instance)`.
"""
@enum Instance begin
a05100
a05200
Expand Down Expand Up @@ -118,7 +125,14 @@
e801600
end

"""
Objective

Enumeration of the objective directions supported by
[`loadAssignmentProblem`](@ref). Use `:Min` for minimisation or `:Max` for
maximisation.
"""
@enum Objective begin
Min
Max
end
end
17 changes: 17 additions & 0 deletions src/Loader.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
"""
loadAssignmentProblem(instance::Symbol, objective::Symbol = :Min)
loadAssignmentProblem(file_name::String, objective::Symbol = :Min)

Load a GAP instance and return it as an [`AssignmentProblem`](@ref).

- When `instance` is provided, the function searches for a bundled ZIP file
under the package `data/` directory. The symbol must match one of the
values defined by [`Instance`](@ref).
- When `file_name` is provided, the file is read from disk. Both plain text
inputs and single-entry ZIP archives following the OR-Library layout are
supported.

The `objective` argument controls which pre-computed bounds are attached to
the resulting object. Use `:Min` for minimisation (default) or `:Max` for
maximisation.
"""
function loadAssignmentProblem(instance::Symbol, objective::Symbol = :Min)
file_name = joinpath(data_path, string(instance) * ".zip")
if !isfile(file_name)
Expand Down
10 changes: 10 additions & 0 deletions src/Util.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
"""
loadBounds(name::String, objective::Symbol) -> Tuple{Int64, Int64}

Return the published lower and upper bounds associated with `name` for the
given objective direction.

Bounds are loaded from `data/bounds.txt`, which stores entries as
`<name>_<objective> <lower> <upper>`. If no entry is found, the tuple
`(typemin(Int64), typemax(Int64))` is returned.
"""
function loadBounds(name::String, objective::Symbol)
file_name = joinpath(data_path, "bounds.txt")
values = split(read(file_name, String))
Expand Down
Loading