Apache commons SimplexSolver:OutOfMemoryError

Apache commons SimplexSolver: OutOfMemoryError

我有 841 个变量和 23382 个约束(对于 LP 来说不是特别大)的问题。

尽管如此,我在使用 Apache SimplexSolver 时遇到了 OutOfMemoryError,即使堆大小为 1GB。

根据错误跟踪,创建 Tableau 时会发生这种情况。矩阵非常稀疏,因为大多数约束只涉及两个或三个变量。对于 LinearConstraints,我使用的是 SparseRealVector(虽然不确定它是否带来任何东西)。

我可以在解算器上配置什么来解决这个问题吗?或者这仅仅是单纯形求解器的局限性?

谢谢

下面的例子:

@Test
public void simplexTest(){

    long[][] net = new long[][]{    
     {0, 746, 746, 797, 796, 846, 797, 848, 847, 847, 848, 848, 848, 898, 898, 898, 948, 899, 899, 949, 949, 950, 950, 1000, 1000, 1000, 1000, 1000, 1000}
    ,{-11, 0, 50, 786, 100, 100, 786, 837, 836, 836, 837, 837, 837, 887, 887, 887, 937, 888, 888, 938, 938, 939, 939, 989, 989, 989, 989, 989, 989}
    ,{-11, 0, 0, 786, 100, 100, 786, 837, 836, 836, 837, 837, 837, 887, 887, 887, 937, 888, 888, 938, 938, 939, 939, 989, 989, 989, 989, 989, 989}
    ,{-12, -1, -1, 0, 49, 99, 50, 836, 100, 100, 836, 836, 836, 886, 886, 886, 936, 887, 887, 937, 937, 938, 938, 988, 988, 988, 988, 988, 988}
    ,{-61, -50, -50, 736, 0, 50, 736, 787, 786, 786, 787, 787, 787, 837, 837, 837, 887, 838, 838, 888, 888, 889, 889, 939, 939, 939, 939, 939, 939}
    ,{-61, -50, -50, 736, 0, 0, 736, 787, 786, 786, 787, 787, 787, 837, 837, 837, 887, 838, 838, 888, 888, 889, 889, 939, 939, 939, 939, 939, 939}
    ,{-62, -51, -51, 0, -1, 49, 0, 786, 100, 100, 786, 786, 786, 836, 836, 836, 886, 837, 837, 887, 887, 888, 888, 938, 938, 938, 938, 938, 938}
    ,{-63, -52, -52, -1, -2, 48, -1, 0, 99, 49, 785, 785, 50, 100, 835, 100, 885, 836, 836, 886, 886, 887, 887, 937, 937, 937, 937, 937, 937}
    ,{-112, -101, -101, -50, -51, -1, -50, 736, 0, 0, 736, 736, 736, 786, 786, 786, 836, 787, 787, 837, 837, 838, 838, 888, 888, 888, 888, 888, 888}
    ,{-112, -101, -101, -50, -51, -1, -50, 736, 50, 0, 736, 736, 736, 786, 786, 786, 836, 787, 787, 837, 837, 838, 838, 888, 888, 888, 888, 888, 888}
    ,{-113, -102, -102, -51, -52, -2, -51, 735, -1, -1, 0, 50, 735, 785, 100, 785, 100, 786, 786, 836, 836, 837, 837, 887, 887, 887, 887, 887, 887}
    ,{-113, -102, -102, -51, -52, -2, -51, 735, -1, -1, 0, 0, 735, 785, 100, 785, 100, 786, 786, 836, 836, 837, 837, 887, 887, 887, 887, 887, 887}
    ,{-113, -102, -102, -51, -52, -2, -51, 0, 49, -1, 735, 735, 0, 100, 785, 100, 835, 786, 786, 836, 836, 837, 837, 887, 887, 887, 887, 887, 887}
    ,{-163, -152, -152, -101, -102, -52, -101, -50, -1, -51, 685, 685, -50, 0, 735, 0, 785, 736, 736, 786, 786, 787, 787, 837, 837, 837, 837, 837, 837}
    ,{-163, -152, -152, -101, -102, -52, -101, 685, -51, -51, -50, -50, 685, 735, 0, 735, 50, 736, 736, 786, 786, 787, 787, 837, 837, 837, 837, 837, 837}
    ,{-163, -152, -152, -101, -102, -52, -101, -50, -1, -51, 685, 685, -50, 50, 735, 0, 785, 736, 736, 786, 786, 787, 787, 837, 837, 837, 837, 837, 837}
    ,{-163, -152, -152, -101, -102, -52, -101, 685, -51, -51, -50, -50, 685, 735, 0, 735, 0, 736, 736, 786, 786, 787, 787, 837, 837, 837, 837, 837, 837}
    ,{-164, -153, -153, -102, -103, -53, -102, -51, -2, -52, -1, -1, -51, -1, 49, -1, 99, 0, 50, 100, 100, 786, 786, 836, 836, 836, 836, 836, 836}
    ,{-164, -153, -153, -102, -103, -53, -102, -51, -52, -52, -51, -51, -51, -1, -1, -1, 49, 0, 0, 100, 100, 786, 786, 836, 836, 836, 836, 836, 836}
    ,{-214, -203, -203, -152, -153, -103, -152, -101, -102, -102, -101, -101, -101, -51, -51, -51, -1, -50, -50, 0, 0, 736, 736, 786, 786, 786, 786, 786, 786}
    ,{-214, -203, -203, -152, -153, -103, -152, -101, -102, -102, -101, -101, -101, -51, -51, -51, -1, -50, -50, 50, 0, 736, 736, 786, 786, 786, 786, 786, 786}
    ,{-215, -204, -204, -153, -154, -104, -153, -102, -103, -103, -102, -102, -102, -52, -52, -52, -2, -51, -51, -1, -1, 0, 50, 100, 100, 785, 785, 785, 785}
    ,{-215, -204, -204, -153, -154, -104, -153, -102, -103, -103, -102, -102, -102, -52, -52, -52, -2, -51, -51, -1, -1, 0, 0, 100, 100, 785, 785, 785, 785}
    ,{-265, -254, -254, -203, -204, -154, -203, -152, -153, -153, -152, -152, -152, -102, -102, -102, -52, -101, -101, -51, -51, -50, -50, 0, 0, 735, 735, 735, 735}
    ,{-265, -254, -254, -203, -204, -154, -203, -152, -153, -153, -152, -152, -152, -102, -102, -102, -52, -101, -101, -51, -51, -50, -50, 50, 0, 735, 735, 735, 735}
    ,{-1000, -254, -254, -203, -204, -154, -203, -152, -153, -153, -152, -152, -152, -102, -102, -102, -52, -101, -101, -51, -51, -50, -50, 0, 0, 0, 0, 0, 0}
    ,{-1000, -254, -254, -203, -204, -154, -203, -152, -153, -153, -152, -152, -152, -102, -102, -102, -52, -101, -101, -51, -51, -50, -50, 0, 0, 0, 0, 0, 0}
    ,{-1000, -254, -254, -203, -204, -154, -203, -152, -153, -153, -152, -152, -152, -102, -102, -102, -52, -101, -101, -51, -51, -50, -50, 0, 0, 0, 0, 0, 0}
    ,{-1000, -254, -254, -203, -204, -154, -203, -152, -153, -153, -152, -152, -152, -102, -102, -102, -52, -101, -101, -51, -51, -50, -50, 0, 0, 0, 0, 0, 0}};

    int[][] edges = new int[][]{{7, 3},{7, 8},{7, 10},{7, 16},{7, 22},{7, 24},{7, 26},{13, 3},{13, 8},{13, 10},{13, 16},{13, 22},{13, 24},{13, 26},{17, 3},{17, 8},{17, 10},{17, 16},{17, 22},{17, 24},{17, 26}
    ,{19, 3},{19, 8},{19, 10},{19, 16},{19, 22},{19, 24},{19, 26},{21, 3},{21, 8},{21, 10},{21, 16},{21, 22},{21, 24},{21, 26},{23, 3},{23, 8},{23, 10},{23, 16},{23, 22},{23, 24},{23, 26}
    ,{25, 3},{25, 8},{25, 10},{25, 16},{25, 22},{25, 24},{25, 26},{7, 1},{7, 5},{7, 11},{7, 14},{7, 18},{7, 20},{7, 27},{13, 1},{13, 5},{13, 11},{13, 14},{13, 18},{13, 20},{13, 27}
    ,{17, 1},{17, 5},{17, 11},{17, 14},{17, 18},{17, 20},{17, 27},{19, 1},{19, 5},{19, 11},{19, 14},{19, 18},{19, 20},{19, 27},{21, 1},{21, 5},{21, 11},{21, 14},{21, 18},{21, 20},{21, 27}
    ,{23, 1},{23, 5},{23, 11},{23, 14},{23, 18},{23, 20},{23, 27},{25, 1},{25, 5},{25, 11},{25, 14},{25, 18},{25, 20},{25, 27},{7, 2},{7, 4},{7, 6},{7, 9},{7, 12},{7, 15},{7, 28}
    ,{13, 2},{13, 4},{13, 6},{13, 9},{13, 12},{13, 15},{13, 28},{17, 2},{17, 4},{17, 6},{17, 9},{17, 12},{17, 15},{17, 28},{19, 2},{19, 4},{19, 6},{19, 9},{19, 12},{19, 15},{19, 28}
    ,{21, 2},{21, 4},{21, 6},{21, 9},{21, 12},{21, 15},{21, 28},{23, 2},{23, 4},{23, 6},{23, 9},{23, 12},{23, 15},{23, 28},{25, 2},{25, 4},{25, 6},{25, 9},{25, 12},{25, 15},{25, 28}
    ,{3, 7},{3, 13},{3, 17},{3, 19},{3, 21},{3, 23},{3, 25},{8, 7},{8, 13},{8, 17},{8, 19},{8, 21},{8, 23},{8, 25},{10, 7},{10, 13},{10, 17},{10, 19},{10, 21},{10, 23},{10, 25}
    ,{16, 7},{16, 13},{16, 17},{16, 19},{16, 21},{16, 23},{16, 25},{22, 7},{22, 13},{22, 17},{22, 19},{22, 21},{22, 23},{22, 25},{24, 7},{24, 13},{24, 17},{24, 19},{24, 21},{24, 23},{24, 25}
    ,{26, 7},{26, 13},{26, 17},{26, 19},{26, 21},{26, 23},{26, 25},{3, 1},{3, 5},{3, 11},{3, 14},{3, 18},{3, 20},{3, 27},{8, 1},{8, 5},{8, 11},{8, 14},{8, 18},{8, 20},{8, 27}
    ,{10, 1},{10, 5},{10, 11},{10, 14},{10, 18},{10, 20},{10, 27},{16, 1},{16, 5},{16, 11},{16, 14},{16, 18},{16, 20},{16, 27},{22, 1},{22, 5},{22, 11},{22, 14},{22, 18},{22, 20},{22, 27}
    ,{24, 1},{24, 5},{24, 11},{24, 14},{24, 18},{24, 20},{24, 27},{26, 1},{26, 5},{26, 11},{26, 14},{26, 18},{26, 20},{26, 27},{3, 2},{3, 4},{3, 6},{3, 9},{3, 12},{3, 15},{3, 28}
    ,{8, 2},{8, 4},{8, 6},{8, 9},{8, 12},{8, 15},{8, 28},{10, 2},{10, 4},{10, 6},{10, 9},{10, 12},{10, 15},{10, 28},{16, 2},{16, 4},{16, 6},{16, 9},{16, 12},{16, 15},{16, 28}
    ,{22, 2},{22, 4},{22, 6},{22, 9},{22, 12},{22, 15},{22, 28},{24, 2},{24, 4},{24, 6},{24, 9},{24, 12},{24, 15},{24, 28},{26, 2},{26, 4},{26, 6},{26, 9},{26, 12},{26, 15},{26, 28}
    ,{1, 7},{1, 13},{1, 17},{1, 19},{1, 21},{1, 23},{1, 25},{5, 7},{5, 13},{5, 17},{5, 19},{5, 21},{5, 23},{5, 25},{11, 7},{11, 13},{11, 17},{11, 19},{11, 21},{11, 23},{11, 25}
    ,{14, 7},{14, 13},{14, 17},{14, 19},{14, 21},{14, 23},{14, 25},{18, 7},{18, 13},{18, 17},{18, 19},{18, 21},{18, 23},{18, 25},{20, 7},{20, 13},{20, 17},{20, 19},{20, 21},{20, 23},{20, 25}
    ,{27, 7},{27, 13},{27, 17},{27, 19},{27, 21},{27, 23},{27, 25},{1, 3},{1, 8},{1, 10},{1, 16},{1, 22},{1, 24},{1, 26},{5, 3},{5, 8},{5, 10},{5, 16},{5, 22},{5, 24},{5, 26}
    ,{11, 3},{11, 8},{11, 10},{11, 16},{11, 22},{11, 24},{11, 26},{14, 3},{14, 8},{14, 10},{14, 16},{14, 22},{14, 24},{14, 26},{18, 3},{18, 8},{18, 10},{18, 16},{18, 22},{18, 24},{18, 26}
    ,{20, 3},{20, 8},{20, 10},{20, 16},{20, 22},{20, 24},{20, 26},{27, 3},{27, 8},{27, 10},{27, 16},{27, 22},{27, 24},{27, 26},{1, 2},{1, 4},{1, 6},{1, 9},{1, 12},{1, 15},{1, 28}
    ,{5, 2},{5, 4},{5, 6},{5, 9},{5, 12},{5, 15},{5, 28},{11, 2},{11, 4},{11, 6},{11, 9},{11, 12},{11, 15},{11, 28},{14, 2},{14, 4},{14, 6},{14, 9},{14, 12},{14, 15},{14, 28}
    ,{18, 2},{18, 4},{18, 6},{18, 9},{18, 12},{18, 15},{18, 28},{20, 2},{20, 4},{20, 6},{20, 9},{20, 12},{20, 15},{20, 28},{27, 2},{27, 4},{27, 6},{27, 9},{27, 12},{27, 15},{27, 28}
    ,{2, 7},{2, 13},{2, 17},{2, 19},{2, 21},{2, 23},{2, 25},{4, 7},{4, 13},{4, 17},{4, 19},{4, 21},{4, 23},{4, 25},{6, 7},{6, 13},{6, 17},{6, 19},{6, 21},{6, 23},{6, 25}
    ,{9, 7},{9, 13},{9, 17},{9, 19},{9, 21},{9, 23},{9, 25},{12, 7},{12, 13},{12, 17},{12, 19},{12, 21},{12, 23},{12, 25},{15, 7},{15, 13},{15, 17},{15, 19},{15, 21},{15, 23},{15, 25}
    ,{28, 7},{28, 13},{28, 17},{28, 19},{28, 21},{28, 23},{28, 25},{2, 3},{2, 8},{2, 10},{2, 16},{2, 22},{2, 24},{2, 26},{4, 3},{4, 8},{4, 10},{4, 16},{4, 22},{4, 24},{4, 26}
    ,{6, 3},{6, 8},{6, 10},{6, 16},{6, 22},{6, 24},{6, 26},{9, 3},{9, 8},{9, 10},{9, 16},{9, 22},{9, 24},{9, 26},{12, 3},{12, 8},{12, 10},{12, 16},{12, 22},{12, 24},{12, 26}
    ,{15, 3},{15, 8},{15, 10},{15, 16},{15, 22},{15, 24},{15, 26},{28, 3},{28, 8},{28, 10},{28, 16},{28, 22},{28, 24},{28, 26},{2, 1},{2, 5},{2, 11},{2, 14},{2, 18},{2, 20},{2, 27}
    ,{4, 1},{4, 5},{4, 11},{4, 14},{4, 18},{4, 20},{4, 27},{6, 1},{6, 5},{6, 11},{6, 14},{6, 18},{6, 20},{6, 27},{9, 1},{9, 5},{9, 11},{9, 14},{9, 18},{9, 20},{9, 27}
    ,{12, 1},{12, 5},{12, 11},{12, 14},{12, 18},{12, 20},{12, 27},{15, 1},{15, 5},{15, 11},{15, 14},{15, 18},{15, 20},{15, 27},{28, 1},{28, 5},{28, 11},{28, 14},{28, 18},{28, 20},{28, 27}};


    // build constraints from matrix 'net' and 'edges'
    List<LinearConstraint> constraints = new ArrayList<LinearConstraint>();

    int n = net.length;         
    for(int v=0; v<n; v++){
        for(int w=0; w<n; w++){
            for(int x=0; x<n; x++){

                if(v!=w && v!=x && w!=x){
                    double[] lhs = new double[n*n];                 
                    lhs[v*n+x] = 1;
                    lhs[v*n+w] = -1;
                    lhs[w*n+x] = -1;                
                    SparseRealVector vlhs = new OpenMapRealVector(lhs);
                    constraints.add(new LinearConstraint(vlhs, Relationship.LEQ, 0));                       
                }

            }
            double[] lhs = new double[n*n];
            lhs[v*n+w] = 1;
            SparseRealVector vlhs = new OpenMapRealVector(lhs);
            constraints.add(new LinearConstraint(vlhs, Relationship.LEQ, (int)net[v][w]));          
        }
        double[] lhs = new double[n*n];
        lhs[v*n+v] = 1;
        SparseRealVector vlhs = new OpenMapRealVector(lhs);
        constraints.add(new LinearConstraint(vlhs, Relationship.EQ, 0));
    }

    for(int i=0; i<edges.length; i++){
        double[] lhs = new double[n*n];
        lhs[n*edges[i][0]] = 1; // x -> z
        lhs[edges[i][1]] = 1; // z -> y     
        SparseRealVector vlhs = new OpenMapRealVector(lhs);
        constraints.add(new LinearConstraint(vlhs, Relationship.LEQ, (int)net[edges[i][0]][edges[i][1]]));          
    }

    // objective function: maximise sum of all variables
    double[] obj = new double[n*n];
    for(int i = 0; i<n*n; i++) {
        obj[i] = 1;
    }

    // solve
    LinearObjectiveFunction objective = new LinearObjectiveFunction(obj, 0);
    LinearConstraintSet constraintSet = new LinearConstraintSet(constraints);
    SimplexSolver solver = new SimplexSolver();
    PointValuePair solution = solver.optimize(objective, constraintSet, GoalType.MAXIMIZE);
}

将上面的评论总结成一个答案:

  • 这个求解器是一个非常简单的实现,基本上使用密集的教科书算法(没有人应该在实际实现中使用它)。周围有更好的求解器,包括以更有效的方式处理大型稀疏问题的求解器。

  • Coin CLP 是一个很好的 LP 求解器,并且有一个 java 接口。其他包括 glpk 和 google Or-Tools。