Choosing a Solver ================= This guide helps you choose the right solver for your optimization problem. Quick Decision Tree ------------------- .. mermaid:: graph TD A[Start] --> B{Need Continuous Variables?} B -->|No| C{Budget/License?} B -->|Yes| D{Need Quadratic/SOCP?} C -->|Free| E[CP-SAT
Best for Scheduling] C -->|Commercial OK| F{Academic?} D -->|Yes| G{License Available?} D -->|No| H{Problem Size?} F -->|Yes| I[Gurobi or CPLEX
Free Academic License] F -->|No| I G -->|Yes| I G -->|No| J[Use Linearization
+ OR-Tools] H -->|Small/Medium| K[OR-Tools
Free, Good Performance] H -->|Large| L[Gurobi/CPLEX
Best Performance] H -->|Very Small| M[GLPK
Basic, Free] style E fill:#90EE90 style I fill:#FFD700 style J fill:#87CEEB style K fill:#90EE90 style L fill:#FFD700 style M fill:#DDA0DD Decision Factors ---------------- 1. Problem Type ~~~~~~~~~~~~~~~ **Linear Programming (LP)** Only continuous variables, linear constraints: .. code-block:: python # Example: Portfolio optimization max: profit_A * x_A + profit_B * x_B s.t.: x_A + x_B <= budget x_A, x_B >= 0 (continuous) **Recommendation:** - Best: Gurobi, CPLEX - Good: OR-Tools - Basic: GLPK **Mixed-Integer Programming (MIP)** Mix of continuous and integer/binary variables: .. code-block:: python # Example: Facility location max: revenue - fixed_cost * is_open s.t.: is_open in {0, 1} (binary) production >= 0 (continuous) **Recommendation:** - Best: Gurobi, CPLEX - Good: OR-Tools - Basic: GLPK (small problems), CP-SAT (integer only) **Quadratic Programming (QP)** Quadratic objective or constraints: .. code-block:: python # Example: Variance minimization min: x^T * Covariance * x s.t.: sum(x) = 1 **Recommendation:** - Best: Gurobi, CPLEX - Alternative: OR-Tools with linearization **Scheduling/Assignment** Pure integer assignment problems: .. code-block:: python # Example: Employee scheduling assign[worker, shift] in {0, 1} s.t.: sum(assign[w, s] for s in shifts) <= 5 # Max 5 shifts per worker **Recommendation:** - Best: CP-SAT (designed for this) - Alternative: Gurobi, CPLEX, OR-Tools 2. Budget and Licensing ~~~~~~~~~~~~~~~~~~~~~~~~ **Free and Open-Source** **OR-Tools** - License: Apache 2.0 (permissive) - Cost: Free - Best for: Most LP/MIP problems - Performance: Good **GLPK** - License: GPL v3 (copyleft) - Cost: Free - Best for: Small problems, teaching - Performance: Moderate - **Warning:** GPL license has viral copyleft provisions **CP-SAT** - License: Apache 2.0 (permissive) - Cost: Free - Best for: Integer programming, scheduling - Performance: Excellent (for its domain) **Commercial with Academic Licenses** **Gurobi** - License: Commercial (free academic) - Cost: Free for academic use, commercial pricing for businesses - Best for: Large-scale, production, research - Performance: Excellent - Get academic license: https://www.gurobi.com/academia/ **CPLEX** - License: Commercial (free academic via IBM Academic Initiative) - Cost: Free for academic use, commercial pricing for businesses - Best for: Enterprise, academic research - Performance: Excellent - Get academic license: IBM Academic Initiative 3. Problem Size ~~~~~~~~~~~~~~~ **Small Problems** (<1000 variables, <1000 constraints) All solvers work well: - OR-Tools: Good default - GLPK: Acceptable for simple problems - CP-SAT: Excellent for integer problems - Gurobi/CPLEX: Overkill but work perfectly **Medium Problems** (1K-100K variables/constraints) - **Best:** Gurobi, CPLEX - **Good:** OR-Tools - **Avoid:** GLPK (too slow) **Large Problems** (>100K variables/constraints) - **Best:** Gurobi, CPLEX (commercial features, parallel solving) - **Acceptable:** OR-Tools (may be slower) - **Avoid:** GLPK, CP-SAT 4. Required Features ~~~~~~~~~~~~~~~~~~~~ **Quadratic Programming** - **Native support:** Gurobi, CPLEX only - **Via linearization:** OR-Tools, GLPK (with LumiX linearization) **Second-Order Cone Programming (SOCP)** - **Supported:** Gurobi, CPLEX - **Not supported:** OR-Tools, GLPK, CP-SAT **Piecewise-Linear Functions** - **Native:** Gurobi, CPLEX - **Via linearization:** OR-Tools, GLPK (with LumiX) **SOS Constraints (SOS1, SOS2)** - **Supported:** Gurobi, CPLEX, OR-Tools - **Not supported:** GLPK, CP-SAT **Indicator Constraints** - **Supported:** Gurobi, CPLEX, OR-Tools - **Not supported:** GLPK **Sensitivity Analysis** - **Supported:** Gurobi, CPLEX, GLPK - **Not supported:** OR-Tools, CP-SAT **Callbacks (Lazy Constraints, Cuts)** - **Supported:** Gurobi, CPLEX - **Not supported:** OR-Tools, GLPK, CP-SAT **Warm Start** - **Supported:** Gurobi, CPLEX, OR-Tools, CP-SAT - **Not supported:** GLPK 5. Performance Requirements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Interactive/Real-Time** (sub-second response) - Gurobi, CPLEX (best) - OR-Tools (good for smaller problems) - CP-SAT (excellent for scheduling) **Batch Processing** (minutes acceptable) - Any solver works - Consider OR-Tools to save licensing costs **Production Systems** (reliability critical) - Gurobi, CPLEX (proven, supported) - OR-Tools (good, but less enterprise support) Solver Comparison ----------------- Feature Matrix ~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 :widths: 20 15 15 15 15 20 * - Feature - OR-Tools - Gurobi - CPLEX - GLPK - CP-SAT * - **Linear (LP)** - ✓ - ✓ - ✓ - ✓ - ✗ * - **Integer (MIP)** - ✓ - ✓ - ✓ - ✓ - ✓ (only) * - **Quadratic** - ✗ - ✓ - ✓ - ✗ - ✗ * - **SOCP** - ✗ - ✓ - ✓ - ✗ - ✗ * - **SOS1/SOS2** - ✓ - ✓ - ✓ - ✗ - ✗ * - **Indicator** - ✓ - ✓ - ✓ - ✗ - ✗ * - **PWL** - ✗ - ✓ - ✓ - ✗ - ✗ * - **Sensitivity** - ✗ - ✓ - ✓ - ✓ - ✗ * - **Callbacks** - ✗ - ✓ - ✓ - ✗ - ✗ * - **Warm Start** - ✓ - ✓ - ✓ - ✗ - ✓ * - **Parallel** - ✓ - ✓ - ✓ - ✗ - ✓ * - **License** - Free - Commercial - Commercial - Free (GPL) - Free Performance Comparison ~~~~~~~~~~~~~~~~~~~~~~ Relative performance (problem-dependent): .. list-table:: :header-rows: 1 :widths: 25 15 15 15 15 15 * - Problem Type - OR-Tools - Gurobi - CPLEX - GLPK - CP-SAT * - Small LP - 9/10 - 10/10 - 10/10 - 7/10 - N/A * - Large LP - 7/10 - 10/10 - 10/10 - 3/10 - N/A * - Small MIP - 8/10 - 10/10 - 10/10 - 6/10 - 9/10 * - Large MIP - 7/10 - 10/10 - 10/10 - 2/10 - 7/10 * - Quadratic - N/A - 10/10 - 10/10 - N/A - N/A * - Scheduling - 7/10 - 10/10 - 10/10 - 3/10 - 10/10 Practical Recommendations -------------------------- By Use Case ~~~~~~~~~~~ **Academic Research** .. code-block:: python # Get free Gurobi academic license optimizer = LXOptimizer().use_solver("gurobi") **Why?** - Free for academic use - Best performance - Full features (sensitivity, callbacks) - Industry-standard for publications **Startup/Small Business** .. code-block:: python # Start with OR-Tools optimizer = LXOptimizer().use_solver("ortools") **Why?** - No licensing costs - Good performance for most problems - Can upgrade to Gurobi/CPLEX later if needed **Enterprise** .. code-block:: python # Use Gurobi or CPLEX optimizer = LXOptimizer().use_solver("gurobi") **Why?** - Best performance - Professional support - Proven reliability - Worth the cost for business-critical applications **Open-Source Project** .. code-block:: python # Use OR-Tools (Apache 2.0 license) optimizer = LXOptimizer().use_solver("ortools") **Why?** - Permissive license (no copyleft) - No commercial restrictions - Avoid GLPK's GPL restrictions **Teaching/Learning** .. code-block:: python # OR-Tools or GLPK optimizer = LXOptimizer().use_solver("ortools") **Why?** - Free - Easy to install - Good for learning concepts **Scheduling/Rostering** .. code-block:: python # Use CP-SAT optimizer = LXOptimizer().use_solver("cpsat") **Why?** - Designed for scheduling problems - Excellent performance - Free - Handles complex logical constraints Migration Strategy ~~~~~~~~~~~~~~~~~~ Start Small, Scale Up ^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: python # Phase 1: Prototype with OR-Tools (free) optimizer = LXOptimizer().use_solver("ortools") solution = optimizer.solve(prototype_model) # Phase 2: Test with Gurobi academic license optimizer = LXOptimizer().use_solver("gurobi") solution = optimizer.solve(full_model) # Phase 3: Production with commercial Gurobi optimizer = LXOptimizer().use_solver("gurobi") solution = optimizer.solve(production_model, Threads=32) Graceful Degradation ^^^^^^^^^^^^^^^^^^^^ .. code-block:: python def get_best_available_solver(): """Try solvers in order of preference.""" try: return LXOptimizer().use_solver("gurobi") except ImportError: try: return LXOptimizer().use_solver("cplex") except ImportError: # Fall back to free solver return LXOptimizer().use_solver("ortools") optimizer = get_best_available_solver() Benchmarking ~~~~~~~~~~~~ Always benchmark with your specific problem: .. code-block:: python import time solvers = ["ortools", "gurobi", "cplex"] results = {} for solver_name in solvers: try: optimizer = LXOptimizer().use_solver(solver_name) start = time.time() solution = optimizer.solve(model, time_limit=300) elapsed = time.time() - start results[solver_name] = { "time": elapsed, "objective": solution.objective_value, "status": solution.status } except ImportError: print(f"{solver_name} not available") # Compare results for solver, result in results.items(): print(f"{solver}: {result['time']:.2f}s, obj={result['objective']:.2f}") Common Scenarios ---------------- Scenario 1: Student Project ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Requirements:** - Free - Learn optimization - Small problems **Recommendation:** OR-Tools .. code-block:: python optimizer = LXOptimizer().use_solver("ortools") Scenario 2: PhD Research ~~~~~~~~~~~~~~~~~~~~~~~~~ **Requirements:** - Academic use - Need best performance - Publish results **Recommendation:** Gurobi (free academic license) .. code-block:: python optimizer = LXOptimizer().use_solver("gurobi") Scenario 3: SaaS Product ~~~~~~~~~~~~~~~~~~~~~~~~~ **Requirements:** - Cost-sensitive - Medium-scale problems - Need reliability **Recommendation:** OR-Tools initially, evaluate Gurobi if performance becomes issue .. code-block:: python # Start with OR-Tools optimizer = LXOptimizer().use_solver("ortools") # Upgrade path if needed: # optimizer = LXOptimizer().use_solver("gurobi") Scenario 4: Enterprise Optimization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Requirements:** - Large-scale - Production-critical - Need support **Recommendation:** Gurobi or CPLEX .. code-block:: python optimizer = LXOptimizer().use_solver("gurobi") solution = optimizer.solve(model, Threads=64, time_limit=3600) Scenario 5: Employee Scheduling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Requirements:** - Complex logical constraints - Integer variables only - Free solution preferred **Recommendation:** CP-SAT .. code-block:: python optimizer = ( LXOptimizer() .use_solver("cpsat") .enable_rational_conversion() # For any float coefficients ) Next Steps ---------- - :doc:`using-optimizer` - How to use the optimizer - :doc:`solver-configuration` - Configure solver parameters - :doc:`solver-capabilities` - Understanding capabilities - :doc:`/getting-started/solvers` - Installation and setup - :doc:`/api/solvers/index` - API reference