Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LpSelect

This gem provides both an FFI interface to the lp_solve library and a simplified interface designed to pick from a set of choices to satisfy constraints (LPSelect).

lp_solve is a Mixed Integer Linear Programming (MILP) solver. It solves pure linear, (mixed) integer/binary, semi-cont and special ordered sets (SOS) models. lp_solve is written in ANSI C and can be compiled on many different platforms like Linux and WINDOWS.

The lp_solve library is included and dynamically loaded. The gem will look for the library in the lib/binaries folder, and searches for the first library it can load in this order:

liblpsolve55.dylib liblpsolve55.dylib-ppc liblpsolve55.dylib.x86-64 liblpsolve55.so liblpsolve55.so-ux64 lpsolve55.dll

You can download and compile the liblpsolve library from http://sourceforge.net/projects/lpsolve/

LPSelect is designed for selecting a set of things that satisfies as many constraints as possible. The lp_select_test.rb test is a contrived example showing how it can be used to select a fruit salad at the lowest cost that satisfies the most people. The price of each fruit is a weight and the objective is to minimize the cost (ie weight) of the selected fruits. Each person's choices is added as a constraint row.

Installation

Add this line to your application's Gemfile:

gem 'lp_select'

And then execute:

$ bundle

Or install it yourself as:

$ gem install lp_select

Usage

Current usage is focused on a handful of known problems to be solved, but it is easily extensible.

The lp_solve library uses 1 indexed arrays.

There is more example usage in the LPSelect library and tests

# Make a three row five column equation
@lp = LPSolve::make_lp(3, 5) 

# Set some column names
LPSolve::set_col_name(@lp, 1, "fred")
LPSolve::set_col_name(@lp, 2, "bob")
# Add a constraint and a row name, the API expects a 1 indexed array
constraint_vars = [0, 0, 1]
FFI::MemoryPointer.new(:double, constraint_vars.size) do |p|
  p.write_array_of_double(constraint_vars)
  LPSolve::add_constraint(@lp, p, LPSelect::EQ, 1.0.to_f)
end
LPSolve::set_row_name(@lp, 1, "onlyBob")

# Set the objective function and minimize it
constraint_vars = [1.0, 3.0]
FFI::MemoryPointer.new(:double, constraint_vars.size) do |p|
  p.write_array_of_double(constraint_vars)
  LPSolve::set_obj_fn(@lp, p)
end
LPSolve::set_minim(@lp)

# Solve it and retreive the result
LPSolve::solve(@lp) 
@objective = LPSolve::get_objective(@lp)

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Contributors

  • James Prior
  • Jake Sower
  • Mattias Ekberg

Releases

Packages

Used by

Contributors

Languages