Class: LpSolver::LinearExpression

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

Overview

Represents a linear expression: sum of (coefficient * variable) + constant.

Linear expressions are the fundamental building blocks of linear programming models. They represent quantities like costs, resource usage, or returns that scale linearly with decision variables.

A linear expression has the mathematical form:

c₀ + c₁·x₁ + c₂·x₂ + ... + cₙ·xₙ

where c₀ is the constant offset and cᵢ are the coefficients for each variable.

Examples:

Building a linear expression

x = model.add_variable(:x, lb: 0)
y = model.add_variable(:y, lb: 0)
expr = x * 2 + y * 3 + 5   # 2x + 3y + 5
expr.terms      # => {0 => 2.0, 1 => 3.0}
expr.constant   # => 5.0

Using in constraints

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

Using in objectives

model.set_objective(x * 2 + y * 3 + 5)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(terms = {}, constant = 0.0) ⇒ LinearExpression

Creates a new LinearExpression.

Parameters:

  • terms (Hash{Integer => Float}) (defaults to: {})

    Maps variable indices to coefficients.

  • constant (Float) (defaults to: 0.0)

    The constant offset (default: 0.0).



44
45
46
47
# File 'lib/lpsolver/linear_expression.rb', line 44

def initialize(terms = {}, constant = 0.0)
  @terms = terms
  @constant = constant
end

Instance Attribute Details

#constantFloat (readonly)

Returns The constant offset in the expression.

Examples:

(x * 2 + 5).constant  # => 5.0

Returns:

  • (Float)

    The constant offset in the expression.



38
39
40
# File 'lib/lpsolver/linear_expression.rb', line 38

def constant
  @constant
end

#termsHash{Integer => Float} (readonly)

Returns Maps variable indices to their coefficients. The keys are the internal indices assigned by the model, and the values are the floating-point coefficients.

Examples:

(x * 2 + y * 3).terms  # => {0 => 2.0, 1 => 3.0}

Returns:

  • (Hash{Integer => Float})

    Maps variable indices to their coefficients. The keys are the internal indices assigned by the model, and the values are the floating-point coefficients.



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

def terms
  @terms
end

Instance Method Details

#*(other) ⇒ LinearExpression

Multiplies this expression by a scalar.

Scales both the variable coefficients and the constant by the given factor.

Examples:

(x * 2 + 3) * 4  # => 8x + 12

Parameters:

  • scalar (Numeric)

    The scalar multiplier.

  • other (Object)

Returns:



119
120
121
122
123
124
125
# File 'lib/lpsolver/linear_expression.rb', line 119

def *(other)
  s = other.to_f
  LinearExpression.new(
    @terms.transform_values { |c| c * s },
    @constant * s
  )
end

#+(other) ⇒ LinearExpression, QuadraticExpression

Adds another expression, variable, constant, or quadratic expression.

When adding a LinearExpression or Variable, returns a new LinearExpression. When adding a QuadraticExpression, returns a new QuadraticExpression that combines the linear and quadratic parts.

Examples:

Adding two linear expressions

(x * 2 + 3) + (x + 5)  # => 3x + 8

Adding a quadratic expression

(x * 2) + (y * y)  # => QuadraticExpression with linear: {x => 2}, quadratic: [[y, y, 1]]

Parameters:

Returns:



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/lpsolver/linear_expression.rb', line 62

def +(other)
  if other.is_a?(Variable)
    LinearExpression.new(
      merge_terms(@terms, { other.index => 1.0 }),
      @constant
    )
  elsif other.is_a?(LinearExpression)
    LinearExpression.new(
      merge_terms(@terms, other.terms),
      @constant + other.constant
    )
  elsif other.is_a?(QuadraticExpression)
    new_linear = other.linear_terms.dup
    @terms.each { |idx, coeff| new_linear[idx] = (new_linear[idx] || 0) + coeff }
    QuadraticExpression.new(new_linear.reject { |_, v| v.zero? }, other.quadratic_terms.dup)
  else
    LinearExpression.new(@terms.dup, @constant + other.to_f)
  end
end

#-(other) ⇒ LinearExpression, QuadraticExpression

Subtracts another expression, variable, constant, or quadratic expression.

Examples:

Subtracting a linear expression

(x * 5 + 10) - (x * 2 + 3)  # => 3x + 7

Parameters:

Returns:



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/lpsolver/linear_expression.rb', line 89

def -(other)
  if other.is_a?(Variable)
    LinearExpression.new(
      merge_terms(@terms, { other.index => -1.0 }),
      @constant
    )
  elsif other.is_a?(LinearExpression)
    LinearExpression.new(
      merge_terms(@terms, negate_terms(other.terms)),
      @constant - other.constant
    )
  elsif other.is_a?(QuadraticExpression)
    new_linear = other.linear_terms.dup
    @terms.each { |idx, coeff| new_linear[idx] = (new_linear[idx] || 0) + coeff }
    neg_quad = other.quadratic_terms.map { |i1, i2, c| [i1, i2, -c] }
    QuadraticExpression.new(new_linear.reject { |_, v| v.zero? }, neg_quad)
  else
    LinearExpression.new(@terms.dup, @constant - other.to_f)
  end
end

#-@LinearExpression

Returns a LinearExpression with all coefficients and the constant negated.

Examples:

-(x * 3 + 5)  # => -3x - 5

Returns:



132
133
134
135
136
137
# File 'lib/lpsolver/linear_expression.rb', line 132

def -@
  LinearExpression.new(
    @terms.transform_values { |c| -c },
    -@constant
  )
end

#<=(other) ⇒ ConstraintSpec

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

Examples:

model.add_constraint(:c, (x * 2 + y * 3 + 5) <= 100)

Parameters:

  • value (Numeric)

    The right-hand side upper bound.

  • other (Object)

Returns:



146
147
148
# File 'lib/lpsolver/linear_expression.rb', line 146

def <=(other)
  ConstraintSpec.new(:le, @terms.dup, @constant, other.to_f)
end

#==(other) ⇒ ConstraintSpec

Creates an equality constraint specification.

Examples:

model.add_constraint(:c, (x * 2 + y * 3 + 5) == 75)

Parameters:

  • value (Numeric)

    The exact value the expression must equal.

  • other (Object)

Returns:



168
169
170
# File 'lib/lpsolver/linear_expression.rb', line 168

def ==(other)
  ConstraintSpec.new(:eq, @terms.dup, @constant, other.to_f)
end

#>=(other) ⇒ ConstraintSpec

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

Examples:

model.add_constraint(:c, (x * 2 + y * 3 + 5) >= 50)

Parameters:

  • value (Numeric)

    The right-hand side lower bound.

  • other (Object)

Returns:



157
158
159
# File 'lib/lpsolver/linear_expression.rb', line 157

def >=(other)
  ConstraintSpec.new(:ge, @terms.dup, @constant, other.to_f)
end