Created optimizeMIP.ts (markdown)
+169
@@ -0,0 +1,169 @@
|
|||||||
|
# 📄 Documentation for `optimizeMIP.ts`
|
||||||
|
|
||||||
|
This document provides detailed documentation for the `optimizeMIP.ts` file. This TypeScript file is designed to handle HTTP POST requests to optimize Mixed Integer Programming (MIP) problems using the GLPK (GNU Linear Programming Kit) solver in a Next.js API route.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🗂️ Index
|
||||||
|
|
||||||
|
1. [Overview](#overview)
|
||||||
|
2. [Imports](#imports)
|
||||||
|
3. [Interfaces](#interfaces)
|
||||||
|
4. [Handler Function](#handler-function)
|
||||||
|
5. [Error Handling](#error-handling)
|
||||||
|
6. [Response](#response)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 Overview
|
||||||
|
|
||||||
|
The **`optimizeMIP.ts`** file defines an API endpoint that processes POST requests for solving MIP problems. It uses the `glpk.js` library to perform the optimization based on the provided objective function, constraints, and optionally, bounds.
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📥 Imports
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { NextApiRequest, NextApiResponse } from 'next';
|
||||||
|
import GLPK from 'glpk.js';
|
||||||
|
```
|
||||||
|
|
||||||
|
- **`NextApiRequest`** and **`NextApiResponse`** are imported from Next.js to handle API requests and responses.
|
||||||
|
- **`GLPK`** is imported from `glpk.js` to perform the optimization computations.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧩 Interfaces
|
||||||
|
|
||||||
|
The file defines several interfaces to structure the input data:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface Variable {
|
||||||
|
name: string;
|
||||||
|
coef: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Constraint {
|
||||||
|
name: string;
|
||||||
|
vars: Variable[];
|
||||||
|
bnds: {
|
||||||
|
lb: number;
|
||||||
|
ub: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Objective {
|
||||||
|
direction: 'max' | 'min';
|
||||||
|
vars: Variable[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RequestBody {
|
||||||
|
objective: Objective;
|
||||||
|
constraints: Constraint[];
|
||||||
|
bounds?: any;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **`Variable`**: Represents a variable with a name and coefficient.
|
||||||
|
- **`Constraint`**: Represents a constraint with a name, variables, and bounds (lower and upper).
|
||||||
|
- **`Objective`**: Defines the objective function with a direction (`max` or `min`) and a list of variables.
|
||||||
|
- **`RequestBody`**: The expected structure of the request body.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✋ Handler Function
|
||||||
|
|
||||||
|
The main function that handles the API request:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
|
if (req.method === 'POST') {
|
||||||
|
const { objective, constraints, bounds }: RequestBody = req.body;
|
||||||
|
|
||||||
|
if (!objective || !constraints) {
|
||||||
|
return res.status(400).json({ message: 'Invalid input data. Ensure that "objective" and "constraints" are provided correctly.' });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const glpk = await GLPK();
|
||||||
|
const options = {
|
||||||
|
msglev: glpk.GLP_MSG_ALL,
|
||||||
|
presol: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const problem = {
|
||||||
|
name: 'MIP',
|
||||||
|
objective: {
|
||||||
|
direction: objective.direction === 'max' ? glpk.GLP_MAX : glpk.GLP_MIN,
|
||||||
|
name: 'obj',
|
||||||
|
vars: objective.vars.map((v: Variable) => ({ name: v.name, coef: v.coef }))
|
||||||
|
},
|
||||||
|
subjectTo: constraints.map((c: Constraint) => ({
|
||||||
|
name: c.name,
|
||||||
|
vars: c.vars.map((v: Variable) => ({ name: v.name, coef: v.coef })),
|
||||||
|
bnds: { type: glpk.GLP_UP, lb: c.bnds.lb, ub: c.bnds.ub }
|
||||||
|
})),
|
||||||
|
binaries: objective.vars.map((v: Variable) => v.name),
|
||||||
|
generals: objective.vars.map((v: Variable) => v.name)
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = glpk.solve(problem, options);
|
||||||
|
res.status(200).json({ result });
|
||||||
|
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error('Error processing optimization:', error);
|
||||||
|
res.status(500).json({ message: 'Error processing optimization', error: error.message });
|
||||||
|
} else {
|
||||||
|
console.error('Unknown error:', error);
|
||||||
|
res.status(500).json({ message: 'Error processing optimization', error: 'Unknown error' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.status(405).json({ message: 'Only POST method is allowed' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Functionality
|
||||||
|
|
||||||
|
- **Request Method Check**: Ensures that only POST requests are processed.
|
||||||
|
- **Input Validation**: Checks if the `objective` and `constraints` are provided.
|
||||||
|
- **GLPK Setup and Problem Definition**:
|
||||||
|
- Initializes the GLPK solver.
|
||||||
|
- Sets solver options.
|
||||||
|
- Constructs the problem definition with the objective function, constraints, and variable bounds.
|
||||||
|
- **Solver Execution**: Solves the problem using GLPK and sends the result back to the client.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ Error Handling
|
||||||
|
|
||||||
|
The function includes robust error handling:
|
||||||
|
|
||||||
|
- **Input Validation Error**: Returns a 400 status with a message if input data is invalid.
|
||||||
|
- **Execution Error**: Catches any errors during the optimization process and logs them. Returns a 500 status with an error message.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error('Error processing optimization:', error);
|
||||||
|
res.status(500).json({ message: 'Error processing optimization', error: error.message });
|
||||||
|
} else {
|
||||||
|
console.error('Unknown error:', error);
|
||||||
|
res.status(500).json({ message: 'Error processing optimization', error: 'Unknown error' });
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📬 Response
|
||||||
|
|
||||||
|
On successful optimization, the function returns:
|
||||||
|
|
||||||
|
- **Status 200**: Success
|
||||||
|
- **Body**: JSON object containing the optimization result.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
res.status(200).json({ result });
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
Reference in New Issue
Block a user