Browse documentation
Docs/Functionality

Operations Research and Teaching

Keep the decision domain, mathematical assumptions and solver stopping evidence visible alongside a numerical result. A successful request means Grid handled the request; individual returned…

Operations research and teaching

Keep the decision domain, mathematical assumptions and solver stopping evidence visible alongside a numerical result. A successful request means Grid handled the request; individual returned values can still be errors or unconverged solver candidates.

For the revised 0.74.0 desktop build recipes, Lite's bundled CLI excludes the HiGHS mixed-integer backend, matching its host. A local CLI check that needs integer or binary solving reports the missing capability; it does not replace the problem with a continuous relaxation. Pro selects the solver and tensor implementations. gridctl source eval executes through the selected host, so that host's available implementations determine what it can run. Full ETL and training services remain host-owned. These source changes do not upgrade an already installed CLI or establish that a new package has been published.

Bounded nonlinear optimization

Assign the report once and project its fields:

Report = BOUNDED_MINIMIZE_N.REPORT(
  LAMBDA(x, (1 - INDEX(x, 1, 1))^2 + 100 * (INDEX(x, 1, 2) - INDEX(x, 1, 1)^2)^2),
  [-1.2, 1], [-2, -1], [2, 3], 1e-12, 10000
)
Design = Report.parameters
Objective = Report.objective
StoppingReason = Report.termination

The report uses grid.optimization.report.v1. status uses the common solver vocabulary: converged, target_hit, or budget_exhausted, with budget_reason where applicable. assurance distinguishes local_convergence from candidate_only. The inspector displays the stopping reason and lets you page through every parameter.

Nelder–Mead stops when the standard deviation of its simplex objective values meets the tolerance. This does not bound distance from the true minimizer, establish stationarity, or prove a global optimum. The report includes bounds, maximum bound violation, iterations, objective evaluations, tolerance and the iteration budget. The objective is evaluated at the returned bounded coordinates; that final check is included in the evaluation count. General constraint and stationarity residuals are unavailable (BLANK), never implied to be zero. An infinite bound is represented by a blank bound field and shown as unbounded.

The one-iteration Rosenbrock example returns a report with candidate [-1, 1], objective 4 and iteration_limit, explicitly marked budget_exhausted. Increasing the budget can improve it; reporting that candidate does not make it a converged solution. Invalid or nonfinite objective values are explicit evaluation failures. Cancellation aborts the resolve without publishing a partial report.

Migration: BOUNDED_MINIMIZE_N retains its successful 1 × n array shape, but now returns a detailed CALC error when its budget expires. Models that intentionally use an incumbent should call .REPORT and read .parameters after inspecting .status. Calling both functions separately requests two calculations; projecting the assigned report shares one solve. Defaults remain tolerance 1e-7 and 200 iterations. The companion requires a runtime that includes it; an older archived runtime is not upgraded by importing source.

Whole-weight knapsack

CS_KNAPSACK_01(values, weights, capacity) returns only the optimal total value. It requires equal-length numeric row or column vectors, finite values, positive whole weights and a nonnegative whole capacity. Negative item values are permitted: selecting no item has value zero. Empty paired vectors return zero. Zero/negative weights, fractions, text, nonfinite values and mismatched lengths fail explicitly.

The dynamic program supports at most 100,000 items, capacity 1,000,000 and 50,000,000 capacity updates, checked before allocation. Weights must be exact whole numbers no larger than 2^53−1. Weights larger than capacity cannot be selected. Overflowing total value is a numerical error; rescale values.

Migration: older versions truncated fractional weights/capacity, shortened unequal lists and omitted unsupported weights. Those behaviors changed the mathematical problem and are no longer accepted. Review existing calls for fractional or invalid weights and unequal lists. For fractional packing or selected-item output, use the existing mixed-integer formulation:

Values = [10, 9]
Weights = [1.5, 1.5]
Selected = MIXED_INTEGER_PROGRAM(Values, [1.5, 1.5; 1, 0; 0, 1], [2.5, 1, 1], [1, 1], TRUE)
PackedValue = SUMPRODUCT(Values, Selected)
PackedWeight = SUMPRODUCT(Weights, Selected)

The binary upper bounds matter. The exact answer is [1, 0], value 10 and weight 1.5. A build without the mixed-integer capability reports that limitation; it must not silently solve a continuous relaxation.

Read the decision, not just its array

LINEAR_PROGRAM.REPORT(c,A,b,maximize,variable_labels,row_labels,original_senses) returns the variables, contributions, resource use, slacks, binding flags and available marginal values from one existing solver result. Assign it once and read Report.parameters, Report.objective, or the tables in the inspector. MIXED_INTEGER_PROGRAM.REPORT adds integer_mask before maximize. Labels and original senses are optional; missing labels use explicit positions. Neither opening the inspector nor paging a table solves again.

The mathematical model remains Ax <= b, x >= 0. An original >= row must already be negated in A and b. Declare ">=" in original_senses to display its original direction and positive demand bound. Its original-bound marginal is the negative of its encoded-bound marginal. For example, minimizing 5x with -x <= -3 has an encoded-bound marginal of -5 and demand marginal +5. Equality in the authoring prototype uses two labeled opposite inequalities. Do not interpret either half as an independently adjustable equality price.

A converged LP/MIP report states the solver's tolerance-qualified result. Infeasibility, unboundedness, unsupported capability and budget completion stay distinct. Unavailable duals and counts are blank. HiGHS currently supplies no iteration/evaluation counts; Clarabel's iteration counter is available but is not an objective-evaluation count. The complete report retains requested solver settings and available solver provenance. These do not imply that every backend implements every option. IIS computation remains an explicit LINEAR_PROGRAM_SENSITIVITY(...,"iis") request.

CS_MAX_FLOW.REPORT(edges,source,sink) adds a labeled edge-flow table and cut certificate from the final residual network of the existing max-flow solve. It reports capacity, flow, node balances, source-side cut membership, cut capacity and flow/cut gap. Parallel edges receive net flow in author order; opposite flows are cancelled. The witness surface limits inputs to 128 nodes and 4,096 edges. The scalar CS_MAX_FLOW contract is unchanged.

Covariance disclosure

PORTFOLIO_QP_WEIGHTS.REPORT uses the existing symmetrization rule (Sigma + Sigma transpose)/2. It records maximum absolute asymmetry, maximum adjustment (half that asymmetry), and a materiality threshold of 1e-12 * max(maximum absolute entry, smallest positive normal number). Symmetric matrices produce no adjustment warning. Negative variances, nonfinite entries and scaled overflow fail explicitly. Other solver failures retain their actual cause; Grid does not guess positive semidefiniteness from a generic numerical failure. No additional eigendecomposition is performed, and the report explicitly says convexity/global optimality are not certified. The final objective corresponds to the returned normalized weights.

Capture and compare assumptions

In I/O → Scenarios, enter a scenario name and optionally the result symbols such as Report, Profit, FeasibilityCheck. Save scenario captures those results and declared effective inputs alongside the existing source, override and package identities. Leaving the result list empty saves inputs only. A capture containing an incomplete or stale result is refused.

Select a saved scenario with results and choose Compare with baseline. This explicitly captures the current model and compares two historical snapshots. It never temporarily restores the baseline to the active model, and never silently refreshes the baseline. Later edits do not change the comparison's timestamps or values. To study another historical state, restore it explicitly and save a newly named capture; the original snapshot remains.

For the production starter, capture labor 100, change it to 110, and compare: X changes 20→30, Y 60→50 and contribution 2,600→2,700. The local dual prediction is +100. At labor 170, labor becomes slack; the comparison flags the changed binding constraints and declines extrapolation. Matching binding flags alone are not a certified sensitivity range. With machine capacity 80, the starter's analytic intersection has both constraints binding for 80 < labor < 160.

Preview restore checks exact source and declared package identities before any input mutation. An imported copy may have a new model ID: compatible portable overrides are applied using the new model's current revision, while the historical capture retains its original identity. Missing overrides mean “use source default”; effective values are separately captured. Native input resource references remain outside portable scenario support.

Export the study record

Choose result symbols and Export study record. Grid downloads JSON and retains the same record under study-records/ in Files. Save/export the Grid document to include the asset in its archive. Records contain source and hash, effective declared inputs, saved overrides, selected full results and stopping status, declared packages, timestamp, available solver settings/provenance and runtime metadata. Capturing results is an explicit access and may calculate the selected cells; exporting never rewrites inputs.

The record discloses missing executable/build identity and unidentified external data. Cache timestamps are not immutable data snapshots, and declared package names without versions are not version locks. Neither a record nor a model archive freezes its runtime or transitive external services. Inspect these limitations before claiming an independently reproducible environment. Records support at most 100 selected results and 500 declared inputs, with a 1 MiB record limit; scenario assets retain their 2 MiB limit.

Checked teaching starters

Find the OR Teaching models in the existing Templates gallery, or open the canonical sources directly:

Starter Decision and independent check
or-production.grid Divisible production, resource residuals, objective reconstruction and local marginal range
or-facility.grid Binary facility choices; covering certificate and lower bound 13; explicit MIP requirement
or-queue.grid Stationary M/M/1 domain guard, analytic capacity and Little's law
or-markov.grid Transition shape/numeric/nonnegative/unit-row-sum checks on change; unique stationary distribution and balance
or-newsvendor.grid Explicit candidate vs continuous domains: expected candidate 60, robust candidate 100, continuous robust 85
or-bounded-optimization.grid Solver stopping reason beside independent Rosenbrock criteria

These arithmetic checks do not establish that a real system satisfies the model assumptions. Each starter states its assumptions, decision domain and units in source and visible readouts.

For labeled authoring, see examples/operations-research/README.md. The native assignment network and job-shop planning examples use existing representations. The separate named-decision prototype emits ordinary Grid source and a matrix preview; it does not promote a new production syntax or visual editor.

Interpreting the strict-unit probe

In the retained strict example 10m + 5s, 5s is a duration literal carried as PT5S, not a numerical magnitude tagged unit:s. Its error now names the refused numeric coercion and explains recovery. This is distinct from a compile-time dimensional mismatch. Use declared numeric unit quantities when teaching dimensional arithmetic; do not infer a particular cause from a bare #TYPE! code.