diff --git a/optimizeMIP.ts.md b/optimizeMIP.ts.md new file mode 100644 index 0000000..cb6b023 --- /dev/null +++ b/optimizeMIP.ts.md @@ -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 }); +``` + +---