Class: LpSolver::Variable

Inherits:
Object
  • Object
show all
Defined in:
lib/lpsolver/variable.rb

Overview

Note:

Variable * Variable produces a QuadraticExpression (for QP). Variable * Scalar produces a LinearExpression (for LP).

Represents a decision variable in an LP/MIP/QP model.

Variables are the building blocks of optimization models. Each variable represents a quantity to be determined by the solver (e.g., production levels, investment amounts, resource allocations).

Variables support arithmetic operators for building expressions and comparison operators for creating constraints. The operator overloading enables a natural, mathematical DSL:

x = model.add_variable(:x, lb: 0)
model.add_constraint(:budget, (x * 2 + y) <= 100)

Examples:

Creating a variable

x = model.add_variable(:x, lb: 0, ub: 100, integer: false)
x.index    # => 0
x.name     # => :x

Using in expressions

expr = x * 2 + y * 3          # LinearExpression
quad = x * x + y * y          # QuadraticExpression
spec = (x * 2 + y) <= 100     # ConstraintSpec

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(index, name) ⇒ Variable

Creates a new Variable instance.

Parameters:

  • index (Integer)

    The internal index assigned by the model.

  • name (Symbol)

    The human-readable name of this variable.



42
43
44
45
# File 'lib/lpsolver/variable.rb', line 42

def initialize(index, name)
  @index = index
  @name = name
end

Instance Attribute Details

#indexInteger (readonly)

Returns The internal index of this variable in the model. This is used internally to map the variable to a column in the solver’s constraint matrix.

Returns:

  • (Integer)

    The internal index of this variable in the model. This is used internally to map the variable to a column in the solver’s constraint matrix.



33
34
35
# File 'lib/lpsolver/variable.rb', line 33

def index
  @index
end

#nameSymbol (readonly)

Returns The human-readable name of this variable.

Returns:

  • (Symbol)

    The human-readable name of this variable.



36
37
38
# File 'lib/lpsolver/variable.rb', line 36

def name
  @name
end

Instance Method Details

#*(other) ⇒ LinearExpression, QuadraticExpression

Multiplies this variable by a scalar or another variable.

When multiplied by a Numeric, returns a LinearExpression with this variable scaled by the given coefficient. When multiplied by another Variable, returns a QuadraticExpression representing the product term (used for quadratic objectives in QP).

Parameters:

  • other (Numeric, Variable)

    The multiplier.

Returns:

  • (LinearExpression)

    When other is a Numeric. Example: ‘x * 2` → LinearExpression with terms => 2.0

  • (QuadraticExpression)

    When other is a Variable. Example: ‘x * y` → QuadraticExpression with terms [[0, 1, 1.0]]



59
60
61
62
63
64
65
# File 'lib/lpsolver/variable.rb', line 59

def *(other)
  if other.is_a?(Variable)
    QuadraticExpression.new({}, [[@index, other.index, 1.0]])
  else
    LinearExpression.new({ @index => other.to_f })
  end
end

#+(other) ⇒ LinearExpression

Adds another variable, expression, or constant to this variable.

Creates a new LinearExpression containing the sum of this variable and the other operand.

Examples:

Adding two variables

(x + y).terms  # => {0 => 1.0, 1 => 1.0}

Adding a constant

(x + 5).constant  # => 5.0

Parameters:

Returns:



78
79
80
81
82
83
84
85
86
# File 'lib/lpsolver/variable.rb', line 78

def +(other)
  if other.is_a?(Variable)
    LinearExpression.new({ @index => 1.0, other.index => 1.0 })
  elsif other.is_a?(LinearExpression)
    LinearExpression.new(merge_terms({ @index => 1.0 }, other.terms), other.constant)
  else
    LinearExpression.new({ @index => 1.0 }, other.to_f)
  end
end

#-(other) ⇒ LinearExpression

Subtracts another variable, expression, or constant from this variable.

Creates a new LinearExpression containing the difference between this variable and the other operand.

Examples:

Subtracting two variables

(x - y).terms  # => {0 => 1.0, 1 => -1.0}

Subtracting a constant

(x - 5).constant  # => -5.0

Parameters:

Returns:



99
100
101
102
103
104
105
106
107
# File 'lib/lpsolver/variable.rb', line 99

def -(other)
  if other.is_a?(Variable)
    LinearExpression.new({ @index => 1.0, other.index => -1.0 })
  elsif other.is_a?(LinearExpression)
    LinearExpression.new(negate_add_terms({ @index => 1.0 }, other.terms), -other.constant)
  else
    LinearExpression.new({ @index => 1.0 }, -other.to_f)
  end
end

#-@LinearExpression

Returns a LinearExpression with this variable negated.

Examples:

(-x).terms  # => {0 => -1.0}

Returns:



114
115
116
# File 'lib/lpsolver/variable.rb', line 114

def -@
  LinearExpression.new({ @index => -1.0 })
end

#<=(other) ⇒ ConstraintSpec

Creates a less-than-or-equal-to constraint specification.

This is used with Model#add_constraint to define upper bounds on linear expressions. The constraint represents: expression <= value.

Examples:

model.add_constraint(:budget, (x * 2 + y) <= 100)

Parameters:

  • value (Numeric)

    The right-hand side upper bound.

  • other (Object)

Returns:



128
129
130
# File 'lib/lpsolver/variable.rb', line 128

def <=(other)
  ConstraintSpec.new(:le, { @index => 1.0 }, 0, other.to_f)
end

#==(other) ⇒ ConstraintSpec

Creates an equality constraint specification.

This is used with Model#add_constraint to define exact values for linear expressions. The constraint represents: expression == value.

Examples:

model.add_constraint(:weights, (x + y + z) == 1)

Parameters:

  • value (Numeric)

    The exact value the expression must equal.

  • other (Object)

Returns:



156
157
158
# File 'lib/lpsolver/variable.rb', line 156

def ==(other)
  ConstraintSpec.new(:eq, { @index => 1.0 }, 0, other.to_f)
end

#>=(other) ⇒ ConstraintSpec

Creates a greater-than-or-equal-to constraint specification.

This is used with Model#add_constraint to define lower bounds on linear expressions. The constraint represents: expression >= value.

Examples:

model.add_constraint(:demand, (x + y * 2) >= 50)

Parameters:

  • value (Numeric)

    The right-hand side lower bound.

  • other (Object)

Returns:



142
143
144
# File 'lib/lpsolver/variable.rb', line 142

def >=(other)
  ConstraintSpec.new(:ge, { @index => 1.0 }, 0, other.to_f)
end

#equals?(other) ⇒ Boolean Also known as: eql?

Checks if two variables refer to the same underlying variable.

Parameters:

  • other (Object)

    The object to compare against.

Returns:

  • (Boolean)

    True if other is a Variable with the same index.



164
165
166
# File 'lib/lpsolver/variable.rb', line 164

def equals?(other)
  other.is_a?(Variable) && other.index == @index
end

#hashInteger

Returns the hash code based on this variable’s index.

Returns:

  • (Integer)

    The hash code of the variable’s index.



189
190
191
# File 'lib/lpsolver/variable.rb', line 189

def hash
  @index.hash
end

#to_sString

Returns a string representation of this variable.

Examples:

x.to_s  # => "@x(0)"

Returns:

  • (String)

    A string in the format “@name(index)”.



173
174
175
# File 'lib/lpsolver/variable.rb', line 173

def to_s
  "@#{@name}(#{@index})"
end

#to_symSymbol

Converts this variable’s name to a Symbol.

Examples:

x.to_sym  # => :x

Returns:

  • (Symbol)

    The variable’s name.



182
183
184
# File 'lib/lpsolver/variable.rb', line 182

def to_sym
  @name
end