NVIDIA cuOpt Examples

repository·main·Indexed 19 days ago

https://github.com/nvidia/cuopt-examples

A collection of demonstrations for NVIDIA cuOpt, a GPU-accelerated engine for solving complex decision optimization problems including Mixed Integer Programming, Linear Programming, and Vehicle Routing. Features include the EARLI hybrid framework for VRP using Reinforcement Learning, a C-based JSON to C API driver, benchmark suites for comparing APIs (Python, C, Julia, CVXPY, AMPL, PuLP, GAMS), and a car rental optimization MILP model.

Tokens
70.2K
Snippets
164
Records
278
Agent score
63%

What's inside cuopt-examples

  1. Understand the Sandbox layout

    main

    The sandbox environment uses a specific directory structure for scripts, data, and virtual environments. Use these paths to locate your workspace files and the cuOpt Python environment.

    PathPurpose
    /sandbox/Workspace root — scripts, some uploads
    /sandbox/.openclaw/workspace/Common chat/workspace file uploads
    /sandbox/workspace/Alternative upload target (openshell)
    /sandbox/probe_cuopt.pyConnectivity probe (no env side effects)
    /sandbox/smoke_*.pyGate 3 smoke tests
    /sandbox/.openclaw-data/cuopt/bin/activatecuOpt Python venv
    /sandbox/.openclaw/skills/Installed skills (upstream + local)
  2. Car Rental Optimization: Optimization Logic and Data

    main

    The optimization process uses the following components:

    Data Inputs

    • Locations: 4 locations (Airport, Downtown, and 2 Suburbs).
    • Demand: 7-day demand patterns.
    • Revenue: Rates by location ranging from $75 to $120 per rental.
    • Costs: Weekly operational cost of $240 per car and specific transfer costs between locations.

    Optimization Model

    • Objective: Maximize revenue - operational costs - transfer costs.
    • Decision Variables:
      • Fleet size (Integer)
      • Availability (Continuous)
      • Rentals (Continuous)
      • Transfers (Continuous)
    • Constraints:
      • Demand limits
      • Availability
      • Flow conservation
      • Fleet capacity

    Outputs and Analysis

    The model provides:

    • Optimal fleet size and allocation.
    • Financial metrics (profit, margins, costs).
    • Utilization rates by location.
    • Demand satisfaction tracking.
    • Transfer operation schedules.
    • Visualizations including heatmaps and charts.
  3. Understand the cuOpt Agent Project Structure

    main

    The cuopt-agent repository is organized into several functional areas:

    • cuopt_agent/: The core application logic.
      • src/nat_cuopt_agent/: Contains the agent implementation, including the orchestrator (deepagent_fn.py), subagent factory, and NAT plugin registration.
      • configs/: YAML configurations for NAT (serve + eval).
      • data/: Datasets and sample prompts for testing.
      • docker/: Dockerfiles for production and development.
    • skills/: Modular agent capabilities.
      • max-supply/: Contains supply chain planning skills and debugging resources.
      • cuopt/: A symlink to external cuOpt skills (LP/MILP formulations and API patterns).
    • deploy/compose/: Docker Compose files for production and development environments.
    • external/: Git submodules containing cuopt and nat-ui (Chat UI).
  4. Solve Diet Optimization problems with NVIDIA cuOpt Python API

    main

    You can use the NVIDIA cuOpt Python API to solve diet optimization problems. These problems typically aim to minimize the total cost of a diet while satisfying specific nutritional requirements using a mix of foods with varying prices and nutritional values.

    There are two primary modeling approaches provided in the examples:

    1. Linear Programming (LP): Used when food serving sizes can be fractional. This approach allows for sensitivity analysis by extracting:
      • DualValue: To identify which nutritional constraints are driving the cost at the margin.
      • ReducedCost: To determine how far an unused food is from being economically viable to include in the diet.
    2. Mixed-Integer Linear Programming (MILP): Used when food serving sizes must be whole numbers (integers) rather than fractions.
  5. Solve Portfolio Optimization problems with cuOpt

    main

    Use the NVIDIA cuOpt Python API to solve various portfolio optimization problems via Jupyter notebooks. The examples cover different mathematical formulations including:

    • CVaR (Conditional Value at Risk): Maximizing expected return while minimizing risk.
    • QP (Quadratic Programming): Balancing expected return against the risk of losses.
    • Multi-Objective Optimization: Tracing the efficient frontier (return vs. risk) using an ε-constraint sweep. This method allows you to read the dual values from cuOpt's barrier (interior-point) solver to determine the sensitivity d(variance)/d(return) at each point.
    • Advanced Workflows: Construction of efficient frontiers, backtesting strategies, turnover optimization, and Mean-CVaR optimization.
  6. What is EARLI and how does it use cuOpt?

    main

    EARLI (Evolutionary Algorithm with RL Initialization) is a hybrid framework designed to accelerate solving the Vehicle Routing Problem (VRP). It combines Reinforcement Learning (RL) with NVIDIA's cuOpt genetic algorithm solver through a three-step workflow:

    1. Offline Training: An RL agent learns to generate high-quality solutions by interacting with a dataset of problem instances.
    2. Inference: When presented with a new problem instance, the trained RL agent quickly generates $K$ candidate solutions.
    3. cuOpt Optimization: These $K$ solutions are injected into the cuOpt solver as its initial population, allowing the genetic algorithm to start from a high-quality baseline and refine the solutions more efficiently than starting from scratch.

    This approach leverages data generalization to accelerate the time required to find state-of-the-art solutions.

  7. Identify cuOpt intent via language clusters

    main

    cuOpt matches the meaning of a request, not specific keywords. You do not need the user to explicitly say "minimize" or "optimal" to use cuOpt. The following intent families are valid triggers:

    Intent familyExample phrasings
    Schedule / timetable"build a season schedule", "plan the season", "set up game times", "put these on the calendar", "when should each game happen"
    Assign / allocate"assign games to slots", "allocate shifts", "place jobs on machines", "who works when"
    Route / visit"plan deliveries", "best routes for trucks", "visit all stops"
    Optimize explicitly"minimize cost", "maximize profit", "best plan", "optimal mix"
    Feasible / valid plan"a valid schedule", "feasible assignment", "make it work under these rules", "respect all constraints"

    Paraphrase rule: If a request can be interpreted as "turn this data into a constraint-respecting plan," treat it as a cuOpt task.

  8. Handle feasibility vs. optimization requests

    main

    In this sandbox, feasibility and optimization use the same solver. There is no need to switch to a different tool (like a greedy Python script) for feasibility tasks.

    User framingMeaningAction
    Feasible / valid / make it workHard constraints must holdUse cuOpt to find a satisfying solution (MILP/LP/QP/routing with constraints).
    Minimize / maximize / best / optimalHard constraints + objectiveUse cuOpt; add or emphasize the objective function.
    No objective statedConstraints only (+ optional default objective)Model constraints; ask one objective question or state a default; use cuOpt.

    Note: Do not split tasks by thinking "feasibility $\rightarrow$ greedy Python" and "optimization $\rightarrow$ cuOpt." Feasibility under discrete rules is a MILP/routing problem that cuOpt is built to handle.

  9. How GAMSPy symbols and models work together

    main

    GAMSPy uses a hierarchical structure to build optimization models:

    1. Container: A Container acts as a centralized hub that gathers all sets, parameters, variables, and equations.
    2. Sets: Define the indices (e.g., plants, markets) for the model. They can be declared separately or combined with data assignment.
    3. Parameters: Indexed data (e.g., supply, demand, costs). They use a domain attribute to link to specific Set objects.
    4. Variables: The decision variables (e.g., shipment quantities) defined with a domain and a type (e.g., "Positive").
    5. Equations: Mathematical constraints. They require a declaration (name, domain) and a definition (the algebraic relationship).
    6. Model: Consolidates equations, an objective function, a Sense (e.g., Sense.MIN), and a problem type (e.g., "LP").
    from gamspy import Container, Set, Parameter, Variable, Equation, Model, Sum, Sense
    
    m = Container()
    
    # Define Sets
    i = Set(container=m, name="i", records=["seattle", "san-diego"])
    j = Set(container=m, name="j", records=["new-york", "chicago"])
    
    # Define Parameters
    a = Parameter(container=m, name="a", domain=i, records=["seattle", 350])
    
    # Define Variables
    x = Variable(container=m, name="x", domain=[i, j], type="Positive")
    
    # Define Equations
    supply = Equation(container=m, name="supply", domain=i)
    supply[i] = Sum(j, x[i, j]) <= a[i]
    
    # Define Model
    obj = Sum((i, j), x[i, j])
    transport = Model(m, name="transport", equations=[supply], problem="LP", sense=Sense.MIN, objective=obj)
  10. Interpret Reduced Cost for Unused Options

    main

    ReducedCost acts as a 'near-miss' signal for variables that are not currently being used (often resting at a bound of 0).

    Key Concepts

    • Threshold for Use: A variable at its bound stays optimal if its objective coefficient is improved by less than |ReducedCost|. If improved by more, the variable may become worthwhile.
    • Identifying Near-Misses: To find the option closest to being included in the plan, look for the variable with the smallest |ReducedCost| among those currently at 0.
    • Unit Comparability: Like duals, reduced costs are objective-units per unit of that variable. To compare different variables, compare the |ReducedCost| as a fraction of its own objective coefficient (e.g., "needs a 3% price move").

    Important Limitations

    • Continuous Models Only: Like duals, these are only available for LP/QP solutions. For MILP, use differencing.
    • Degeneracy: A variable at its bound might have a ReducedCost of ~0 if an alternative optimum exists that uses it without changing the objective.
    # Unused options ranked by how close they are to paying off (LP / QP only).
    # Compare |reduced cost| within comparable-unit variables:
    near = [(v.VariableName, v.ReducedCost) for v in problem.getVariables() if abs(v.Value) < 1e-6]
    for name, rc in sorted(near, key=lambda kv: abs(kv[1])):
        note = ("already interchangeable — degenerate" if abs(rc) < 1e-9
                else f"~{abs(rc):.4g} coefficient improvement before it pays off")
        print(f"{name}: reduced cost {rc:+.4g}  ({note})")
  11. Choose the correct interface for your optimization problem

    main

    Select your interface based on the problem type and desired workflow:

    Problem TypeInterfaceSkill Chain
    LP, MILP, QPgRPC + Pythonnumerical-optimization-formulationcuopt-numerical-optimization-api-python
    VRP, TSP, PDPRESTrouting-formulationcuopt-routing-api-pythoncuopt-server-api-python

    Note: In this sandbox, the default for MILP scheduling is gRPC Python on port 5001. Use REST only if you explicitly require the server JSON workflow.

  12. Understand the Optimization From Data Orchestrator sequence

    main

    The orchestration follows a specific multi-step sequence to move from raw data to a solved cuOpt model.

    Execution Sequence

    Step 0 (Prerequisite): Perform the cuopt-sandbox sequence: probe $\rightarrow$ env $\rightarrow$ smoke. You must ensure the smoke test passes before attempting to generate schedules or heuristic outputs.

    1. optimization-intent-router: Identifies the optimization family (e.g., LP, MILP, QP, or routing).
    2. optimization-mode-router: Triggered only if there are signals for replay, audit, or export.
    3. tabular-optimization-ingestion: Interprets the roles of the provided tables.
    4. cuopt-model-mapper: Clarifies requirements if necessary, maps the interpreted data to a cuOpt model, and executes the solve.

    Handoffs after Step 4

    Depending on the intent identified in Step 1, the flow hands off to specific formulation and API skills:

    • LP / MILP / QP: $\rightarrow$ numerical-optimization-formulation $\rightarrow$ cuopt-numerical-optimization-api-python
    • Routing: $\rightarrow$ routing-formulation $\rightarrow$ cuopt-routing-api-python