Skip to content

toulbar2/baryonyx

 
 

Repository files navigation

Baryonyx

Baryonyx is an integer and binary linear programming solver based on the Dag Wedelin heuristic.

Build Status

Build Status

Copyright © 2017-2018 INRA

The software is released under the MIT license. See the LICENSE file.

Baryonyx

  • cmake (≥ 3)

  • c compiler with c14 support (gcc ≥ 5, clang ≥ 3.5, visual studio 2017)

For recent Debian GNU/Linux and Ubuntu derivatives (remove clang to only use gcc):

apt-get install build-essential cmake clang

For Windows, install the CMake program and Visual Studio 2017 (MSVC). You may also install the vcpkg program to install nlopt and other dependencies.

  • nlopt library - optimization library to automatic parametrization of the Baryonyx solver parameters.

First installation

First, we clone Baryonyx git repository and the submodule.

git clone https://github.com/quesnel/baryonyx.git
cd baryonyx
git submodule update --init --recursive

Default, Baryonyx provides a shared library libbaryonyx-0.3.so (with hidden symbol), a static library libbaryonyx-0.3.a (all symbols are public) and an executable baryonyx-0.3. To compile and install in the default CMake install directory:

cd baryonyx
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make install

Previous command line install Baryonyx program and library into the /usr/local prefix. If you install into another directory, you need to define three environment variables (into your .bashrc or equivalent). If you install into $HOME/usr for example, you need to define in your .bashrc:

export PATH=$PATH:$HOME/usr/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/usr/lib
export PKG_CONFIG_PATH=$PKG_CONFIX_PATH:$HOME/usr/lib/pkgconfig

Then run the following commands:

cd baryonyx
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$HOME/usr ..
make install

To override the default build flags, remove the CMAKE_BUILD_TYPE parameter and override the CXXFLAGS as follow:

export CXX=g++-8
export CXXFLAGS='-Wall -Wextra -Werror -ftree-vectorize -mmmx -msse -msse2 -msse3 -O3'
cmake -DCMAKE_INSTALL_PREFIX=$HOME/usr ..

The CMake script provide parameters to control debug, log facility and optimization.

Table 1. Table CMake Command line parameters (cmake -DWITH_LOG=OFF …​)
name default summary

WITH_LOG

ON

Enable log message on standard output.

WITH_DEBUG

ON

Enable maximum debug function and add more log message. Be careful, this mode slow down computation.

WITH_FULL_OPTIMIZATION

OFF

Enable optimal computation but remove some control on float and control.

Update installation

First, we need to update the Git repository with the following commands:

cd baryonyx
git pull -r
git submodule update --recursive

Then go to the build directory and restart compilation and installation :

cd baryonyx
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make install

Usage

Solver & Optimizer

To run Baryonyx in solver mode (i.e. trying to valid all constraints):

baryonyx-0.3 file.lp

To run baryonyx into the heuristic model (i.e. trying to valid all constraints and optimize the solution), add a -o or --optimize option to the command line:

baryonyx-0.3 -o file.lp

To run baryonyx into the heuristic model (i.e. trying to valid all constraints and optimize the solution), add a -o or --optimize option to the command line:

baryonyx-0.3 -o file.lp

The Baryonyx solver have many parameters. Some parameters are global, some specific for the optimization algorithms.

Table 2. Table Command line global parameters
name type summary

--help -h

Show help message

--quiet -q

Remove many console output

--bench [name]

Start benchmark. Need csv input files

--optimize -O

Start Baryonyx in optimization mode, default is to use the solve mode

--limit -l -plimit

integer

number of loop to stop algorithm

--verbose -v

integer

verbose level from 0 (very very verbose in debug mode) to 7 (quiet)

--disable-preprocessing -np

disable the use of preprocessing

--auto[:= ]value

string

Select the type of optimizer meta-heuristic. Values are:

  • none without specific algorithm.

  • manual tries to update parameters to found best solution.

  • nlopt tries to update parameters to found best solution using nlopt library and the Nelder Mead algorithm.

  • branch split recursively original problem to found best solution.

  • branch-manual mix branch and manual algorithm.

  • branch-nlopt mix branch and nlopt algorithm.

To assign parameters to solver or optimizer algorithms, use the -p [name]:value syntax in the command line:

Table 3. Table Command line parameters
name type summary

time-limit

real

time in second to stop algorithm or stop the optimize mode

limit

integer

number of loop to stop algorithm

w

integer

warmup-iterator (number of loop without updating kappa)

theta

real

history parameters [0, 1[

delta

real

influence parameters [0, +oo[

kappa-min

real

kappa minimal value [0, kappa-max

kappa-step

real

kappa updater [0, +oo[

kappa-max

real

kappa maximal value ]kappa-min, +oo[ to stop algorithm

alpha

real

adaptiveness parameter

pushing-k-factor

integer

use to lower the kappa using the push system

pushes-limit

integer

number of push before stopping the algorithm

pushing-objective-amplifier

real

use to make r more similar to costs

pushing-iteration-limit

integer

number of loop before trying a new push

norm

string

Select the cost normalization function

  • none let unmodified costs.

  • l1 use the l1-norm function

  • l2 use the l2-norm function

  • rng (experimental)

  • inf (default): use the infinity norm.

constraint-order

string

Remaining constraints order. Values are:

  • none (default): use the lp format constraint order

  • reversing: reverse the lp format constraint order

  • random-sorting: random the remaining constraint list

  • infeasibility-decr: compute infeasibility constraint in decremental order

  • infeasibility-incr: compute infeasibility constraint in incremental order

  • lagrangian-decr: sort violated constraints according to the Lagrangian multiplier values in decremental order

  • lagrangian-incr: sort violated constraints according to the Lagrangian multiplier values in incremental order

preprocessing

string

Constraints matrix A order. Values are:

  • none: Use the raw_problem (or lp file) order for constraints and variables.

  • memory: Default, use the raw_problem (or lp file) order for constraints but sort the variables to improve the memory cache efficiency.

  • less_greater_equal: sort constraints according to their type (first less and finally greater then equal) and sort variable to improve the memory cache efficiency.

  • less_equal_greater: sort constraints according to their type (first less and finally equal then greater) and sort variable to improve the memory cache efficiency.

  • greater_less_equal: sort constraints according to their type (first greater then less and finally equal) and sort variable to improve the memory cache efficiency.

  • greater_equal_less: sort constraints according to their type (first greater then equal and finally less) and sort variable to improve the memory cache efficiency.

  • equal_less_greater: sort constraints according to their type (first equal then less and finally greater) and sort variable to improve the memory cache efficiency.

  • equal_greater_less: sort constraints according to their type (first equal then greater and finally less) and sort variable to improve the memory cache efficiency.

  • p1: reserved

  • p2: reserved

  • p3: reserved

  • p4: reserved

observation

string

Select the type of observation mechanism (only in solve mode)

  • none no observation (default).

  • pnm produce picture files for the P matrix (one per loop) and Pi vector (Lagrangian multipliers) each loop

  • file produce CSV files for the P matrix (one per loop) and Pi vector (Lagrangian multipliers) each loop

floating-point_type

string

Select the type of real use internally in the solvers. Values are:

  • float float (32 bits)

  • double double (64 bits)

  • longdouble long double (84 or 128 bits)

print-level

integer

show information if greater than 0

init-policy

string

Change the (re)initialization policy of the solution vector. Values are:

  • bastert (default): use cost values.

  • random: use random value.

  • best: use best solution found if available (bastert otherwise).

init-random

real

[0-1] p parameter of the bernoulli’s law.

storage-type

string

Change the solution storage policy for the optimizer mode.

  • one (default): stores only the best solution found.

  • bound: stores the best and the bad solution found.

  • five: stores the best five solution found.

For example:

baryonyx -p limit:1000000 lib/test/prevl1.lp
baryonyx -p limit:-1 -p kappa-min:0.2 lib/test/prevl1.lp

Benchmark

Baryonyx permits to run benchmark on a set of problems described in a csv files. This option is available using the --bench [name] option and csv files. All Baryonyx parameters are available to perform the benchmark.

For example:

baryonyx --bench bx-0.3 -pdelta:0.01 -ptime-limit:60 spp.csv

The benchmark mode generates a new spp-new.csv file with results of computation. The csv format is:

file optimum status cplex lsp bx-0.2 (1)
cplex:
lsp:    (2)
bx-0.2:
scp410 optimum 514 514 514 804 (3)
scp41 optimum 429 429 429 627
scp42 optimum 512 512 512 934
  1. The header: three columns mandatory (file, optimum, status) and one solver per column. In this example, cplex, local solver and baryonyx 0.2.

  2. The description part: one line per solver to describe version and parameter for example.

  3. Finally, one line per solve: model name (with or without extension), status (optimum/feasible), best solution found and solver’s solution. inf can be use to indicate no solution found.

In benchmark directory, some files are provided and a script to download classical problem.

R

To use rbaryonyx, you must compile and install the baryonyx library. Follow the previous section and install R.

Installation

The R rbaryonyx package requires several packages. Then, under a R terminal:

cd baryonyx/rbaryonyx
R CMD REMOVE rbaryonyx (1)

install.packages("roxygen2") (2)
install.packages("Rcpp")
install.packages("devtools")

library(Rcpp) (3)
compileAttributes(".")
library(devtools)
devtools::document()
devtools::build()
devtools::install()

library(rbaryonyx) (4)
?rbaryonyx (5)
  1. Remove previous installed version of rbaryonyx

  2. Install the dependencies of rbaryonyx

  3. Build the rbaryonyx package

  4. Load the package

  5. The help

API

Two functions are provided to solve or optimize 01 linear programming problem. Parameters are the same as C++ API. These function returns a scalar:

  • If a solution is found:

    • if the problem is a minimization: the value of the solution found.

    • if the problem is a maximization: the inverse of the solution found.

  • If no solution is found, we use the limits of the objective function (minimal and maximal value possible.

    • if the problem is a minimization: the maximal value possible + the remaining constraints.

    • if the problem is a maximization: the inverse of the minimal value possible + the remaining constraints.

  • If a error occurred (not enough memory, problem error etc.):

    • if the problem is a minimization: the maximal value possible + the number of constraints .

    • if the problem is a maximization: the inverse of the minimal value possible + the number of constraints.

solve_01lp_problem <- function(file_path, limit = 1000L, theta = 0.5,
  delta = 1e-4, constraint_order = 0L, kappa_min = 0.1, kappa_step = 1e-4,
  kappa_max = 1.0, alpha = 1.0, w = 500L, time_limit = 10.0, seed = -1L,
  thread = 1L, norm = 4L, pushing_k_factor = 0.9,
  pushing_objective_amplifier = 5.0, pushes_limit = 10L,
  pushing_iteration_limit = 20L, init_policy = 0L, init_random = 0.5,
  float_type = 1L, verbose = TRUE)

optimize_01lp_problem <- function(file_path, limit = 1000L, theta = 0.5,
  delta = 1e-4, constraint_order = 0L, kappa_min = 0.1, kappa_step = 1e-4,
  kappa_max = 1.0, alpha = 1.0, w = 500L, time_limit = 10.0, seed = -1L,
  thread = 1L, norm = 4L, pushing_k_factor = 0.9,
  pushing_objective_amplifier = 5.0, pushes_limit = 10L,
  pushing_iteration_limit = 20L, init_policy = 0L, init_random = 0.5,
  float_type = 1L, verbose = TRUE)

Usage

Apply morris method to found useful parameters:

library(rbaryonyx)
library(sensitivity)

factors = c("theta", "delta", "constraint_order", "kappa_min", "kappa_step",
  "kappa_max", "alpha", "w", "norm", "pushing_k_factor",
  "pushing_objective_amplifier", "pushes_limit", "pushing_iteration_limit",
  "float_type")

bounds = data.frame(
  min=c(
    0,     # theta
    0,     # delta
    0,     # constraint_order
    0,     # kappa_min
    1e-16, # kappa_step
    1.0,   # kappa_max
    0.0,   # alpha
    50,    # w
    0,     # norm
    0.1,   # pushing_k_factor
    1.0,   # pushing_objective_amplifier
    10,    # pushes_limit
    20,    # pushing_iteration_limit
    0,     # init_policy
    0.0,   # init_random
    0
    ),    # float_type
max=c(
    1,     # theta
    0,     # delta
    4,     # constraint_order
    0.1,   # kappa_min
    1e-1,  # kappa_step
    1.0,   # kappa_max
    2.0,   # alpha
    500,   # w
    4,     # norm
    1,     # pushing_k_factor
    10.0,  # pushing_objective_amplifier
    100,   # pushes_limit
    200,   # pushing_iteration_limit
    2,     # init_policy
    1.0,   # init_random
    2))    # float_type

rownames(bounds) <- factors

morrisDesign <- morris(model = NULL,
                factors = factors,
                r = 10,
                design=list(type="oat", levels=10, grid.jump=5),
                binf = bounds$min,
                bsup = bounds$max,
                scale=TRUE)

solve_lp <- function(x, file_path, limit=10000, time_limit=10, seed=123456789, thread=1) {
  r <- rbaryonyx::solve_01lp_problem(file_path = file_path,
                   limit = limit,
                   theta = x["theta"],
                   delta = x["delta"],
                   constraint_order = x["constraint_order"],
                   kappa_min = x["kappa_min"],
                   kappa_step = x["kappa_step"],
                   kappa_max = x["kappa_max"],
                   alpha = x["alpha"],
                   w = x["w"],
                   time_limit = time_limit,
                   seed = seed,
                   thread = thread,
                   norm = x["norm"],
                   pushing_k_factor = x["pushing_k_factor"],
                   pushing_objective_amplifier = x["pushing_objective_amplifier,"],
                   pushes_limit = x["pushes_limit"],
                   pushing_iteration_limit = x["pushing_iteration_limit"],
                   init_policy = x["init_policy"],
                   init_random = x["init_random"],
                   float_type = x["float_type"])

  return(r)
}

r = apply(morrisDesign$X, 1, solve_lp, file_path="verger_5_5.lp", thread=1, limit=10000, time_limit=10, seed=123456789)

morrisDesign$Y <- r
mu <- apply(morrisDesign$X,2,mean)
mu.star <- apply(morrisDesign$X, 2, function(x) mean(abs(x)))
sigma <- apply(morrisDesign$ee, 2, sd)

apply(morrisDesign$X, 2, function(v) plot(factor(v), r))

Use RGenoud method to found best paramter values:

library(rgenoud)
library(rbaryonyx)
library(parallel)

optim_gen_lp <- function(x) {
  r <- rbaryonyx::optimize_01lp_problem(
           file_path = "rail507pre.lp",
           limit = -1,
           theta = x[1],
           delta = x[2],
           constraint_order = 0,
           kappa_min = x[3],
           kappa_step = x[4],
           kappa_max = 1.0,
           alpha = 1.0,
           w = 60,
           time_limit = 10,
           seed = 123654785,
           thread = 4,
           norm = 0,
           pushing_k_factor = 1,
           pushing_objective_amplifier = 10,
           pushes_limit = 20,
           pushing_iteration_limit = 50,
           init_policy = 0,
           init_random = 0.5,
           float_type = 1,
           verbose = FALSE)

  return(r)
}

d = matrix(c(0.0, 0.00001, 0.0, 1e-10,
             1.0, 0.001,   0.2, 1e-4),
             nrow=4, ncol=2)

s = c(0.5, 0.003226, 0.1, 1e-8)

no_cores <- detectCores() - 1
cl <- makeCluster(no_cores, outfile="debug.txt")

claw1 <- genoud(optim_gen_lp, nvars=4,
                Domains=d,
                starting.values=s,
                cluster=cl,
                boundary.enforcement=1,
                max=FALSE, pop.size=10)

Upgrade

To upgrade to the latest version of rbaryonyx, under bash (or equivalent):

cd baryonyx
git pull -r (1)
cd build
make -j4 (2)
make install
R CMD REMOVE rbaryonyx (3)
cd rbaryonyx
Rscript -e 'library(Rcpp); compileAttributes(".")'
Rscript -e 'library(devtools); devtools::document()'
cd ..
R CMD build rbaryonyx (4)
R CMD INSTALL rbaryonyx_1.0.tar.gz
  1. Update the baryonyx and rbaryonyx from Git

  2. Build and install baryonyx

  3. Remove old rbaryonyx package

  4. Build and install

About

binary/integer linear programming solver

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C++ 97.1%
  • CMake 2.0%
  • Other 0.9%