Created
March 22, 2021 04:46
-
-
Save mtsmfm/26b5090f9a305347401d364dd6245b37 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class LpGen | |
INFINITY = Float::INFINITY | |
module HasMembers | |
def set_coefficient(var, x) | |
members << Member.new(var, x) | |
end | |
def members | |
@members ||= [] | |
end | |
end | |
class Member < Struct.new(:var, :x) | |
def to_s | |
"#{x} #{var.to_s}" | |
end | |
end | |
class Objective | |
include HasMembers | |
attr_reader :type | |
def set_maximization | |
@type = :max | |
end | |
def set_minimization | |
@type = :min | |
end | |
def to_s | |
<<~LP | |
#{type == :min ? "Minimize" : "Maximize"} | |
obj: #{members.join(" + ")} | |
LP | |
end | |
def inspect | |
to_s | |
end | |
end | |
class Constraint | |
attr_reader :min, :max | |
include HasMembers | |
def self.rhs(min, max) | |
case | |
when min == max | |
"= #{min}" | |
when min == -INFINITY | |
"<= #{max}" | |
when max == INFINITY | |
">= #{min}" | |
else | |
raise | |
end | |
end | |
def initialize(min, max, i) | |
@min = min | |
@max = max | |
@i = i | |
end | |
def to_s | |
<<~LP | |
c#{@i}: #{members.join(" + ")} #{Constraint.rhs(min, max)} | |
LP | |
end | |
def inspect | |
to_s | |
end | |
end | |
class BoolVar < Struct.new(:name) | |
def to_s | |
"B#{name.tr(",.", "_")}" | |
end | |
end | |
class IntVar < Struct.new(:min, :max, :name) | |
def to_s | |
"I#{name.tr(",.", "_")}" | |
end | |
def bound | |
"#{to_s} #{Constraint.rhs(min, max)}" | |
end | |
end | |
def objective | |
@objective ||= Objective.new | |
end | |
def constraint(min, max) | |
Constraint.new(min, max, constraints.size).tap do |c| | |
constraints << c | |
end | |
end | |
def constraints | |
@constraints ||= [] | |
end | |
def infinity | |
INFINITY | |
end | |
def bool_var(*args) | |
BoolVar.new(*args).tap do |v| | |
bool_vars << v | |
end | |
end | |
def int_var(*args) | |
IntVar.new(*args).tap do |v| | |
int_vars << v | |
end | |
end | |
def bool_vars | |
@bool_vars ||= Set.new | |
end | |
def int_vars | |
@int_vars ||= Set.new | |
end | |
def to_s | |
<<~LP | |
#{objective.to_s} | |
Subject to | |
#{constraints.map {|c| " #{c.to_s}" }.join()} | |
Bounds | |
#{int_vars.map(&:bound).join("\n")} | |
Binary | |
#{bool_vars.map(&:to_s).join(" ")} | |
End | |
LP | |
end | |
def inspect | |
to_s | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment