c - 在 GUROBI 的 C API 中添加约束需要太长时间

标签 c constraints gurobi

我有一个模型,有 113000 个约束和 127940 个变量(28400 个连续变量和 99540 个整数)。问题是只写约束花费的时间太长(大约 108 秒)。解决这个问题需要 32 秒。我打算解决比这更大的问题,并且所需的时间增长得非常快。我认为这不应该花这么长时间。有没有办法在 C API 中更快地添加约束?我正在使用GRBaddconstr,它一一添加约束。在 GUROBI 中,还有另一个函数,它是通过 Bathces 来完成此操作的,即 GRBaddconstrs,但在文档中它说实际上并没有太大的性能差异。另外,GRBaddconstrs的使用也相当困难。

我正在使用 GUROBI 8.1.0 的 C API。例如,写入一个约束集需要 50 秒以上。当我仅删除使用 GRBaddconstr 添加约束的行时,运行相同循环所需的时间不到一秒(99400 次迭代)。我的模型太大,无法附加在这里,而且很复杂,但我添加了我提到的循环,以防它可能有帮助。

//LOGICAL
                            time ( &rawtime );
                            timeinfo = localtime ( &rawtime );
                            printf("LOGICAL %d:%d:%d\n", timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);

                            int c=0;
                            int tmp,tmp2,tmp3;
                            int tmp_sabit;
                            int week_start=wk*T;
                            int week_end=(wk+1)*T;
                            for(int i=0;i<orders_length;i++){
                                for(int t = week_start; t < week_end; t++){
                                    tmp_sabit=i*(T*no_scenarios)+(t-week_start)*no_scenarios+B_threshold;
                                    tmp2=(t-week_start)*no_of_terminals+booking[orders[i]].o;
                                    tmp3=(t-week_start+1)*no_of_terminals+booking[orders[i]].d;
                                    for(int w=0;w<no_scenarios;w++){
                                        tmp=tmp_sabit+w;
                                        val[tmp]=1;
                                        if(booking[orders[i]].o>0){

                                            val[tmp2]=-1;
                                            }
                                        else if(t+1<week_end)
                                            {                                   
                                            val[tmp3]=-1;
                                            }
                                        error = GRBaddconstr(model, no_variable, ind, val, GRB_LESS_EQUAL, 0, "LOGICAL");
                                        c++;
                                        //Initialise val to 0
                                        val[tmp]=0;
                                        if(booking[orders[i]].o>0){

                                            val[tmp2]=0;
                                            }
                                        else if(t+1<week_end)
                                            {
                                            val[tmp3]=0;
                                            }
                                        //for(int j = 0; j < no_variable; j++){val[j] = 0;}
                                        }
                                    }
                                }
                            error = GRBupdatemodel(model);

最佳答案

我认为问题在于您为 Gurobi 提供了约束的密集版本,而不是稀疏表示。考虑以下约束:

error = GRBaddconstr(model, no_variable, ind, val, GRB_LESS_EQUAL, 0, "LOGICAL");

此处,no_variable 等于 127940。因此,每次调用 GRBaddconstr 时,您都会向 Gurobi 传递所有 127940 个变量的系数值,尽管事实上,此约束中最多有两个变量具有非零系数值。如果您对每个约束都执行此操作,则可能会消耗大量时间。为了提高效率,您应该只传递具有非零系数的变量的 Gurobi 索引/值信息。检查documentation for GRBaddconstr了解更多详细信息。

这可以通过一些小的代码更改来修复。在 for 循环之外,定义两个长度为 2 的数组,用于存储特定“逻辑”约束中具有非零系数的变量的索引和值:

lInd = (int *) malloc(sizeof(int) * 2);
lVal = (double *) malloc(sizeof(double) * 2);

然后,在最里面的 for 循环中,在添加每个约束之前适本地设置这些索引和值:

lInd[0] = tmp_sabit + w;
lVal[0] = 1;

if (booking[orders[i]].o > 0) {
    lInd[1] = tmp2;
    lVal[1] = -1;
}
else if (t+1 < week_end) {                                   
    lInd[1] = tmp3;
    lVal[1] = -1;
}
else {
    lVal[1] = 0;
}

error = GRBaddconstr(model, 2, lInd, lVal, GRB_LESS_EQUAL, 0, NULL);

最后,请注意约束应该具有唯一的名称。如果约束具有重复的名称,则在尝试按名称访问约束、读/写模型文件等时可能会遇到意外行为。

关于c - 在 GUROBI 的 C API 中添加约束需要太长时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59897537/

相关文章:

postgresql - 如何查看取决于postgres中的主键约束

python - Gurobipy 优化 : Constraint to make variable value to be greater than 100 OR equal to 0

c++ - 在c++中将pcap文件解析为sip消息

c - 识别稀疏矩阵数组 C 的列中的 1

字符常量 :\000\xhh

constraints - Pyomo 约束 > 100000 或 0

C 编译器断言 : how to dynamically use them wherever the expression is fixed?

mysql - ERROR 1822 (HY000) : Failed to add the foreign key constraint. 缺少约束索引

python - Gurobi 多目标函数分层退化

callback - Julia JUMP Gurobi MIP - 查询并存储最佳目标并在运行时绑定(bind)