Skip to content

Syntax meant for easy creation of linear programs with anywhere from 1 to thousands of constraints. Built on top of rglpk. The syntax is similar to that of OPL Studio.

brg8/opl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

67 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OPL (pronounced Opal) is a Linear Programming syntax based off of OPL Studio.

The entire purpose of this gem is to allow you to write your linear programs or optimization problems in a simple, human-understandable way. So instead of 30 lines of code to set up a problem (as in the rglpk documentation), you can set up your problem like so:

maximize(  
  "x + y",  
subject_to([  
  "x <= 10",  
  "y <= 3"  
]))

I try to keep the tests up to date, so take a look in there for more examples. Run tests with

rspec tests.rb

A quick view at functionality:

Summation and Forall constraints:

maximize(  
  "sum(i in (0..3) x[i])",  
subject_to([  
  "forall(i in (0..3), x[i] <= 3)"  
]))

Easy specification of variable types:

lp = maximize(  
	"10x1 + 6x2 + 4x3",  
subject_to([  
	"x1 + x2 + x3 <= 100",  
	"10x1 + 4x2 + 5x3 <= 600",  
	"2x1 + 2x2 + 6x3 <= 300",  
	"x1 >= 0",  
	"x2 >= 0",  
	"x3 >= 0"  
],[  
	"BOOLEAN: x1",  
	"INTEGER: x3"  
]  
))

Access to epsilon for strict inequalities:

lp = maximize(  
	"x + y + z",  
subject_to([  
	"x + z < 2",  
	"y <= 4",  
],[  
	"INTEGER: y",  
	"EPSILON: 0.03"  
]  
))  

BE WARNED - When you specify a variable as INTEGER or BOOLEAN, you will be using the Branch & Cut method to solve the problem. This is very inefficient, and some seemingly easy problems can take forever to solve. You may have to formulate your problem in a clever way. Here is an example.

This problem would take B&C hours to solve:

lp = maximize(  
	"x + y + x[3]",  
subject_to([   
	"x + x[3] <= 2.5",  
	"y <= 4"  
],[  
	"INTEGER: x, y",  
]  
))  

But if we just use some common sense, we can make this model:

lp = maximize(  
	"x + y + x[3]",  
subject_to([  
	"x <= 2.5",  
	"x[3] <= 2.5",  
	"x + x[3] <= 2.5",  
	"y <= 4"  
],[  
	"INTEGER: x, y",  
]  
))  

Which is solvable in a few milliseconds and clearly does not affect the result.

Use ruby data matrices:

d = [[3,5,3],[1,2,3],[2,5,9]]

lp = maximize(
	"sum(i in [1,2], j in (0..1), d[i][j+1]*x[i-1][j])",
subject_to([
	"forall(i in (1..2), x[i-1][1] <= 100)",
	"forall(i in (0..2), j in (0..2), x[i][j] <= 200)"
],[
	"NONNEGATIVE: x",
	"DATA: {d => #{d}}"
]
))

Sudoku wrapper:

problem = [
  [0,0,0,2,6,0,7,0,1],
  [6,8,0,0,7,0,0,9,0],
  [1,9,0,0,0,4,5,0,0],
  [8,2,0,1,0,0,0,4,0],
  [0,0,4,6,0,2,9,0,0],
  [0,5,0,0,0,3,0,2,8],
  [0,0,9,3,0,0,0,7,4],
  [0,4,0,0,5,0,0,3,6],
  [7,0,3,0,1,8,0,0,0]
]
sudoku = OPL::Sudoku.new problem
sudoku.solve
sudoku.format_solution
sudoku.print_solution

About

Syntax meant for easy creation of linear programs with anywhere from 1 to thousands of constraints. Built on top of rglpk. The syntax is similar to that of OPL Studio.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages