guruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,37 @@
1
+ require 'ffi'
2
+
3
+ module Gurobi
4
+ extend FFI::Library
5
+ ffi_lib File.join(ENV['GUROBI_HOME'], 'lib/libgurobi56.so')
6
+
7
+ attach_function :GRBloadenv, [:pointer, :string], :int
8
+ attach_function :GRBsetintparam, [:pointer, :string, :int], :int
9
+ attach_function :GRBgeterrormsg, [:pointer], :string
10
+ attach_function :GRBfreeenv, [:pointer], :void
11
+
12
+ attach_function :GRBnewmodel, [:pointer, :pointer, :string, :int,
13
+ :pointer, :pointer, :pointer, :pointer,
14
+ :pointer], :int
15
+ attach_function :GRBupdatemodel, [:pointer], :int
16
+ attach_function :GRBfreemodel, [:pointer], :int
17
+
18
+ attach_function :GRBaddvar, [:pointer, :int, :pointer, :pointer,
19
+ :double, :double, :double, :char, :string], :int
20
+ attach_function :GRBaddvars, [:pointer, :int, :int, :pointer, :pointer,
21
+ :pointer, :pointer, :pointer, :pointer,
22
+ :pointer, :pointer], :int
23
+ attach_function :GRBaddconstr, [:pointer, :int, :pointer, :pointer, :char,
24
+ :double, :string], :int
25
+ attach_function :GRBoptimize, [:pointer], :int
26
+ attach_function :GRBcomputeIIS, [:pointer], :int
27
+ attach_function :GRBwrite, [:pointer, :string], :int
28
+
29
+ attach_function :GRBsetintattr, [:pointer, :string, :int], :int
30
+
31
+ attach_function :GRBgetintattr, [:pointer, :string, :pointer], :int
32
+ attach_function :GRBgetdblattr, [:pointer, :string, :pointer], :int
33
+ attach_function :GRBgetdblattrarray, [:pointer, :string, :int, :int,
34
+ :pointer], :int
35
+ attach_function :GRBsetdblattrarray, [:pointer, :string, :int, :int,
36
+ :pointer], :int
37
+ end
@@ -0,0 +1,121 @@
1
+ require_relative 'ext'
2
+
3
+ module Guruby
4
+ class Model
5
+ attr_reader :ptr, :environment, :variables, :constraints
6
+
7
+ def initialize(env)
8
+ @environment = env
9
+
10
+ @ptr = FFI::MemoryPointer.new :pointer
11
+ Gurobi.GRBnewmodel env.ptr, @ptr, 'model', 0, nil, nil, nil, nil, nil
12
+ @ptr = @ptr.read_pointer
13
+
14
+ # Ensure the model is freed
15
+ ObjectSpace.define_finalizer self, self.class.finalize(@ptr)
16
+
17
+ @var_count = 0
18
+ @variables = []
19
+ @constraints = []
20
+ end
21
+
22
+ # Add new objects (variables and constraints) to the model
23
+ def <<(obj)
24
+ case obj
25
+ when Variable
26
+ add_variable obj
27
+ when Constraint
28
+ add_constraint obj
29
+ else
30
+ fail TypeError
31
+ end
32
+ end
33
+
34
+ # Update the model
35
+ def update
36
+ ret = Gurobi.GRBupdatemodel @ptr
37
+ fail if ret != 0
38
+ end
39
+
40
+ # Write the model to a file
41
+ def write(filename)
42
+ Gurobi.GRBwrite @ptr, filename
43
+ end
44
+
45
+ # Set the sense of the model
46
+ def set_sense(sense)
47
+ ret = Gurobi.GRBsetintattr @ptr, GRB_INT_ATTR_MODELSENSE, sense
48
+ fail if ret != 0
49
+ end
50
+
51
+ # Optimize the model
52
+ def optimize
53
+ ret = Gurobi.GRBoptimize @ptr
54
+ fail if ret != 0
55
+ end
56
+
57
+ # Get the status of the model
58
+ def status
59
+ intptr = FFI::MemoryPointer.new :pointer
60
+ ret = Gurobi.GRBgetintattr @ptr, GRB_INT_ATTR_STATUS, intptr
61
+ fail if ret != 0
62
+ intptr.read_int
63
+ end
64
+
65
+ # Compute an irreducible inconsistent subsytem for the model
66
+ def compute_IIS
67
+ ret = Gurobi.GRBcomputeIIS @ptr
68
+ fail if ret != 0
69
+ end
70
+
71
+ # The value of the objective function
72
+ def objective_value
73
+ dblptr = FFI::MemoryPointer.new :pointer
74
+ ret = Gurobi.GRBgetdblattr @ptr, GRB_DBL_ATTR_OBJVAL, dblptr
75
+ fail if ret != 0
76
+ dblptr.read_double
77
+ end
78
+
79
+ private
80
+
81
+ # Free the model
82
+ def self.finalize(ptr)
83
+ proc { Gurobi.GRBfreemodel ptr }
84
+ end
85
+
86
+ # Add a new variable to the model
87
+ def add_variable(var)
88
+ ret = Gurobi.GRBaddvar @ptr, 0, nil, nil, var.coefficient,
89
+ var.lower_bound, var.upper_bound,
90
+ var.type.ord, var.name
91
+ fail if ret != 0
92
+
93
+ # Update the variable to track the index in the model
94
+ var.instance_variable_set :@model, self
95
+ var.instance_variable_set :@index, @var_count
96
+ @var_count += 1
97
+
98
+ @variables << var
99
+ end
100
+
101
+ # Add a new constraint to the model
102
+ def add_constraint(constr)
103
+ terms = constr.expression.terms
104
+ indexes_buffer = FFI::MemoryPointer.new :int, terms.length
105
+ indexes_buffer.write_array_of_int(terms.each_key.map do |var|
106
+ var.instance_variable_get(:@index)
107
+ end)
108
+
109
+ values_buffer = FFI::MemoryPointer.new :double, terms.length
110
+ values_buffer.write_array_of_double terms.values
111
+
112
+ ret = Gurobi.GRBaddconstr @ptr, terms.length,
113
+ indexes_buffer, values_buffer,
114
+ constr.sense.ord, constr.rhs, constr.name
115
+ fail if ret != 0
116
+
117
+ @constraints << constr
118
+ end
119
+
120
+ end
121
+ end
data/lib/guruby/var.rb ADDED
@@ -0,0 +1,88 @@
1
+ module Guruby
2
+ class Variable
3
+ attr_reader :lower_bound, :upper_bound, :coefficient, :type, :name, :model
4
+
5
+ def initialize(lb, ub, coeff, type, name = nil)
6
+ @lower_bound = lb
7
+ @upper_bound = ub
8
+ @coefficient = coeff
9
+ @type = type
10
+ @name = name
11
+
12
+ # These will be populated when this is added to a model
13
+ @model = nil
14
+ @index = nil
15
+ end
16
+
17
+ # Set the variable lower bound
18
+ def lower_bound=(lb)
19
+ set_double_attribute GRB_DBL_ATTR_LB, lb
20
+ @lower_bound = lb
21
+ end
22
+
23
+ # Set the variable upper bound
24
+ def upper_bound=(ub)
25
+ set_double_attribute GRB_DBL_ATTR_UB, ub
26
+ @upper_bound = ub
27
+ end
28
+
29
+ # Get the final value of this variable
30
+ def value
31
+ # Model must be solved to have a value
32
+ return nil unless @model && @model.status == GRB_OPTIMAL
33
+
34
+ dblptr = FFI::MemoryPointer.new :pointer
35
+ Gurobi::GRBgetdblattrarray @model.instance_variable_get(:@ptr),
36
+ GRB_DBL_ATTR_X, @index, 1, dblptr
37
+ value = dblptr.read_array_of_double(1)[0]
38
+
39
+ case @type
40
+ when GRB_INTEGER
41
+ value.round
42
+ when GRB_BINARY
43
+ [false, true][value.round]
44
+ else
45
+ value
46
+ end
47
+ end
48
+
49
+ # Create a {LinExpr} consisting of a single term
50
+ # which is this variable multiplied by a constant
51
+ def *(coeff)
52
+ fail TypeError unless coeff.is_a? Numeric
53
+
54
+ LinExpr.new({ self => coeff })
55
+ end
56
+
57
+ def +(other)
58
+ case other
59
+ when LinExpr
60
+ other + self * 1
61
+ when Variable
62
+ self * 1 + other * 1
63
+ else
64
+ fail TypeError
65
+ end
66
+ end
67
+
68
+ # Produce the name of the variable and the value if the model is solved
69
+ def inspect
70
+ if @model && @model.status == GRB_OPTIMAL
71
+ value = self.value
72
+ else
73
+ value = '?'
74
+ end
75
+
76
+ "#{@name} = #{value}"
77
+ end
78
+
79
+ private
80
+
81
+ def set_double_attribute(name, value)
82
+ buffer = FFI::MemoryPointer.new :double, 1
83
+ buffer.write_array_of_double [value]
84
+ ret = Gurobi.GRBsetdblattrarray model.ptr, name, @index, 1, buffer
85
+ fail if ret != 0
86
+ end
87
+ end
88
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: guruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Michael Mior
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.9'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.9'
27
+ description: Guruby is a Ruby interface to the Gurobi solver
28
+ email: michael.mior@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - lib/guruby.rb
34
+ - lib/guruby/constr.rb
35
+ - lib/guruby/env.rb
36
+ - lib/guruby/expr.rb
37
+ - lib/guruby/ext.rb
38
+ - lib/guruby/ext/constants.rb
39
+ - lib/guruby/ext/gurobi.rb
40
+ - lib/guruby/model.rb
41
+ - lib/guruby/var.rb
42
+ homepage: https://github.com/michaelmior/guruby
43
+ licenses:
44
+ - GPLv3
45
+ metadata: {}
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 2.4.6
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: A Ruby interface to the Gurobi solver
66
+ test_files: []
67
+ has_rdoc: