Skip to content

Commit f70e9f6

Browse files
committed
fix: dynamic BIG_M, isFinite validation, remove EPSILON duplicate and console.error, bump version to 1.0.0
1 parent 43f56f9 commit f70e9f6

File tree

6 files changed

+24
-14
lines changed

6 files changed

+24
-14
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "resolucion-metodo-simplex",
3-
"version": "0.0.0",
3+
"version": "1.0.0",
44
"private": true,
55
"type": "module",
66
"engines": {

src/components/SimplexInput.vue

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,26 @@ const initializeMatrices = () => {
3636
constraintTypes.value = Array(numConstraints.value).fill('')
3737
}
3838
39+
const isValidCoef = (v) =>
40+
v !== '' && v !== null && v !== undefined && !isNaN(v) && isFinite(Number(v))
41+
3942
const validateInputs = () => {
4043
for (let i = 0; i < numVariables.value; i++) {
4144
const coef = objectiveCoefficients.value[i]
42-
if (coef === '' || coef === null || isNaN(coef)) {
45+
if (!isValidCoef(coef)) {
4346
return `Coeficiente ${i + 1} de función objetivo inválido`
4447
}
4548
}
4649
4750
for (let i = 0; i < numConstraints.value; i++) {
4851
for (let j = 0; j < numVariables.value; j++) {
4952
const coef = constraintCoefficients.value[i][j]
50-
if (coef === '' || coef === null || isNaN(coef)) {
53+
if (!isValidCoef(coef)) {
5154
return `Restricción ${i + 1}, variable ${j + 1} inválida`
5255
}
5356
}
54-
if (!constraintRHS.value[i] || isNaN(constraintRHS.value[i])) {
57+
const rhs = constraintRHS.value[i]
58+
if (!isValidCoef(rhs)) {
5559
return `Restricción ${i + 1}, lado derecho inválido`
5660
}
5761
}

src/components/SimplexSolution.vue

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ const solveProblem = () => {
4343
}
4444
} catch (e) {
4545
solveError.value = e?.message || 'Error inesperado al resolver el problema.'
46-
console.error('[SimplexSolution] Error al resolver:', e)
4746
}
4847
}
4948
@@ -135,7 +134,7 @@ const exportToPDF = async () => {
135134
doc.autoTable({ head: headers, body, startY: 30 })
136135
doc.save('simplex-solution.pdf')
137136
} catch (e) {
138-
console.error('Error exporting PDF', e)
137+
solveError.value = 'No se pudo exportar el PDF. Intenta de nuevo.'
139138
}
140139
}
141140
</script>

src/utils/grafico.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,4 +404,3 @@ export class GraphicMethodSolver {
404404
}
405405
}
406406

407-
export { EPSILON }

src/utils/simplex.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,22 @@ import { formatNumber, EPSILON } from './formatters.js'
33

44
// Constantes de configuración
55
const MAX_ITERATIONS = 100 // Máximo de iteraciones permitidas
6-
const BIG_M = 1e6 // Penalización para variables artificiales (Método de la M Grande)
76

87
export class SimplexSolver {
98
constructor(problemData) {
109
this.problemData = problemData
1110
this.iterations = []
1211
this.finalSolution = null
1312
this.status = null
13+
14+
// BIG_M dinámico: al menos 1000x el coeficiente más grande del problema
15+
const allValues = [
16+
...problemData.objective.map(Math.abs),
17+
...problemData.constraints.flat().map(Math.abs),
18+
...problemData.rhs.map(Math.abs)
19+
]
20+
const maxCoef = Math.max(...allValues, 1)
21+
this.BIG_M = maxCoef * 1000
1422
}
1523

1624
/**
@@ -184,13 +192,13 @@ export class SimplexSolver {
184192
tiposDeVariablesAgregadas.push({ type: 'surplus', constraintIndex: indiceRestriccion })
185193
tiposDeVariablesAgregadas.push({ type: 'artificial', constraintIndex: indiceRestriccion })
186194
coeficientesObjetivo.push(0) // Variable de exceso: no afecta Z
187-
coeficientesObjetivo.push(-BIG_M) // Variable artificial: penalización Big-M (maximización)
195+
coeficientesObjetivo.push(-this.BIG_M) // Variable artificial: penalización Big-M (maximización)
188196
} else if (tipoDeRestriccion === '=') {
189197
// Restricción tipo =: Agregar variable artificial
190198
// Ejemplo: X₁ + X₂ = 8 → X₁ + X₂ + A₁ = 8
191199
contadorVariablesArtificiales++
192200
tiposDeVariablesAgregadas.push({ type: 'artificial', constraintIndex: indiceRestriccion })
193-
coeficientesObjetivo.push(-BIG_M) // Variable artificial: penalización Big-M (maximización)
201+
coeficientesObjetivo.push(-this.BIG_M) // Variable artificial: penalización Big-M (maximización)
194202
}
195203
}
196204

@@ -900,4 +908,4 @@ export class SimplexSolver {
900908
}
901909

902910
// Exportar constantes para uso en otros módulos si es necesario
903-
export { EPSILON, MAX_ITERATIONS, BIG_M }
911+
export { EPSILON, MAX_ITERATIONS }

test/simplex.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, it, expect } from 'vitest'
2-
import { SimplexSolver, BIG_M } from '../src/utils/simplex.js'
2+
import { SimplexSolver } from '../src/utils/simplex.js'
33

44
// Helper para construir problemData
55
function makeProblem({ type = 'max', objective, constraints, rhs, constraintTypes }) {
@@ -147,9 +147,9 @@ describe('SimplexSolver - Restricciones ≥ con Big-M', () => {
147147
expect(result.status).toBe('optimal')
148148
// Solo debe haber 2 variables (las originales)
149149
expect(result.solution.variables).toHaveLength(2)
150-
// Ningún valor debe ser del orden de Big-M
150+
// Ningún valor debe ser del orden de Big-M (usamos la instancia dinámica)
151151
result.solution.variables.forEach(v =>
152-
expect(Math.abs(v)).toBeLessThan(BIG_M / 2)
152+
expect(Math.abs(v)).toBeLessThan(solver.BIG_M / 2)
153153
)
154154
})
155155
})

0 commit comments

Comments
 (0)