guruby 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: