A simple REST API for solving linear programming problems using the GLPK (GNU Linear Programming Kit) library.
cargo runYour application will be available at http://localhost:9000.
docker compose up --buildVisit http://localhost:9000/docs for interactive API documentation, or simply go to http://localhost:9000 (automatically redirects to docs).
GET /- Redirects to documentationGET /docs- Interactive API documentationGET /health- Health checkPOST /solve- Solve linear programming problems
curl -X POST http://127.0.0.1:9000/solve \
-H "Content-Type: application/json" \
-d '{
"polyhedron": {
"A": {
"rows": [0,0,1,1,2,2],
"cols": [0,1,0,2,1,2],
"vals": [1,1,1,1,1,1],
"shape": {"nrows": 3, "ncols": 3}
},
"b": [1, 1, 1],
"variables": [
{ "id": "x1", "bound": [0,1] },
{ "id": "x2", "bound": [0,1] },
{ "id": "x3", "bound": [0,1] }
]
},
"objectives": [
{ "x1":0, "x2":0, "x3":1 },
{ "x1":1, "x2":2, "x3":1 }
],
"direction": "maximize"
}'Returns one solution for each objective:
{
"solutions": [
{
"error": null,
"objective": 1,
"solution": {
"x1": 1,
"x2": 1,
"x3": 1
},
"status": "Optimal"
},
{
"error": null,
"objective": 4,
"solution": {
"x1": 1,
"x2": 1,
"x3": 1
},
"status": "Optimal"
}
]
}The API is designed to solve integer linear programming problems in the standard idiomatic form:
Where:
-
$w$ is the objective coefficient vector (specified in theobjectivesfield) -
$x$ is the decision variable vector (defined in thevariablesfield) -
$A$ is the constraint coefficient matrix (specified in thepolyhedron.Afield) -
$b$ is the constraint right-hand side vector (specified in thepolyhedron.bfield)
This standard formulation allows you to express a wide variety of optimization problems by properly setting up the constraint matrix and objective coefficients.
polyhedron- Constraint matrix and variable definitionsobjectives- Array of objective functions to optimizedirection- Either "maximize" or "minimize"
A- Sparse constraint matrix (rows, cols, vals, shape)b- Right-hand side constraint valuesvariables- Array of variable definitions with bounds
id- Variable name (string)bound- [lower_bound, upper_bound] as integers
| Code | Status | Description |
|---|---|---|
| 1 | Undefined | Solution status is undefined |
| 2 | Feasible | Solution is feasible |
| 3 | Infeasible | Problem is infeasible |
| 4 | NoFeasible | No feasible solution exists |
| 5 | Optimal | Optimal solution found |
| 6 | Unbounded | Problem is unbounded |
| 7 | SimplexFailed | Simplex method failed |
| 8 | MIPFailed | Mixed-integer programming failed |
| 9 | EmptySpace | Search space is empty |
PORT- Server port (default: 9000)JSON_PAYLOAD_LIMIT- Maximum request size (default: 2MB)
Create a .env file in the project root:
PORT=8080
JSON_PAYLOAD_LIMIT=5242880
Enable authentication for the POST /solve endpoint by setting the following variables in the enviroment:
PROTECT=true(default:false)API_TOKEN=****
When enabled, all requests to /solve must include a valid API key in a X-API-Key header.
docker build -t glpk-api .docker build --platform=linux/amd64 -t glpk-api .docker push myregistry.com/glpk-apiThe image is available on Our Studio's Dockerhub account.
To build and push a new version:
- Login to the ourstudio account
$ docker login
Username: ourstudio Password: {in Bitwarden}
- Build and push the new image
docker buildx create --use
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t ourstudio/rust-glpk-api:x.y.z \
-t ourstudio/rust-glpk-api:x.y \
-t ourstudio/rust-glpk-api:latest \
--push .
Where x, y and z are major, minor and patch version numbers.
- Verify that the new image is available here.
Run the integration tests:
cargo testOr test manually with the included script:
./test.shThe API uses sparse matrix format for efficiency:
rows- Array of row indices (0-based)cols- Array of column indices (0-based)vals- Array of values at those positionsshape- Matrix dimensions{"nrows": N, "ncols": M}
- The API converts GE constraints (A x โฅ b) to LE constraints internally
- Variable bounds are specified as
[lower_bound, upper_bound] - Multiple objectives are solved independently
- Unknown variables in objectives are silently ignored