adding unit test for rendering site and fixing LP export issue #46
@@ -0,0 +1,54 @@
|
||||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import GLPK from 'glpk.js';
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method === 'POST') {
|
||||
const { objective, constraints } = req.body;
|
||||
|
||||
try {
|
||||
const glpk = await GLPK();
|
||||
const options = {
|
||||
msglev: glpk.GLP_MSG_ALL,
|
||||
presol: true,
|
||||
cb: {
|
||||
call: (progress: any) => console.log(progress),
|
||||
each: 1
|
||||
}
|
||||
};
|
||||
|
||||
const problem = {
|
||||
name: 'LP',
|
||||
objective: {
|
||||
direction: objective.direction === 'max' ? glpk.GLP_MAX : glpk.GLP_MIN,
|
||||
name: 'obj',
|
||||
vars: objective.vars
|
||||
},
|
||||
subjectTo: constraints.map((c: any) => ({
|
||||
name: c.name,
|
||||
vars: c.vars,
|
||||
bnds: {
|
||||
type: glpk.GLP_UP,
|
||||
ub: c.bnds.ub,
|
||||
lb: c.bnds.lb
|
||||
}
|
||||
}))
|
||||
};
|
||||
|
||||
const result = glpk.solve(problem, options);
|
||||
|
||||
const lpFormat = `\n# Problem Definition\n
|
||||
name: ${problem.name}\n
|
||||
# Objective Function\n
|
||||
${problem.objective.direction === glpk.GLP_MAX ? 'max' : 'min'} ${problem.objective.vars.map((v: any) => `${v.coef} ${v.name}`).join(' + ')}\n
|
||||
# Constraints\n
|
||||
${problem.subjectTo.map((c: any) => `${c.vars.map((v: any) => `${v.coef} ${v.name}`).join(' + ')} ${c.bnds.ub ? `<= ${c.bnds.ub}` : ''}`).join('\n')}\n`;
|
||||
|
||||
res.status(200).json({ result, lpFormat });
|
||||
} catch (error) {
|
||||
console.error('Error processing optimization:', error);
|
||||
res.status(500).json({ message: 'Error processing optimization', error: error.message });
|
||||
}
|
||||
} else {
|
||||
res.status(405).json({ message: 'Only POST method is allowed' });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import GLPK from 'glpk.js';
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method === 'POST') {
|
||||
const { objective, constraints, bounds } = 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 => ({ name: v.name, coef: v.coef }))
|
||||
},
|
||||
subjectTo: constraints.map(c => ({
|
||||
name: c.name,
|
||||
vars: c.vars.map(v => ({ name: v.name, coef: v.coef })),
|
||||
bnds: {
|
||||
type: glpk.GLP_UP,
|
||||
lb: c.bnds.lb,
|
||||
ub: c.bnds.ub
|
||||
}
|
||||
})),
|
||||
binaries: objective.vars.map(v => v.name),
|
||||
generals: objective.vars.map(v => v.name)
|
||||
};
|
||||
|
||||
const result = glpk.solve(problem, options);
|
||||
res.status(200).json({ result });
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: 'Error processing optimization', error: error.message });
|
||||
}
|
||||
} else {
|
||||
res.status(405).json({ message: 'Only POST method is allowed' });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
|
||||
export default function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method === 'POST') {
|
||||
res.status(200).json({ message: 'API is working!' });
|
||||
} else {
|
||||
res.status(405).json({ message: 'Method not allowed' });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
type VariableLP = { name: string; coef: number };
|
||||
type ConstraintLP = {
|
||||
name: string;
|
||||
vars: VariableLP[];
|
||||
bnds: { ub: number; lb: number };
|
||||
};
|
||||
|
||||
interface ProblemLP {
|
||||
objective: {
|
||||
vars: VariableLP[];
|
||||
};
|
||||
constraints: ConstraintLP[];
|
||||
}
|
||||
|
||||
function createProblemLP(
|
||||
objectiveVars: VariableLP[],
|
||||
constraints: { name: string; vars: VariableLP[]; ub: number; lb: number }[]
|
||||
): ProblemLP {
|
||||
const constraintsFormatted: ConstraintLP[] = constraints.map((constraint) => ({
|
||||
name: constraint.name,
|
||||
vars: constraint.vars,
|
||||
bnds: {
|
||||
ub: constraint.ub,
|
||||
lb: constraint.lb
|
||||
}
|
||||
}));
|
||||
|
||||
const problem: ProblemLP = {
|
||||
objective: {
|
||||
vars: objectiveVars
|
||||
},
|
||||
constraints: constraintsFormatted
|
||||
};
|
||||
|
||||
return problem;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
interface VariableMIP {
|
||||
name: string;
|
||||
coef: number;
|
||||
}
|
||||
|
||||
interface Bounds {
|
||||
type: number;
|
||||
ub: number;
|
||||
lb: number;
|
||||
}
|
||||
|
||||
interface ConstraintMIP {
|
||||
name: string;
|
||||
vars: VariableMIP[];
|
||||
bnds: Bounds;
|
||||
}
|
||||
|
||||
interface Options {
|
||||
mipgap: number;
|
||||
tmlim: number;
|
||||
msglev: number;
|
||||
}
|
||||
|
||||
interface Problem {
|
||||
name: string;
|
||||
objective: {
|
||||
direction: "min" | "max";
|
||||
name: string;
|
||||
vars: VariableMIP[];
|
||||
};
|
||||
constraints: ConstraintMIP[];
|
||||
binaries?: string[];
|
||||
generals?: string[];
|
||||
options: Options;
|
||||
}
|
||||
|
||||
function createProblemMIP(
|
||||
name: string,
|
||||
direction: "min" | "max",
|
||||
objectiveName: string,
|
||||
objectiveVars: VariableMIP[],
|
||||
constraints: { name: string; vars: VariableMIP[]; bnds_type: number; ub: number; lb: number }[],
|
||||
binaries: string[],
|
||||
generals: string[] = [],
|
||||
mipgap: number,
|
||||
tmlim: number,
|
||||
msglev: number
|
||||
): Problem {
|
||||
const constraintsFormatted: ConstraintMIP[] = constraints.map((constraint) => ({
|
||||
name: constraint.name,
|
||||
vars: constraint.vars,
|
||||
bnds: {
|
||||
type: constraint.bnds_type,
|
||||
ub: constraint.ub,
|
||||
lb: constraint.lb
|
||||
}
|
||||
}));
|
||||
|
||||
const problem: Problem = {
|
||||
name: name,
|
||||
objective: {
|
||||
direction: direction,
|
||||
name: objectiveName,
|
||||
vars: objectiveVars
|
||||
},
|
||||
constraints: constraintsFormatted,
|
||||
binaries: binaries.length > 0 ? binaries : undefined,
|
||||
generals: generals.length > 0 ? generals : undefined,
|
||||
options: {
|
||||
mipgap: mipgap,
|
||||
tmlim: tmlim,
|
||||
msglev: msglev
|
||||
}
|
||||
};
|
||||
|
||||
return problem;
|
||||
}
|
||||
Reference in New Issue
Block a user