Class: Amor::Model
- Inherits:
-
Object
- Object
- Amor::Model
- Defined in:
- lib/amor/model.rb
Instance Attribute Summary collapse
-
#blocks ⇒ Object
readonly
Returns the value of attribute blocks.
-
#bounded ⇒ Object
readonly
Returns the value of attribute bounded.
-
#constraints ⇒ Object
readonly
Returns the value of attribute constraints.
-
#solved ⇒ Object
readonly
Returns the value of attribute solved.
Class Method Summary collapse
-
.from_file(filename) ⇒ Object
Create a model from a file.
-
.from_string(string) ⇒ Object
Create a model from a given string.
Instance Method Summary collapse
- #binary(variable) ⇒ Object (also: #bin)
-
#block ⇒ Object
Creates a new block and makes sure that constraints added in yield are added to block.
- #dec_string ⇒ Object
- #for_all(container) ⇒ Object (also: #forall)
- #gcg ⇒ Object
-
#initialize ⇒ Model
constructor
A new instance of Model.
- #integer(variable) ⇒ Object (also: #int)
- #internal_index(index) ⇒ Object
- #lp_string ⇒ Object
-
#max(expression) ⇒ Object
(also: #maximize)
Add a maximization objective.
-
#min(expression) ⇒ Object
(also: #minimize)
Add a minimization objective.
- #objective ⇒ Object (also: #obj)
- #parse_scip_output(scip_result) ⇒ Object
- #positive(variable) ⇒ Object
- #save_dec(filename) ⇒ Object
- #save_lp(filename) ⇒ Object
- #scip ⇒ Object
-
#st(constraint) ⇒ Object
(also: #subject_to)
Add a constraint.
- #sum(container) ⇒ Object
-
#x(index) ⇒ Object
(also: #var)
Return the variable for that index if already existing or a new one.
Constructor Details
#initialize ⇒ Model
Returns a new instance of Model.
8 9 10 11 12 |
# File 'lib/amor/model.rb', line 8 def initialize @variables = Array.new @indices = Hash.new @constraints = Array.new end |
Instance Attribute Details
#blocks ⇒ Object (readonly)
Returns the value of attribute blocks.
6 7 8 |
# File 'lib/amor/model.rb', line 6 def blocks @blocks end |
#bounded ⇒ Object (readonly)
Returns the value of attribute bounded.
6 7 8 |
# File 'lib/amor/model.rb', line 6 def bounded @bounded end |
#constraints ⇒ Object (readonly)
Returns the value of attribute constraints.
6 7 8 |
# File 'lib/amor/model.rb', line 6 def constraints @constraints end |
#solved ⇒ Object (readonly)
Returns the value of attribute solved.
6 7 8 |
# File 'lib/amor/model.rb', line 6 def solved @solved end |
Class Method Details
.from_file(filename) ⇒ Object
Create a model from a file
64 65 66 |
# File 'lib/amor/model.rb', line 64 def self.from_file(filename) Model.from_string(File.read(filename)) end |
Instance Method Details
#binary(variable) ⇒ Object Also known as: bin
124 125 126 127 |
# File 'lib/amor/model.rb', line 124 def binary(variable) variable.type = :binary return variable end |
#block ⇒ Object
Creates a new block and makes sure that constraints added in yield are added to block
177 178 179 180 181 182 |
# File 'lib/amor/model.rb', line 177 def block (@blocks ||= Array.new) << Block.new @in_block = @blocks.last yield @in_block = nil end |
#dec_string ⇒ Object
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/amor/model.rb', line 184 def dec_string result = ["PRESOLVED 0", "NBLOCKS #{@blocks.size}"] @blocks.each_with_index do |block, i| result << block.dec_string(i + 1) end result << "MASTERCONSS" # Remaining constraints @blocks.inject(@constraints) {|mem, block| mem - block.constraints}.each do |constraint| result << constraint.lp_name end result.join("\n") end |
#for_all(container) ⇒ Object Also known as: forall
101 102 103 104 105 106 107 108 109 |
# File 'lib/amor/model.rb', line 101 def for_all(container) container.each do |e| result = yield(e) if result.is_a?(Constraint) self.st result end end return nil end |
#gcg ⇒ Object
204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/amor/model.rb', line 204 def gcg self.save_lp('__temp.lp') self.save_dec('__temp.dec') gcg_result = `gcg -f __temp.lp -d __temp.dec` File.open('gcg.log', 'w') {|file| file.puts gcg_result} File.delete('__temp.lp') File.delete('__temp.dec') parse_scip_output gcg_result rescue Errno::ENOENT => e puts "Could not find GCG. Please make sure that GCG is installed and you can execute 'gcg'." raise e end |
#integer(variable) ⇒ Object Also known as: int
118 119 120 121 |
# File 'lib/amor/model.rb', line 118 def integer(variable) variable.type = :integer return variable end |
#internal_index(index) ⇒ Object
68 69 70 |
# File 'lib/amor/model.rb', line 68 def internal_index(index) @indices[index] end |
#lp_string ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/amor/model.rb', line 72 def lp_string result = @objective.lp_string result << "\nSubject To\n" result << @constraints.each_with_index.map do |constraint, i| " #{constraint.lp_string}" end.join("\n") # Bounds section bounded_vars = @variables.each_with_index.select{|v| v[0].lb} result << "\nBounds" if bounded_vars.size > 0 bounded_vars.each{|v| result << "\n 0 <= x#{v[1]+1}"} # Variable type section integer_vars = @variables.each_with_index.select{|v| v[0].type == :integer} result << "\nGenerals\n " if integer_vars.size > 0 result << integer_vars.map{|v| "x#{v[1]+1}"}.join(" ") binary_vars = @variables.each_with_index.select{|v| v[0].type == :binary} result << "\nBinary\n " if binary_vars.size > 0 result << binary_vars.map{|v| "x#{v[1]+1}"}.join(" ") result << "\nEnd" return result end |
#max(expression) ⇒ Object Also known as: maximize
Add a maximization objective
42 43 44 |
# File 'lib/amor/model.rb', line 42 def max(expression) @objective = Objective.new(:maximize, expression) end |
#min(expression) ⇒ Object Also known as: minimize
Add a minimization objective
36 37 38 |
# File 'lib/amor/model.rb', line 36 def min(expression) @objective = Objective.new(:minimize, expression) end |
#objective ⇒ Object Also known as: obj
25 26 27 28 29 30 31 |
# File 'lib/amor/model.rb', line 25 def objective if @solved @objective_value else @objective end end |
#parse_scip_output(scip_result) ⇒ Object
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/amor/model.rb', line 148 def parse_scip_output(scip_result) solution_section = false scip_result.each_line do |line| if !@solved && line =~ /problem is solved \[([\w\s]*)\]/ @solved = true if $1 == 'optimal solution found' @bounded = true elsif $1 == 'unbounded' @bounded = false elsif $1 == 'infeasible' @infeasible = true else raise "Unknown solve status: #{$1}" end end solution_section = true if line =~ /primal solution:/ solution_section = false if line =~ /Statistics/n if solution_section @objective_value = $1 if line =~ /objective value:\s*([\.\d]+)/ if line =~ /x(\d+)\s*([\.\d]+)/ @variables[$1.to_i-1].value = $2.to_f end end end end |
#positive(variable) ⇒ Object
130 131 132 133 |
# File 'lib/amor/model.rb', line 130 def positive(variable) variable.lb = 0 return variable end |
#save_dec(filename) ⇒ Object
200 201 202 |
# File 'lib/amor/model.rb', line 200 def save_dec(filename) File.open(filename, 'w') {|file| file.puts self.dec_string} end |
#save_lp(filename) ⇒ Object
97 98 99 |
# File 'lib/amor/model.rb', line 97 def save_lp(filename) File.open(filename, 'w') {|file| file.puts self.lp_string} end |
#scip ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/amor/model.rb', line 135 def scip self.save_lp('__temp.lp') scip_result = `scip -f __temp.lp` File.open('scip.log', 'w') {|file| file.puts scip_result} File.delete('__temp.lp') parse_scip_output scip_result rescue Errno::ENOENT => e puts "Could not find SCIP. Please make sure that SCIP is installed and you can execute 'scip'." raise e end |
#st(constraint) ⇒ Object Also known as: subject_to
Add a constraint
48 49 50 51 52 53 |
# File 'lib/amor/model.rb', line 48 def st(constraint) constraint.index = @constraints.size @constraints << constraint @in_block.add_constraint(constraint) if @in_block return constraint end |
#sum(container) ⇒ Object
112 113 114 115 116 |
# File 'lib/amor/model.rb', line 112 def sum(container) container[1..-1].inject(yield(container[0])) do |m, e| m + yield(e) end end |
#x(index) ⇒ Object Also known as: var
Return the variable for that index if already existing or a new one
15 16 17 18 19 20 21 22 |
# File 'lib/amor/model.rb', line 15 def x(index) variable = @variables[@indices[index] ||= @indices.size] ||= Variable.new(self, index) if @solved variable.value || 0 else variable end end |