杰瑞科技汇

python scipy linprog

Of course! Let's dive deep into scipy.optimize.linprog, the powerful function in SciPy for solving linear programming (LP) problems.

python scipy linprog-图1
(图片来源网络,侵删)

What is Linear Programming?

Linear Programming is a method to achieve the best outcome (like maximum profit or lowest cost) in a mathematical model whose requirements are represented by linear relationships. It's a fundamental technique in operations research, economics, and engineering.

A standard LP problem has the following components:

  1. Decision Variables: The quantities you want to determine (e.g., how many of product A and B to produce).
  2. Objective Function: A linear equation you want to maximize or minimize (e.g., maximize profit: 3x + 5y).
  3. Constraints: A set of linear inequalities or equations that the decision variables must satisfy (e.g., limited labor hours: 2x + 4y <= 100).

The scipy.optimize.linprog Function

scipy.optimize.linprog solves a linear programming problem in the following standard form:

Minimize: cᵀx

python scipy linprog-图2
(图片来源网络,侵删)

Subject to: A_ub x <= b_ub A_eq x = b_eq lb <= x <= ub

Where:

  • x is a vector of decision variables (what we're solving for).
  • c is a vector of coefficients in the objective function.
  • A_ub and b_ub define the inequality constraints (<=).
  • A_eq and b_eq define the equality constraints ().
  • lb and ub are lower and upper bounds on the decision variables x.

Key Point: SciPy's linprog only solves minimization problems. If you want to maximize a function, you can simply minimize its negative.


Function Signature and Parameters

scipy.optimize.linprog(c, A_ub=None, b_ub=None, A_eq=None, b_eq=None, bounds=None, method='highs', ...)

Let's break down the most important parameters:

python scipy linprog-图3
(图片来源网络,侵删)
Parameter Description
c A 1-D array representing the coefficients of the linear objective function to be minimized.
A_ub 2-D array defining the left-hand side of the inequality constraints. Each row corresponds to one constraint.
b_ub 1-D array defining the right-hand side of the inequality constraints. A_ub @ x <= b_ub.
A_eq 2-D array defining the left-hand side of the equality constraints. A_eq @ x == b_eq.
b_eq 1-D array defining the right-hand side of the equality constraints.
bounds Sequence of (min, max) pairs for each element in x, defining the variable bounds. Use None for one of min or max to indicate no bound. e.g., [(0, None), (0, 10)].
method The solver to use. 'highs' is the default and recommended modern solver. Other options include 'highs-ds' and 'highs-ipm' for different variants of the HiGHS solver. The legacy 'simplex' and 'interior-point' solvers are also available but not recommended for new problems.

Return Value

The function returns an OptimizeResult object, which is a dictionary-like object with several useful attributes:

Attribute Description
x The values of the decision variables that minimize the objective function.
fun The optimal value of the objective function (c @ x).
success A boolean indicating if the optimization was successful.
message A string describing the termination reason.
slack The slack values for the inequality constraints (b_ub - A_ub @ x). A value of 0 means the constraint is active (binding).
con The residuals (values) of the equality constraints (A_eq @ x - b_eq). These should be close to zero for a feasible solution.

Practical Examples

Let's work through two common examples.

Example 1: Maximization Problem (A Classic "Product Mix")

A company produces two products, A and B. Product A gives a profit of $3 per unit, and Product B gives a profit of $5 per unit. The production is constrained by two resources:

  1. Labor: 100 hours available. Product A takes 2 hours, and Product B takes 4 hours.
  2. Materials: 120 kg available. Product A takes 4 kg, and Product B takes 3 kg.

Goal: How many units of A and B should be produced to maximize profit?

Formulate the Math Problem:

  • Decision Variables:
    • x = number of units of Product A
    • y = number of units of Product B
  • Objective Function (Maximize Profit):
    • P = 3x + 5y
  • Constraints:
    • Labor: 2x + 4y <= 100
    • Materials: 4x + 3y <= 120
    • Non-negativity: x >= 0, y >= 0

Convert to SciPy's Standard Form (Minimization):

  • We need to minimize -P.
  • c = [-3, -5]
  • Inequality constraints A_ub x <= b_ub:
    • A_ub = [[2, 4], [4, 3]]
    • b_ub = [100, 120]
  • Bounds: x >= 0, y >= 0. We can set this using the bounds parameter.

Python Code:

import numpy as np
from scipy.optimize import linprog
# Coefficients of the objective function (to be minimized)
# We want to maximize P = 3x + 5y, so we minimize -P = -3x - 5y
c = [-3, -5]
 # Coefficients for the inequality constraints (A_ub @ x <= b_ub)
# 2x + 4y <= 100
# 4x + 3y <= 120
A_ub = [[2, 4],
        [4, 3]]
b_ub = [100, 120]
# Bounds for x and y (x >= 0, y >= 0)
# Each tuple is (min, max) for a variable.
# None for max means no upper bound.
bounds = [(0, None), (0, None)]
# Solve the linear programming problem
# 'highs' is the recommended default solver
result = linprog(c, A_ub=A_ub, b_ub=b_ub, bounds=bounds, method='highs')
# Print the results
if result.success:
    print("Optimization successful!")
    print(f"Optimal values (x, y): {result.x}")
    print(f"Maximum Profit: ${-result.fun:.2f}") # Negate the result because we minimized -P
    print("\nConstraint Slack:")
    print(f"Labor constraint slack: {result.slack[0]:.2f} hours")
    print(f"Material constraint slack: {result.slack[1]:.2f} kg")
else:
    print("Optimization failed.")
    print("Message:", result.message)

Output:

Optimization successful!
Optimal values (x, y): [10. 20.]
Maximum Profit: $130.00
Constraint Slack:
Labor constraint slack: 0.00 hours
Material constraint slack: 10.00 kg

Interpretation: The company should produce 10 units of A and 20 units of B for a maximum profit of $130. The labor constraint is fully used (slack is 0), but 10 kg of materials are left over.


Example 2: Problem with Equality and Variable Bounds

Problem: Minimize the function: f(x, y) = x + y Subject to:

  1. x + y = 10 (Equality constraint)
  2. x >= 2 (Lower bound)
  3. y <= 8 (Upper bound)

Formulate for SciPy:

  • c = [1, 1]
  • Equality constraint A_eq x = b_eq:
    • A_eq = [[1, 1]]
    • b_eq = [10]
  • Variable bounds:
    • x: [2, None]
    • y: [None, 8]

Python Code:

import numpy as np
from scipy.optimize import linprog
# Coefficients of the objective function (to be minimized)
c = [1, 1]
# Coefficients for the equality constraint (A_eq @ x == b_eq)
A_eq = [[1, 1]]
b_eq = [10]
# Bounds for x and y
# x >= 2, y <= 8
bounds
分享:
扫描分享到社交APP
上一篇
下一篇