# Optimization Solver: Linear & Integer Programming (LP/MIP) (`jumblemog/optimization-solver`) Actor

Solve linear and integer programming models with HiGHS, written as plain algebra, LP or MPS files or JSON: optimal values, shadow prices, sensitivity ranges and the conflicting constraints of infeasible models. Ready-made assignment, knapsack, bin packing and transportation problems. For AI agents.

- **URL**: https://apify.com/jumblemog/optimization-solver.md
- **Developed by:** [Jumble Mog](https://apify.com/jumblemog) (community)
- **Categories:** AI, Developer tools, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Optimization Solver: Linear & Integer Programming (LP/MIP)

**Solve linear and integer programming problems written the way you would write them on paper.** Type `maximize profit: 3 doors + 5 windows subject to 3 doors + 2 windows <= 18, ...`, send a CPLEX LP or MPS file, a JSON model or SciPy `linprog` arrays, and get the **optimal values, the objective, every constraint's slack and shadow price, the ranges they hold over**, and for a model with no solution, **the constraints that conflict and the smallest change that fixes it**. It runs on [HiGHS](https://highs.dev), the open-source solver behind SciPy's `linprog` and `milp`, with ready-made **assignment, knapsack, bin packing and transportation** problems that need no model at all. Made for analysts, operations and supply chain teams, students, developers, spreadsheets, automations and AI agents that need exact optimization from one API call.

### What it does

- **Linear programming (LP)**: maximize or minimize a linear objective under linear constraints, with up to 200,000 variables and 200,000 constraints. Product mix, blending, diet, production planning, portfolio allocation, media budgets, cutting and network flow models.
- **Integer and mixed-integer programming (MIP)**: whole-number and yes/no (binary) variables for scheduling, staffing, facility location, capital budgeting and any decision that can't be fractional, solved by branch and cut. When the time limit ends first, you get the best solution found and how far from the best possible it can be.
- **Models in plain algebra**: `maximize 3x + 5y subject to x + 2y <= 14, 3x - y >= 0, x - y <= 2`, one constraint per line or on one line, with names, coefficients like `2.5x` or `3 * x`, parentheses, ranges like `2 <= x + y <= 10`, indexed names like `ship[A,1]`, and `≤ ≥` symbols pasted from documents.
- **Standard formats**: CPLEX LP files and fixed or free MPS files (gzipped too), so models from Gurobi, CPLEX, PuLP, Pyomo, JuMP, AMPL and the MIPLIB library run as they are, typed in or from a link.
- **JSON for programs and AI agents**: expressions as strings, coefficient maps, or SciPy `linprog` and `milp` arrays (`c`, `A_ub`, `b_ub`, `A_eq`, `b_eq`, `bounds`, `integrality`).
- **Sensitivity analysis**: each constraint's **shadow price** (what one more unit of its limit is worth) and the range of the limit it holds over, each variable's **reduced cost** and the range its objective coefficient can move without changing the solution.
- **Infeasible models explained**: an irreducible set of constraints and bounds that can't all hold together, and the smallest total change of limits that would make the model feasible, keeping whole numbers whole for integer models.
- **Unbounded models explained**: the variables that can grow forever while improving the objective, so you can see which limit is missing.
- **Ready-made problems** that need no model: **assignment** (who does which task), **knapsack** (which items to pick within a capacity or budget), **bin packing** (the fewest boxes, pallets or trucks, or the cheapest mix of sizes, solved with Google's OR-Tools CP-SAT) and **transportation** (what to ship from where to where), each answered in its own terms.
- **Answers people and programs can use**: a summary in plain sentences, a `values` map from each variable name to its value, and full tables of variables and constraints. Up to 100 problems per run, each with its own result.

### Who it's for

- **Operations and supply chain**: production plans, shipping plans, staffing, blending and capacity questions without a solver license or a Python setup.
- **Finance and planning**: budget allocation, capital budgeting and project selection under constraints, with shadow prices that show which limit is worth raising.
- **Students and teachers**: check homework and textbook problems, with the shadow prices, slacks and ranges that sensitivity analysis courses ask for.
- **Developers and automations**: a hosted LP/MIP solver API for apps, spreadsheets and no-code flows (Make, n8n, Zapier), billed per problem with no monthly plan.
- **AI agents and LLM apps**: language models can write an optimization model but can't solve one reliably in their heads. An agent can write the model in plain algebra or JSON, call this Actor, and get back exact values it can act on and explain.

### How to use it

1. Write your problem in **Model**: an objective line, `subject to`, then the constraints. The form starts with a small production planning model, so you can click **Start** right away.
2. Or clear **Model** and fill in a ready-made problem: **Assignment**, **Knapsack**, **Bin packing** or **Transportation**.
3. Click **Start**. The **Answers** view shows each problem's status, objective, values and the answer in words; the **Sensitivity and details** view has every variable and constraint with reduced costs, shadow prices and ranges.

You can also run it through the [Apify API](https://docs.apify.com/api/v2), on a schedule, or from Make, n8n, Zapier and other integrations.

### Writing a model

| What | How to write it |
| --- | --- |
| Objective | `maximize 3x + 5y`, `minimize cost: 4a + 2.5b`, `max: 2 x1 + x2`, `min z` |
| Constraints | after `subject to` (or `st`, `s.t.`, `such that`), one per line, or separated by commas or semicolons |
| Names | `labor: 2x + y <= 100` names a constraint, and the name comes back with its shadow price |
| Comparisons | `<=`, `>=`, `=`, `<`, `>`, `≤`, `≥`, and ranges `10 <= x + y <= 20` |
| Arithmetic | `2x`, `2 x`, `2*x`, `x/4`, `0.5(x + y)`, `-(a - b)`, constants on either side |
| Bounds | variables are 0 or more by default; `x <= 10`, `-5 <= y <= 5`, `free z`, `x, y >= 1`, or a `bounds` section |
| Whole numbers | `int x, y`, `integer x`, `x, y integer`, a `generals` section, or `x in {0, 1}` and `bin z` for yes/no |
| Variable names | letters, digits, `_`, `.` and indices: `x1`, `make_steel`, `ship[A,B]`, `x[1][2]` |
| Comments | `#`, `//` or `\` to the end of the line |

A model with no objective finds any solution that meets every constraint. A constraint with a negative limit on a single variable, like `x >= -5`, lets that variable go below 0.

### Examples

**Production planning** (the form's example, from Hillier and Lieberman's textbook):

```
maximize profit: 3 doors + 5 windows
subject to
  plant1: doors <= 4
  plant2: 2 windows <= 12
  plant3: 3 doors + 2 windows <= 18
```

The answer: `Optimal: maximum profit = 36 with doors = 2 and windows = 6. Shadow prices of the constraints at their limit: plant2 (1.5), plant3 (1). Each unit more of plant2's limit adds 1.5 to profit, while that limit stays between 6 and 18. Room left: plant1 (2).`

**Integer variables** on one line:

```
max 5x + 4y + 3z st 2x + 3y + z <= 5, 4x + y + 2z <= 11, 3x + 4y + 2z <= 8, int x, y, z
```

**Facility location with yes/no decisions**: which warehouses to open, and who ships to whom:

```
minimize cost: 1000 openA + 1200 openB + 4 shipA1 + 6 shipA2 + 5 shipB1 + 3 shipB2
subject to
  demand1: shipA1 + shipB1 = 80
  demand2: shipA2 + shipB2 = 120
  capacityA: shipA1 + shipA2 <= 250 openA
  capacityB: shipB1 + shipB2 <= 250 openB
bin openA, openB
```

The answer opens only warehouse B, for a total cost of 1,960.

**JSON** (handy for programs and AI agents):

```json
{
    "jsonModel": {
        "maximize": "3x + 5y",
        "constraints": ["plant1: x <= 4", "plant2: 2y <= 12", "plant3: 3x + 2y <= 18"],
        "integer": ["x"]
    }
}
```

**SciPy `linprog` arrays**, minimized as in SciPy:

```json
{
    "jsonModel": {
        "c": [-1, 4],
        "A_ub": [[-3, 1], [1, 2]],
        "b_ub": [6, 4],
        "bounds": [[null, null], [-3, null]]
    }
}
```

**An MPS file from a link**, such as a MIPLIB benchmark instance:

```json
{
    "modelUrl": "https://miplib.zib.de/WebData/instances/markshare_4_0.mps.gz",
    "timeLimitSeconds": 60
}
```

**Assignment**: three workers, three tasks, the cheapest way to cover them:

```json
{
    "assignment": {
        "workers": ["Ann", "Bob", "Cy"],
        "tasks": ["Paint", "Wire", "Plumb"],
        "costs": [[9, 2, 7], [6, 4, 3], [5, 8, 1]]
    }
}
```

**Knapsack**: what to pack within 15 kg for the most value:

```json
{
    "knapsack": {
        "capacity": 15,
        "items": [
            {"name": "Tent", "value": 10, "weight": 5},
            {"name": "Stove", "value": 7, "weight": 3},
            {"name": "Camera", "value": 6, "weight": 2},
            {"name": "Books", "value": 3, "weight": 6},
            {"name": "Food", "value": 9, "weight": 4, "required": true}
        ]
    }
}
```

**Bin packing**: the cheapest mix of two box sizes for parcels by weight and volume:

```json
{
    "binPacking": {
        "bins": [
            {"name": "Small box", "capacity": {"weight": 20, "volume": 30}, "cost": 3},
            {"name": "Large box", "capacity": {"weight": 50, "volume": 80}, "cost": 6}
        ],
        "items": [
            {"name": "Books", "weight": 12, "volume": 10, "quantity": 3},
            {"name": "Lamp", "weight": 4, "volume": 25, "quantity": 2},
            {"name": "Kettle", "weight": 2, "volume": 8, "quantity": 4}
        ]
    }
}
```

**Transportation**: shipping from two plants to three stores at the lowest cost:

```json
{
    "transportation": {
        "supply": {"Plant A": 120, "Plant B": 80},
        "demand": {"Store 1": 60, "Store 2": 70, "Store 3": 50},
        "costs": [[4, 6, 9], [5, 3, 7]]
    }
}
```

**Several problems in one run**, each answered on its own:

```json
{
    "problems": [
        "max 3x + 2y st x + y <= 4, x + 3y <= 6",
        {"title": "Packing", "binPacking": {"binCapacity": 10, "items": [{"size": 6, "quantity": 2}, {"size": 4, "quantity": 3}]}},
        {"title": "Big MIP", "modelUrl": "https://example.com/model.mps", "timeLimitSeconds": 120}
    ]
}
```

### How-to examples

Each example below is a complete input. The result line is what the run says in `summary`.

#### How to solve a linear programming problem online

Write the model the way it's written on paper:

```json
{"model": "maximize profit: 3 doors + 5 windows\nsubject to\n  plant1: doors <= 4\n  plant2: 2 windows <= 12\n  plant3: 3 doors + 2 windows <= 18"}
```

Result: "Optimal: maximum profit = 36 with doors = 2 and windows = 6. Shadow prices of the constraints at their limit: plant2 (1.5), plant3 (1). Each unit more of plant2's limit adds 1.5 to profit, while that limit stays between 6 and 18. Room left: plant1 (2)."

#### How to solve an integer programming problem (MILP)

```json
{"model": "max 5x + 4y + 3z st 2x + 3y + z <= 5, 4x + y + 2z <= 11, 3x + 4y + 2z <= 8, int x, y, z"}
```

Result: "Optimal: maximum objective = 13 with x = 2 and z = 1 (y at 0). At their limit: c1 and c3." LP and MPS files, JSON and SciPy `linprog` arrays work too.

#### How to solve an assignment or knapsack problem without writing a model

```json
{"assignment": {"workers": ["Ann", "Bob", "Cy"], "tasks": ["Paint", "Wire", "Plumb"], "costs": [[9, 2, 7], [6, 4, 3], [5, 8, 1]]}}
```

Result: "3 assignments with the lowest total cost, 9 (proven optimal): Ann -> Wire; Bob -> Paint; Cy -> Plumb." The knapsack example under **Examples** gives "Take 4 items for a total value of 32 (proven optimal): Tent, Stove, Camera, and Food. Used: weight 14 of 15. Left out: Books." Bin packing and transportation problems have their own fields too.

#### How to let an AI agent solve optimization problems

Add this Actor to the [Apify MCP server](https://mcp.apify.com) with `https://mcp.apify.com/?tools=jumblemog/optimization-solver`. The agent writes the model in `jsonModel` or as text and passes on the `summary`. If the model has no solution, the result says which constraints conflict, so the agent can fix them.

### FAQ

**Which solvers does it use?** HiGHS for linear and mixed-integer models. Bin packing uses Google OR-Tools' CP-SAT.

**Does it give shadow prices and sensitivity?** Yes, for linear models: shadow prices, reduced costs and the ranges they hold over.

**Which model formats does it read?** Plain-text models, LP and MPS files (also gzipped, from a link), JSON, and SciPy `linprog` arrays.

**What if there's no solution?** It says the model is infeasible, lists the constraints and bounds that can't all hold together, and gives the smallest change of limits that would make it feasible.

**Does it work with Zapier, Make or n8n?** Yes. Call the Actor with its Apify app or an HTTP request and pass the answer on.

### Input

| Field | What it does |
| --- | --- |
| `model` | The model as plain algebra, a CPLEX LP or MPS file, or JSON text. |
| `format` | `auto` (default), `algebra`, `lp` (HiGHS's own LP reader, for semi-continuous variables and SOS), `mps` or `json`. |
| `jsonModel` | The model as a JSON object: strings, coefficient maps or SciPy arrays. |
| `modelUrl` | A link to a model file (MPS, LP, JSON or algebra, gzipped or not; GitHub and Gist links work). |
| `assignment`, `knapsack`, `binPacking`, `transportation` | Ready-made problems; see the examples above and each field's description. |
| `problems` | Up to 100 problems in one run, each a model string or an object with any of the fields above plus `title`, `timeLimitSeconds`, `mipGap` and `format`. |
| `timeLimitSeconds` | How long the solver may search per problem: 10 by default, up to 300. |
| `mipGap` | For integer models, the relative gap at which the search stops: 0.0001 by default, 0 to prove the exact optimum. |
| `sensitivity` | Shadow prices, reduced costs and ranges for linear models (on by default). |
| `includeZeros` | List variables at 0 too (on by default). |

### Output

Each problem gives one dataset item. The production planning example:

```json
{
    "problem": 1,
    "title": null,
    "type": "model",
    "status": "optimal",
    "summary": "Optimal: maximum profit = 36 with doors = 2 and windows = 6. Shadow prices of the constraints at their limit: plant2 (1.5), plant3 (1). Each unit more of plant2's limit adds 1.5 to profit, while that limit stays between 6 and 18. Room left: plant1 (2).",
    "objective": 36,
    "values": {"doors": 2, "windows": 6},
    "variables": [
        {"name": "doors", "value": 2, "type": "continuous", "objectiveCoefficient": 3, "lower": 0, "upper": null,
         "reducedCost": 0, "costRangeLow": 0, "costRangeHigh": 7.5},
        {"name": "windows", "value": 6, "type": "continuous", "objectiveCoefficient": 5, "lower": 0, "upper": null,
         "reducedCost": 0, "costRangeLow": 2, "costRangeHigh": null}
    ],
    "constraints": [
        {"name": "plant1", "expression": "doors <= 4", "activity": 2, "lower": null, "upper": 4, "slack": 2,
         "binding": false, "shadowPrice": 0, "rhsRangeLow": 2, "rhsRangeHigh": null},
        {"name": "plant2", "expression": "2 windows <= 12", "activity": 12, "lower": null, "upper": 12, "slack": 0,
         "binding": true, "shadowPrice": 1.5, "rhsRangeLow": 6, "rhsRangeHigh": 18},
        {"name": "plant3", "expression": "3 doors + 2 windows <= 18", "activity": 18, "lower": null, "upper": 18,
         "slack": 0, "binding": true, "shadowPrice": 1, "rhsRangeLow": 12, "rhsRangeHigh": 24}
    ],
    "conflict": null,
    "unboundedDirection": null,
    "details": null,
    "model": {"format": "algebra", "sense": "maximize", "objectiveName": "profit", "variables": 2,
              "integerVariables": 0, "binaryVariables": 0, "constraints": 3, "nonzeros": 4},
    "solver": {"engine": "HiGHS 1.15", "seconds": 0.001, "timeLimitSeconds": 10, "iterations": 0, "nodes": null,
               "bestBound": null, "gap": null, "solverStatus": "Optimal"},
    "notes": [],
    "variablesCsvUrl": null,
    "constraintsCsvUrl": null,
    "error": null
}
```

- **status**: `optimal` (proven best), `feasible` (the best found in the time limit; `solver.bestBound` and `solver.gap` say how close it is), `infeasible`, `unbounded`, `time limit` (nothing found in time) or `failed` (the model couldn't be read; `error` says why and what to change).
- **shadowPrice**: how much the objective changes per unit more of the constraint's limit, valid while the limit stays between `rhsRangeLow` and `rhsRangeHigh`. 0 for constraints with slack.
- **reducedCost**: how much the objective changes per unit a variable at its bound is pushed into the solution. `costRangeLow` and `costRangeHigh` are the range of its objective coefficient over which the solution stays the same.
- **conflict** (infeasible models): `constraints` and `bounds` that can't all hold together, `fix` (the smallest total change of limits that makes the model feasible) and `integerOnly`. For example: `Infeasible: no values meet every constraint. These can't all hold together: demand (x + y >= 6); capacity (x + y <= 4). The smallest change that makes it feasible: lower demand's minimum from 6 to 4.`
- **details** (ready-made problems): `assignments`, `unassignedTasks` and `workerLoads`; `chosen`, `leftOut` and `usage`; `bins` with their contents and fill, `binsUsed` and `lowerBound`; or `shipments` with each source's and destination's totals, the marginal cost of each destination's demand and what one more unit of each source's supply would save.
- Models with over 5,000 variables or constraints list the nonzero values and the first 5,000 constraints, with every value in CSV files (`variablesCsvUrl`, `constraintsCsvUrl`).

The run's `OUTPUT` record holds every answer as one JSON object, so `run-sync` API calls return them directly.

### How it works

Linear and integer models are solved by [HiGHS](https://highs.dev): dual simplex for linear programs, with sensitivity ranging from the optimal basis, and branch and cut for integer programs. Infeasible models get two more passes: HiGHS's irreducible infeasible subsystem (IIS) on the linear relaxation, and a relaxation that adds a variable to push each limit and minimizes their total, which gives the smallest fix. Bin packing runs on Google's [OR-Tools CP-SAT](https://developers.google.com/optimization/cp) solver, starting from a first-fit-decreasing packing and a lower bound, so it always has an answer and says when it's proven the fewest possible. Each solver runs in its own sandboxed process with no access to your Apify token.

### Accuracy

On textbook and documented examples, which are also the Actor's automated tests:

| Problem | Known answer | This Actor |
|---|---|---|
| Wyndor Glass (Hillier and Lieberman) | profit 36 at (2, 6); shadow prices 0, 1.5, 1; limit ranges 6 to 18 and 12 to 24 | the same |
| Chvátal's integer example | 13 at x = 2, z = 1 | 13 at x = 2, z = 1 |
| SciPy `linprog` documentation example | -22 at (10, -3) | -22 at (10, -3) |
| Netlib `afiro` (HiGHS test file, MPS) | -464.7531 | -464.7531 |
| HiGHS `TESTLP` MPS example | -7 at (1, -1, 6) | -7 at (1, -1, 6) |
| Classic camping knapsack, capacity 15 | value 32 | 32 |

### Pricing

You pay per **problem answered** at the price shown on this page: a solution, or proof that the model has no solution (with the conflicting constraints) or is unbounded. Problems that can't be read, or that find nothing in the time limit, aren't charged. Solving past the first 10 seconds of a problem adds a **solver time** charge per started 10 seconds, so the default 10-second time limit never adds it. If you set a maximum cost per run, the Actor checks before each problem that it fits and shortens the time limit when needed.

### Speed

Most linear models solve in well under a second, and a call through the API answers in 3 to 7 seconds, most of it the cloud container starting. A batch of 14 problems, including a MIPLIB file fetched from its link and solved for 25 seconds, took 35 seconds. Integer models take up to the time limit when they're hard. More memory gives the solver more CPU: 4 GB is one full core.

### Tips and limits

- **Limits**: 200,000 variables, 200,000 constraints and 2,000,000 coefficients per model written as text or JSON, 4 MB of model text, files up to 64 MB from links, 100 problems per run, and a time limit of up to 300 seconds per problem.
- **Linear only**: constraints and objectives must be linear (no `x * y`, `x^2` or division by a variable). Products of a binary and a bounded variable can be modeled with the usual big-M constraints.
- **Hard integer models**: raise the time limit, accept a larger `mipGap` (0.01 stops within 1%), or give tighter bounds on the variables.
- **Shadow prices** come from linear models; integer models report values, slacks and the gap instead.
- **Links**: every site's robots.txt is checked first, and only public web addresses are fetched.

### For AI agents and developers

This Actor works with the [Apify MCP server](https://mcp.apify.com), so AI agents can call it as a tool: write the model, send it in `model` or `jsonModel`, and read `status`, `objective`, `values` and `summary` from the result. A direct API call that waits for the answer:

```bash
curl -X POST "https://api.apify.com/v2/acts/jumblemog~optimization-solver/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"model": "max 3x + 5y st x <= 4, 2y <= 12, 3x + 2y <= 18"}'
```

`run-sync` instead returns the run's `OUTPUT`: how many problems were answered and every answer as JSON.

In Python, with the `apify-client` package:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("jumblemog/optimization-solver").call(run_input={
    "jsonModel": {
        "minimize": "cost: 2a + 3b",
        "constraints": ["protein: 4a + 3b >= 24", "fat: a + 2b >= 8"],
    },
})
for answer in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(answer["status"], answer["objective"], answer["values"])
```

### Credits

- Linear and integer programming: [HiGHS](https://highs.dev) (MIT License) through highspy.
- Bin packing: [Google OR-Tools](https://developers.google.com/optimization) CP-SAT (Apache License 2.0).
- Arrays: [NumPy](https://numpy.org) (BSD-3-Clause).
- Test problems: the Wyndor Glass example from Hillier and Lieberman's *Introduction to Operations Research*, the integer example from Chvátal's *Linear Programming*, the SciPy `linprog` documentation, and HiGHS's own test files (Netlib `afiro`).

# Actor input Schema

## `model` (type: `string`):

The problem to solve, in plain algebra: an objective line (maximize or minimize, optionally named, like 'maximize profit: 3x + 5y'), then 'subject to' and the constraints, one per line or separated by commas, optionally named ('labor: 2x + y <= 100'). Variables are 0 or more unless bounded otherwise ('x >= -5', '0 <= y <= 10', 'free z'). Whole-number variables go on a line like 'int x, y' or 'x, y integer', yes/no ones like 'bin z'. Indexed names work (x\[1], ship\[A,B]), and so do CPLEX LP and MPS files and JSON (see Format).

## `format` (type: `string`):

How the model is written. Detect recognizes MPS files, JSON and plain algebra (CPLEX LP files included) from the text, and LP files the plain reader can't take (semi-continuous variables, SOS) go to HiGHS's own LP reader.

## `jsonModel` (type: `object`):

The model as a JSON object, for programs and AI agents. With strings: {"maximize": "3x + 5y", "constraints": \["x <= 4", "labor: 3x + 2y <= 18"], "integer": \["x"]}. With coefficients: {"objective": {"sense": "max", "coefficients": {"x": 3, "y": 5}}, "constraints": \[{"name": "labor", "terms": {"x": 3, "y": 2}, "<=": 18}], "variables": \[{"name": "x", "upper": 4, "type": "integer"}]}. As SciPy linprog arrays (minimized, like SciPy; add "maximize": true to maximize): {"c": \[-3, -5], "A_ub": \[\[1, 0], \[0, 2], \[3, 2]], "b_ub": \[4, 12, 18], "bounds": \[0, null], "integrality": \[0, 1]}.

## `modelUrl` (type: `string`):

A link to a model file: MPS (.mps, or gzipped .mps.gz like MIPLIB instances), CPLEX LP (.lp), JSON or plain algebra text. GitHub and Gist file links work. Up to 64 MB; the site's robots.txt is respected.

## `assignment` (type: `object`):

Who does which task at the lowest total cost (or highest total value): {"workers": \["Ann", "Bob", "Cy"], "tasks": \["Paint", "Wire", "Plumb"], "costs": \[\[9, 2, 7], \[6, 4, 3], \[5, 8, 1]]}, one row per worker and one column per task. null or "x" marks a pair that isn't allowed. Give "values" instead of costs to maximize. Optional: workers as objects with a capacity (tasks each can take, default 1), {"name": "Ann", "capacity": 2}, and tasks with workersNeeded (default 1). costs can also be {"Ann": {"Paint": 9}} or a list of {"worker", "task", "cost"} records.

## `knapsack` (type: `object`):

Which items to pick for the most value within a capacity, such as weight, space or budget: {"capacity": 15, "items": \[{"name": "Tent", "value": 10, "weight": 5}, {"name": "Stove", "value": 7, "weight": 3}]}. Several limits at once: "capacity": {"weight": 15, "volume": 20} with each item's weight and volume. Per item, optional: quantity (copies available), min and "required": true. Several knapsacks: "knapsacks": \[{"name": "Bag 1", "capacity": 10}, {"name": "Bag 2", "capacity": 8}]. Project or budget selection works the same way (value = return, weight = cost).

## `binPacking` (type: `object`):

The fewest bins, boxes, pallets or trucks that hold every item: {"binCapacity": 10, "items": \[{"name": "A", "size": 6, "quantity": 2}, {"name": "B", "size": 4, "quantity": 3}]}. Several dimensions: "binCapacity": {"weight": 20, "volume": 1.5} with each item's weight and volume. Bins of several types for the cheapest mix: "bins": \[{"name": "Small box", "capacity": 20, "cost": 3, "count": 10}, {"name": "Large box", "capacity": 50, "cost": 6}]. Also cuts stock in one dimension: the stock length as the capacity and the pieces as items. Solved with OR-Tools CP-SAT.

## `transportation` (type: `object`):

What to ship from each source to each destination at the lowest cost while meeting demand: {"supply": {"Plant A": 120, "Plant B": 80}, "demand": {"Store 1": 60, "Store 2": 70, "Store 3": 50}, "costs": \[\[4, 6, 9], \[5, 3, 7]]}, costs per unit with one row per source. null or "x" blocks a route. Optional: routeCapacities (shaped like costs) and "integer": true for whole units. When supply falls short, as much demand as possible is met. The answer includes each destination's marginal cost and what one more unit of each source's supply would save.

## `problems` (type: `array`):

Several problems in one run: each one a model string or an object with one of model, jsonModel, modelUrl, assignment, knapsack, binPacking or transportation, plus an optional title, timeLimitSeconds, mipGap and format. For example \["max 3x + 2y st x + y <= 4, x + 3y <= 6", {"title": "Packing", "binPacking": {"binCapacity": 10, "items": \[{"size": 6}, {"size": 4}]}}]. Up to 100 per run; each is answered and charged on its own.

## `timeLimitSeconds` (type: `integer`):

How long the solver may search on each problem. Linear models usually solve in well under a second. Hard integer models use the whole limit and return the best solution found, with how far from the best possible it can be. Solving past the first 10 seconds of a problem is charged per started 10 seconds.

## `mipGap` (type: `number`):

For integer models: stop once the solution is proven to be within this fraction of the best possible. 0.0001 (0.01%, the default), 0.01 for 1% (faster on hard models), 0 to prove the exact optimum.

## `sensitivity` (type: `boolean`):

For linear models: each constraint's shadow price (what one more unit of its limit is worth), each variable's reduced cost, and the ranges over which they hold.

## `includeZeros` (type: `boolean`):

List every variable, including those at 0. Turn off to list only the nonzero ones, handy for big models. Models with over 5,000 variables list the nonzero ones and put every value in a CSV file.

## Actor input object example

```json
{
  "model": "maximize profit: 3 doors + 5 windows\nsubject to\n  plant1: doors <= 4\n  plant2: 2 windows <= 12\n  plant3: 3 doors + 2 windows <= 18",
  "format": "auto",
  "timeLimitSeconds": 10,
  "mipGap": 0.0001,
  "sensitivity": true,
  "includeZeros": true
}
```

# Actor output Schema

## `results` (type: `string`):

One item per problem: the status, objective, values and the answer in words.

## `details` (type: `string`):

Each problem's variables and constraints with reduced costs, shadow prices and ranges, conflicts and solver statistics.

## `output` (type: `string`):

The OUTPUT record: every answer in one JSON object.

## `files` (type: `string`):

CSV files of big models' variables and constraints, and OUTPUT, in the run's key-value store.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "model": `maximize profit: 3 doors + 5 windows
subject to
  plant1: doors <= 4
  plant2: 2 windows <= 12
  plant3: 3 doors + 2 windows <= 18`
};

// Run the Actor and wait for it to finish
const run = await client.actor("jumblemog/optimization-solver").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "model": """maximize profit: 3 doors + 5 windows
subject to
  plant1: doors <= 4
  plant2: 2 windows <= 12
  plant3: 3 doors + 2 windows <= 18""" }

# Run the Actor and wait for it to finish
run = client.actor("jumblemog/optimization-solver").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "model": "maximize profit: 3 doors + 5 windows\\nsubject to\\n  plant1: doors <= 4\\n  plant2: 2 windows <= 12\\n  plant3: 3 doors + 2 windows <= 18"
}' |
apify call jumblemog/optimization-solver --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jumblemog/optimization-solver"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/JmJDZzLcJBjrDfihG/builds/CpaJHME8GlIRRPsAJ/openapi.json
