加速单纯形算法

时间:2015-04-02 12:51:35

标签: javascript arrays algorithm mathematical-optimization simplex

我正在玩我在这里找到的一个很好的单纯形算法:https://github.com/JWally/jsLPSolver/

我创建了一个jsfiddle,我已经设置了一个模型,并使用上面的算法解决了问题。 http://jsfiddle.net/Guill84/qds73u0f/

该模型基本上是一长串变量和约束。您可以将其视为试图在不同的枢纽(国家)之间找到最便宜的乘客运输方式,每个国家对乘客的需求最少,乘客最多,每个连接都有价格。我不在乎乘客去哪里,我只是想找到最便宜的方式来分发它们。为实现这一目标,我使用以下最小化目标:

model = {
        "optimize": "cost",
            "opType": "min",
            "constraints": { \\etc... 

我对模型和算法提供的答案感到满意......但后者需要很长时间才能运行(> 15秒......)有什么方法可以加快计算速度吗?

亲切的问候,谢谢。 -G。

3 个答案:

答案 0 :(得分:4)

听起来好像有minimum-cost flow problem。 Zealint有一个看似合理的TopCoder tutorial on min-cost flow,它涵盖了循环取消算法,这将是我的第一个建议(假设没有可以为你的LP求解器做快速优化)。如果那仍然太慢,那里有一整套文献。

由于你决定使用LP求解器解决这个问题,我的建议是编写一个更简单的求解器,它快速而贪婪但不是最理想的,并通过用LP来表达LP作为LP的起点。与起点不同。

答案 1 :(得分:3)

<@> @Noobster,我很高兴除了我之外的其他人正在使用我的Simplex库。我经历了,看着它,并且和你一样(10 - 20秒)。有一段代码不必要地转换数组,将RHS转换成2d数组的1d数组。有了你的问题,每次发生这种情况都会导致性能降低60ms(对于你的问题,137次)。

我在回购中纠正了这个问题,我看到运行时间大约为2秒。可能有大量的代码清理这样的优化需要发生,但我构建的问题集(http://mathfood.com)非常小,以至于我从来不知道这是一个问题。谢谢!

为了它的价值,我把大学教科书中的单纯形算法转化为代码; MILP文章来自维基百科。

答案 2 :(得分:2)

想出来。最昂贵的代码是旋转操作;事实证明,通过添加0来更新矩阵需要做很多工作。事先做一点逻辑以防止这会使节点上的运行时间从~12秒减少到~0.5。

    for (i = 0; i < length; i++) {
        if (i !== row) {
            pivot_row = tbl[i][col];
            for (j = 0; j < width; j++) {


                // No point in doing math if you're just adding
                // Zero to the thing


                if (pivot_row !== 0 && tbl[row][j] !== 0) {
                    tbl[i][j] += -pivot_row * tbl[row][j];
                }
            }
        }
    }