Pyomo对接CPLEX:如何获取不可行LP极射线及对偶无界LP的无界射线?
Let's tackle your two questions about retrieving rays using Pyomo with CPLEX, step by step:
When your linear program is infeasible, CPLEX can return a Farkas ray (the extreme ray that proves the problem's infeasibility) — but Pyomo doesn't expose this directly through its high-level API. You'll need to access the underlying CPLEX Python API instance to grab it.
Here's a practical breakdown:
- First, solve your model and confirm it's infeasible using Pyomo's solver results.
- Then, fetch the raw CPLEX model from the Pyomo solver object.
- Use CPLEX's
solution.get_farkas_ray()method to retrieve the extreme ray.
Example code:
import pyomo.environ as pyo from pyomo.opt import SolverStatus, TerminationCondition # Build an infeasible LP model model = pyo.ConcreteModel() model.x = pyo.Var(within=pyo.NonNegativeReals) model.c1 = pyo.Constraint(expr=model.x <= -1) # Impossible constraint to satisfy # Solve with CPLEX solver = pyo.SolverFactory('cplex') results = solver.solve(model, tee=False) # Verify infeasibility status if (results.solver.status == SolverStatus.infeasible and results.solver.termination_condition == TerminationCondition.infeasible): # Access the underlying CPLEX instance cplex_model = solver._solver_model # Get the Farkas extreme ray farkas_ray = cplex_model.solution.get_farkas_ray() print("Extreme ray (Farkas) for infeasible LP:", farkas_ray)
This ray corresponds to dual multipliers on your constraints, showing exactly which combination of constraints creates the inconsistency.
First, a quick duality note: If the primal LP is feasible and the dual is unbounded, strong duality theory tells us the primal must also be unbounded. That said, yes — you can absolutely retrieve the unbounded ray using Pyomo + CPLEX, just like the infeasible case, by leveraging the underlying CPLEX API.
Here's how to do it:
- Solve the model and check if the termination condition is
unbounded. - Grab the CPLEX instance and use
solution.get_ray()to get the direction vector that drives the primal objective to infinity. - As you noted, since the primal is feasible, you can also pull dual values using CPLEX's
get_dual_values()if needed.
Example code:
# Build an unbounded primal LP (feasible, objective can grow infinitely) model = pyo.ConcreteModel() model.x = pyo.Var(within=pyo.NonNegativeReals) model.obj = pyo.Objective(expr=model.x, sense=pyo.maximize) model.c1 = pyo.Constraint(expr=model.x >= 0) # Solve with CPLEX solver = pyo.SolverFactory('cplex') results = solver.solve(model, tee=False) # Check for unboundedness if results.solver.termination_condition == TerminationCondition.unbounded: cplex_model = solver._solver_model # Get the unbounded ray unbounded_ray = cplex_model.solution.get_ray() print("Unbounded ray for primal LP:", unbounded_ray) # Retrieve dual values (feasible primal allows this, as you noted) dual_values = cplex_model.solution.get_dual_values() print("Dual variable values:", dual_values)
The unbounded ray gives you the direction in which you can move the primal variables to make the objective function infinitely large (or small, depending on your objective sense) while still satisfying all constraints.
内容的提问来源于stack exchange,提问作者SantaClaus

