SimplexPro es un servicio web con API REST desarrollado en Python, especializado en la resolución de problemas de Programación Lineal mediante el Método Gráfico (2 variables) y el Método Simplex/Gran M (N variables).
- API REST con FastAPI: Endpoints CRUD para problemas de programación lineal + resolución unificada.
- Método Gráfico: Encuentra vértices de la región factible, incluye restricciones de no-negatividad (
x ≥ 0,y ≥ 0), gráfico matplotlib en base64 y exportación a PDF. - Método Simplex / Gran M: Soporta maximización/minimización, restricciones
<=,>=,=, variables artificiales con penalización Big-M, y retorna todas las iteraciones (tabla, pivote, entrada/salida). - Persistencia: SQLite asíncrona (
aiosqlite). - PDF: Reportes con fpdf2 (solución, vértices evaluados, gráfico).
| Componente | Librerias |
|---|---|
| Web Framework | FastAPI (async) |
| Gestor de dependencias | uv |
| Base de Datos | SQLite (aiosqlite) |
| Cálculo Numérico | NumPy |
| Visualización | Matplotlib |
| fpdf2 |
simplexPro/
├── main.py # Entry point FastAPI + lifespan
├── simplexPro.sql # DDL de la base de datos
├── app/
| ├── assets/
│ │ ├── fonts/ # Archivos de fuentes TTF para la generación de PDF (Deja-Vu Sans Condensed)
│ ├── db/
│ │ └── connection.py # Conexión async SQLite + DbDep
│ ├── schemas/
│ │ ├── problemaPL.py # Modelos base (ProblemaPL)
│ │ ├── resultados.py # Modelos para mostrar resultados de los métodos gráficos y simplex
│ ├── validators/
│ │ └── problema.py # Validación de estructura del problema
│ ├── services/
│ │ ├── grafico.py # Solver gráfico (2 variables)
│ │ ├── simplex.py # Solver simplex / Gran M
│ │ └── exportador.py # Generación de PDF
│ ├── repository/
│ │ ├── problemaPL_dao.py # CRUD de problemaPL
│ │ ├── grafico_dao.py # CRUD de metodoGrafico
│ │ └── simplex_dao.py # CRUD de metodoSimple + iteraciones
│ └── routes/
│ ├── problemas.py # Endpoints CRUD + resolución
│ └── utilidad.py # Endpoint de exportación PDF
# 1. Sincronizar dependencias
uv sync
# 2. Iniciar servidor de desarrollo
uv run fastapi dev main.pyLa API queda en http://localhost:8000.
Documentación Swagger: http://localhost:8000/docs.
- Ruta:
GET /problemas - Query Params:
page(opcional, default: 1). - Descripción: Obtiene una lista paginada de los problemas registrados.
- Respuesta (200 OK): Lista de
ResumenProblema.[ { "id": "uuid", "titulo": "Nombre del problema", "descripcion": "Opcional", "tipoOptimizacion": "max/min", "fechaCreacion": "YYYY-MM-DD HH:MM:SS" } ]
- Ruta:
GET /problemas/{id} - Descripción: Recupera los detalles y la solución de un problema por su ID. Retorna dinámicamente el resultado gráfico (
MostrarResultadoGrafico) o simplex (MostrarResultadoSimplex) según corresponda. - Respuesta (200 OK):
MostrarResultadoGraficooMostrarResultadoSimplex. - Errores: 404 si el problema no existe.
- Ruta:
POST /problemas/registrar - Query Params:
metodo(obligatorio: "grafico" o "simplex"). - Cuerpo (JSON):
- Para
grafico: Requierex,yen variables, restricciones y FO. - Para
simplex: Requiere variables tipox1,x2, ...,xny términos estructurados en un diccionarioterminos.
- Para
- Flujo:
- Valida la estructura según el método.
- Ejecuta el servicio correspondiente (
metodoGraficoometodoSimplex). - Persiste el problema y el resultado en la base de datos.
- Respuesta (201 Created):
{"id": "uuid-del-problema-registrado"}.
- Ruta:
PUT /problemas/actualizar - Query Params:
metodo(obligatorio: "grafico" o "simplex")id(obligatorio: ID del problema a actualizar)
- Cuerpo (JSON): Misma estructura que el registro.
- Respuesta (200 OK):
{"mensaje": "Problema actualizado"}.
- Ruta:
DELETE /problemas/eliminar/{id} - Respuesta (200 OK):
{"mensaje": "Problema eliminado"}. - Errores: 404 si no existe.
POST /problemas/registrar?metodo=grafico
{
"titulo": "Problema de ejemplo",
"descripcion": "Optimizar producción",
"variables": { "x": "Producto A", "y": "Producto B" },
"restricciones": [
{ "x": 2, "y": 3, "signo": "<=", "constante": 100, "glosa": "Materia prima" },
{ "x": 1, "y": 2, "signo": "<=", "constante": 80, "glosa": "Mano de obra" }
],
"funcion_objetivo": { "x": 50, "y": 40, "tipo": "max" }
}POST /problemas/registrar?metodo=simplex
{
"titulo": "Problema simplex",
"descripcion": "Optimizar producción",
"variables": { "x1": "Producto A", "x2": "Producto B", "x3": "Producto C" },
"restricciones": [
{
"terminos": { "x1": 2, "x2": 1, "x3": 3 },
"signo": "<=",
"constante": 100,
"glosa": "Materia prima"
},
{
"terminos": { "x1": 1, "x2": 2, "x3": 1 },
"signo": ">=",
"constante": 50,
"glosa": "Mano de obra"
}
],
"funcion_objetivo": {
"terminos": { "x1": 30, "x2": 20, "x3": 50 },
"tipo": "max"
}
}- Ruta:
GET /problemas/{id}/exportar - Descripción: Genera y descarga un reporte PDF del problema (actualmente enfocado en el método gráfico).
- Respuesta (200 OK): Archivo binario
application/pdf.
- 400 Bad Request:
- Falta de campos obligatorios (
titulo,variables,restricciones,funcion_objetivo). - Signos inválidos (Grafico:
<=, >=, =; Simplex:<=, >=, =). - Formato incorrecto de variables (ej. para simplex deben ser
x1, x2...). - Tipo de optimización no es
maxomin.
- Falta de campos obligatorios (
- 422 Unprocessable Entity: Error automático de FastAPI cuando el JSON no cumple con el esquema Pydantic.
- 404 Not Found: ID de problema no existe en la base de datos.
problemaPL— Problemas registrados (UUID, título, FO, tipo optimización).variables— Variables asociadas a cada problema.restricciones— Restricciones con inecuación y glosa.metodoGrafico— Resultados gráficos (vértices, mensaje, gráfico PNG en BLOB).metodoSimple— Resultados simplex (valor FO, mensaje).iteracionSimple— Cada iteración del simplex (tabla JSON, pivote, entrada/salida).