Saya memecahkan model yang memiliki dua jenis variabel, x[i][j] adalah ILOBOOL dan u[i] adalah ILOFLOAT. Saya mencoba menambahkan batasan malas ke model ini. Saya telah berhasil menambahkan batasan malas dengan benar dengan cara berikut:

std::stringstream name;
IloNumVar** x = new IloNumVar*[ins.n+1];
for(int i = 0; i < ins.n+1; ++i){
    x[i] = new IloNumVar[ins.n];
    for(int j = 0; j < ins.n; ++j){
        if(ins.has_edge(i,j) || i == ins.n){
            name << "x_" << i << "_" << j;
            x[i][j] = IloNumVar(env,0,1,ILOBOOL, name.str().c_str());
            name.str("");
        }
    }
}

IloNumVar* u = new IloNumVar[ins.n+1];
for(int i = 0; i < ins.n+1; ++i){
    name << "u_" << i;
    u[i] = IloNumVar(env,(i < ins.n) ? 1 : 0,ins.L+1,ILOFLOAT,name.str().c_str());
    name.str("");
}
/*Objective function and some other non-lazy Constraints
*/
cplex.extract(model);
for(int i = 0; i < ins.n; ++i){
    for(int j = 0; j < ins.n; ++j){
        if(ins.has_edge(i,j)){
            IloConstraint edge_con(x[i][j] + x[j][i]<= 1);
            name << "edge_" <<i << "_" << j;
            edge_con.setName(name.str().c_str());
            name.str("");
            try{
                cplex.addLazyConstraint(edge_con);
            }catch(IloCplex::InvalidCutException& ex){
                auto con = ex.getCut();
                std::cout << ex.getMessage() << " " << ex.getStatus();
                std::cout << con << "\n";
            }
        }
    }
}

Kode ini berfungsi dengan baik dan ketika saya mencetak .lp, ada batasan malas. Namun, ketika saya mengubah IloConstraint edge_con(x[i][j] + x[j][i]<= 1); menjadi IloConstraint edge_con(x[i][j] + x[j][i] + u[j] <= 1); saya mendapatkan pesan InvalidCutException: invalid cut -1. Mengapa pengecualian ini dilemparkan?

1
Victor Hugo 28 Maret 2020, 00:21

1 menjawab

Jawaban Terbaik

Mengubah komentar saya menjadi jawaban: Masalahnya adalah CPLEX tidak tahu tentang variabel u yang dirujuk dalam batasan malas.

Jika Anda menambahkan batasan reguler maka semua variabel dalam batasan secara otomatis diekstraksi ke CPLEX. Untuk kendala malas, semuanya berbeda: variabel tidak secara otomatis diekstraksi. Jadi jika batasan lazy merujuk pada variabel yang tidak digunakan dalam batasan reguler atau tujuan sebelumnya, maka CPLEX tidak akan mengetahui variabel ini. Ini akan mengakibatkan kegagalan untuk menambahkan potongan dan Anda akan mendapatkan pengecualian yang Anda amati.

Untuk memperbaikinya, tambahkan variabel u secara eksplisit ke masalah menggunakan

for (i = 0; i < ins.n+1; ++i)
    model.add(u[i]);

(dan mungkin melakukan hal yang sama untuk variabel x)

1
Daniel Junglas 2 April 2020, 08:36