高分数
刚才 建 议 顿 带有 TypeScript 绑定的解析器 。 支持线性编程和混合整数线性编程,在节点和浏览器环境中运行,运行时依赖度为零.
解析器的标记胶被装入了普通的相亲 import(),因此软件包既可以拆分(作为本地ES模块提供),也可以在捆绑器(webpack and vite)下分解出,这可以静态地解决导入问题,并将胶水和相干放入你的捆绑.
基本用途
这个 HiGHS 类可直接访问解析器。 问题可以从字符串中装入 CPLEX 缩写 或者说 移动 格式.
import { HiGHS } from '@bubblyworld/highs-ts';
const lp = `
Maximize
obj: x + 2 y
Subject To
c1: x + y <= 10
c2: x <= 5
Bounds
0 <= x <= 10
0 <= y <= 10
End
`;
const highs = await HiGHS.create();
await highs.parse(lp, 'lp');
const result = await highs.solve();
console.log(result.status); // @expect: result.status === 'optimal'
console.log(result.objective); // @expect: result.objective === 20
console.log(result.solution); // Map { 'x' => 0, 'y' => 10 }
highs.free();
原始列输入
对于大型模型来说,序列化到LP/MPS文本并重新解析成为
主要成本. passModel 跳过两者:它直接复制输入的数组
通过 Highs_passLp (或 Highs_passMip 何时 integrality 实值
页:1 约束矩阵很稀少, 默认情况下按行排列, 并且有边框
默认为 0 <= x < +inf 列和 -inf < row < +inf 用于行 -
通过 HIGHS_INF 明确你需要它的地方. getSolutionValues 读取
溶液因列指数而密集回放,这是自
生列无名.
import { HiGHS } from '@bubblyworld/highs-ts';
// The same problem as above, in columnar form.
const highs = await HiGHS.create();
highs.passModel({
numCol: 2,
numRow: 2,
sense: 'maximize',
colCost: Float64Array.from([1, 2]),
colUpper: Float64Array.from([10, 10]),
rowUpper: Float64Array.from([10, 5]),
matrix: {
start: Int32Array.from([0, 2, 3]),
index: Int32Array.from([0, 1, 0]),
value: Float64Array.from([1, 1, 1]),
},
});
const result = await highs.solve();
const values = highs.getSolutionValues();
console.log(result.status); // @expect: result.status === 'optimal'
console.log(result.objective); // @expect: result.objective === 20
console.log(values[1]); // @expect: values[1] === 10
highs.free();
高级API
这个 Model class为程序上定义问题提供了构建器接口.
import { Model, sum } from '@bubblyworld/highs-ts';
const model = new Model();
// Variables: numVar (continuous), intVar (integer), boolVar (binary)
const x = model.numVar(0, 10, 'x');
const y = model.numVar(0, 10, 'y');
// Constraints with expressions
model.addConstraint(x.plus(y).leq(10), 'c1');
model.addConstraint(x.leq(5), 'c2');
// Objective
model.maximize(x.plus(y.times(2)));
const solution = await model.solve();
console.log(solution.status); // @expect: solution.status === 'optimal'
console.log(solution.objective); // @expect: solution.objective === 20
console.log(solution.getValue(x)); // 0
console.log(solution.getValue(y)); // 10
可变和约束名称可以是任何白空字符串. solve() 用 MPS 格式将模型交给解析器,它与 LP 语法不同,没有保留字符,所以名称像 item-cost 或者说 x[1,2] 没事了。 为了自己检查模特儿, model.print() 返回 CPLEX LP 文本,并 model.print('mps') 返回 MPS.
表达式支持链式算法 : plus(), (中文(简体) ), minus(), (中文(简体) ), times(), (中文(简体) ), neg(). 与 leq(), (中文(简体) ), geq(),以及 eq()编辑 sum() 帮助器结合多个名词,或者作为参数来扩展,或者作为一个单数组来传递(为非常大集合优先的数组形式),以及 solution.getValue() 对照溶液评价变量或任何线性表达式。 可以任意混合和匹配不同种类的变量和约束:
const model = new Model();
const x_a = model.intVar(0, 10, 'x_a');
const x_b = model.intVar(0, 8, 'x_b');
const y_a = model.boolVar('y_a');
const y_b = model.boolVar('y_b');
model.addConstraint(x_a.minus(y_a.times(10)).leq(0), 'cap_a');
model.addConstraint(x_b.minus(y_b.times(8)).leq(0), 'cap_b');
model.addConstraint(x_a.plus(x_b).leq(12), 'material');
model.maximize(
x_a.times(10)
.plus(x_b.times(12))
.minus(y_a.times(50))
.minus(y_b.times(60))
);
const solution = await model.solve();
console.log(solution.objective); // @expect: solution.objective === 50
建模初级
这个 Model 类包括一些用于常见MILP再生的更高级原始物,以基本变量和约束API为上. 逻辑操作( O)and, (中文(简体) ), or, (中文(简体) ), not, (中文(简体) ), xor)),主要制约因素addAtMost, (中文(简体) ), addAtLeast, (中文(简体) ), addExactly),指标, abs, (中文(简体) ), max, (中文(简体) ), min,以及 product 详细情况见资料来源。 本节其余部分涵盖一些不太明显的原始人.
半连续变量
一个半连续变量要么完全为零,要么位于一个范围内 [lb, ub],在两者之间没有值。 这对于模拟最小批量大小或部分激活不合理时的起/起决定是有用的.
const model = new Model();
const batch = model.semiContVar(100, 500, 'batch');
model.maximize(batch);
const solution = await model.solve();
console.log(solution.objective); // @expect: solution.objective === 500
整数师
divMod(expr, d) 返回商数和剩余变量,将非负整数表达式除以正整数常数.
const model = new Model();
const minutes = model.intVar(0, 1440, 'minutes');
const { quotient, remainder } = model.divMod(minutes, 60);
model.addConstraint(minutes.eq(145));
model.minimize(quotient);
const solution = await model.solve();
console.log(solution.objective); // @expect: solution.objective === 2
抑或制约
addEitherOr(c1, c2) 强制规定,必须至少有两个制约因素之一,在内部使用指标变量.
const model = new Model();
const x = model.numVar(0, 100, 'x');
const y = model.numVar(0, 100, 'y');
model.addEitherOr(x.leq(10), y.leq(10));
model.maximize(x.plus(y));
const solution = await model.solve();
console.log(solution.objective); // @expect: solution.objective === 110
重新编号
reify(constraint) 返回二进制变量 delta 只有在满足了约束的情况下,才算1。 这是将约束转换成变量用于其他表达式的最通俗的方法. 它支持 <=, (中文(简体) ), >=,以及 = 觉相.
const model = new Model();
const tasks = [
model.intVar(0, 10, 'a'),
model.intVar(0, 10, 'b'),
model.intVar(0, 10, 'c'),
];
const overloaded = tasks.map(t => model.reify(t.geq(8)));
model.addConstraint(sum(...overloaded).leq(1));
model.maximize(sum(...tasks));
const solution = await model.solve();
console.log(solution.objective); // @expect: solution.objective === 24
Epsilon默认为纯整数表达式(精确再化)为1,连续表达式为1e-6. epsilon和Big-M都可以通过选项被推翻:
const model = new Model();
const x = model.numVar(0, 100, 'x');
const delta = model.reify(x.leq(50), { bigM: 200, epsilon: 1e-4 });
model.addConstraint(delta.eq(1));
model.maximize(x);
const solution = await model.solve();
console.log(solution.objective); // @expect: solution.objective === 50
配置
主控台输出
默认情况下,解析器输出被压制. 为了启用进度记录, 通过明确的控制台配置 :
const highs = await HiGHS.create({
console: {
log: (msg) => console.log(msg),
error: (msg) => console.error(msg)
}
});
同一选项适用于 Model.solve()数字 :
const solution = await model.solve({
console: { log: console.log, error: console.error }
});
大楼
构建项目( WASM 汇编需要标记) :
npm run build
npm run build:ts
npm run build:wasm
运行测试套件( 需要一个与剧作家兼容的浏览器):
npm test
npm run test:node # Node only
npm run test:browser # Browser only (using Playwright)
启动开发服务器 :
npm run serve
许可证发放
这个包裹根据麻省理工学院的许可证获得许可. WASM 捆绑包括 顿,也根据麻省理工学院颁发许可证(许可证) (中文(简体) ).
鸣谢
大部分的功劳都归功于作者们 顿我刚刚把它打包好 用来在Javascript/型号上使用.