Skip to content

Commit

Permalink
support quadratic programs
Browse files Browse the repository at this point in the history
  • Loading branch information
DominikPeters committed Feb 21, 2024
1 parent 87a4565 commit 82a42a4
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 16 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,18 @@ console.log(`Objective value: ${model.ObjVal}`); // 17
console.log(`Included items: ${itemNames.filter(name => included[name].value > 0.5)}`); // A,B,D
```

### Example 3: quadratic objective function

The HiGHS solver supports (convex) quadratic objective functions. Quadratic terms are specified as length-3 arrays, with coefficient followed by the two variables that are being multiplied (which may be the same variable in case of a squared term). Here is an example of how to model a quadratic objective function.

```javascript
const x = model.addVar({ name: "x" });
model.addConstr([x], ">=", 10);
model.setObjective([[3, x, x]], "MINIMIZE"); // minimize 3 x^2
await model.solve(highs);
console.log(`Objective value: ${model.ObjVal}, with x = ${x.value}`); // 300, with x = 10
```

## API

<a name="new_module_lp-model.Model_new"></a>
Expand Down
3 changes: 3 additions & 0 deletions src/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,9 @@ export class Model {
* @see {@link https://www.npmjs.com/package/jsLPSolver}
*/
toJSLPSolverFormat(options) {
if (this.isQuadratic()) {
throw new Error("jsLPSolver does not support quadratic models.");
}
return toJSLPSolverFormat(this, options);
}

Expand Down
2 changes: 1 addition & 1 deletion src/write-lp-format.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export function toLPFormat(model) {
if (term.length === 2) {
return `${term[0]} ${term[1].name}`;
} else if (term.length === 3) {
return `[${term[0]} ${term[1].name} * ${term[2].name}]`;
return `[ ${term[0]*2} ${term[1].name} * ${term[2].name} ]/2`;
}
} else {
return `${term}`;
Expand Down
31 changes: 16 additions & 15 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,21 @@ async function testInfeasible() {
console.log(m.status);
}

// async function testQuadratic() {
// const LPModel = require('../dist/lp-model.js');
// const m = new LPModel.Model();
// const x = m.addVar({ name: "x" });
// const y = m.addVar({ name: "y" });
// m.setObjective([[1, x, x]], "MINIMIZE");
// m.addConstr([x, y], ">=", 1);

// console.log(m.toLPFormat());

// const highs = await require("highs")();
// m.solve(highs);
// console.log(x.value, y.value);
// }
// testQuadratic();
async function testQuadratic() {
const LPModel = require('../dist/lp-model.js');
const m = new LPModel.Model();
const x = m.addVar({ name: "x" });
m.setObjective([[1, x, x]], "MINIMIZE");
m.addConstr([x], ">=", 10);
m.addConstr([x], "<=", 20);

console.log(m.toLPFormat());

const highs = await require("highs")();
m.solve(highs);
console.log(x.value, x.value === 10);
console.log(m.ObjVal, m.ObjVal === 100);
}

async function testObjectiveConstantTerm() {
const LPModel = require('../dist/lp-model.js');
Expand All @@ -82,5 +82,6 @@ async function allTests() {
await test1();
await testInfeasible();
await testObjectiveConstantTerm();
await testQuadratic();
}
allTests();

0 comments on commit 82a42a4

Please sign in to comment.