GUROBI的C API中添加约束时间太长

问题描述 投票:0回答:1

我有一个模型,该模型具有113000个约束和127940个变量(28400个连续变量和99540个整数)。问题在于仅写入约束会花费太长时间(大约108秒)。解决需要32秒。我打算解决比这个更大的问题,并且所需时间增长很快。我认为这不应该花那么长时间。有没有办法在C API中更快地添加约束?我正在使用GRBaddconstr,它一一添加约束。在GUROBI中,还有另一个功能,即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);
c constraints gurobi
1个回答
1
投票

我相信问题是您给的是Gurobi约束的密集版本,而不是稀疏表示。考虑以下约束:

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

此处,no_variable等于127940。因此,尽管实际上在此约束中最多有两个变量具有非-零系数值。如果对每个约束都这样做,则可能会花费大量时间。为了提高效率,您只应传递具有非零系数的变量的Gurobi索引/值信息。有关更多详细信息,请检查GRBaddconstr这可以通过一些小的代码更改来解决。在documentation for GRBaddconstr循环之外,定义两个长度为2的数组,这些数组将在特定的“逻辑”约束中存储具有非零系数的变量的索引和值:

for

然后,在最里面的lInd = (int *) malloc(sizeof(int) * 2);
lVal = (double *) malloc(sizeof(double) * 2);
循环中,在添加每个约束之前,适当地设置这些索引和值:

for

最后,请注意约束应具有唯一的名称。如果约束具有重复的名称,则在尝试按名称访问约束,读取/写入模型文件等时,您可能会遇到意外的行为。
© www.soinside.com 2019 - 2024. All rights reserved.