With the code i posted, i was able to add additional constraints to testmodel1 without modifying testmodel. This made me believe that it might be a deep copy. But obviously it was not 100% (if that's even possible).
For now following your advise seems to be the clever one. I use getExpr to recreate the equations.
Maybe different using environments would somehow isolate the models, dont know yet.
Original Message:
Sent: Mon October 16, 2023 06:26 AM
From: Hugues Juille
Subject: CPLEX C++ Add columns to a deep copy of an IloModel
Dear Ozan,
I'm still confused about the "deep copy" snippet...
I did a simple experiment where I edited "cnstr" in "testmodel" (duplicating the same loop, but using different values for the coefs) AFTER "testmodel1" has been created using the iterator over IloModel entities.
Then, I displayed both models as follows:
IloModel testmodel1(testenv); for (IloModel::Iterator it(testmodel); it.ok(); ++it) { testmodel1.add(*it); } testenv.out() << "=========================================" << std::endl; for (int i = 0; i < cnstr.getSize(); i++) { cnstr[i].setLinearCoef(x[0], (6 - i) + 2); // Arbitrary updates to original constraints... cnstr[i].setLinearCoef(x[1], i * 11 + 1); cnstr[i].setUB(10 * (49 - i) - 2); } testenv.out() << "=========================================" << std::endl; for (IloModel::Iterator it(testmodel); it.ok(); ++it) { IloExtractable e = *it; testenv.out() << "TestModel : " << e << std::endl; } for (IloModel::Iterator it(testmodel1); it.ok(); ++it) { IloExtractable e = *it; testenv.out() << "TestModel1 : " << e << std::endl; }
The same information is displayed for both models, meaning that a shallow copy was performed, not a deep copy.
Could you replicate the experiment on your side ?
Is performing a deep copy of the model the only possibility in your application ? Wouldn't it be better to just recreate a new model from scratch for testmodel1 ?
Best regards,
------------------------------
Hugues Juille
Original Message:
Sent: Fri October 13, 2023 03:53 PM
From: ozan aksu
Subject: CPLEX C++ Add columns to a deep copy of an IloModel
Dear Hugues
Thank you for your reply. I think i am creating a deep model because adding new constraints to the copy does not affect the original model:
IloRangeArray cnstr1 = CreateRangeArray; testmodel1.add(cnstr1);
However adding columns only to testmodel1
is not possible:
IloNumColumn col(testenv);col += testobj(int);for (int i = 0; i < cnstr.getSize(); ++i) { col += cnstr[i](int);}IloNumVar newVar(col, 0, 1, ILOFLOAT);testmodel1.add(newVar);
This is probably because I don't have copies of IloObjective and IloRangeArray. How can i create those copies? Or in general how can i add new columns to testmodel1
without modifying testmodel
?
------------------------------
ozan aksu
Original Message:
Sent: Tue October 10, 2023 06:08 AM
From: Hugues Juille
Subject: CPLEX C++ Add columns to a deep copy of an IloModel
Dear Ozan,
My understanding of your code is that by iterating over the `testmodel` entities, you are creating a shallow copy of the model (not a deep copy). This means that both models are then updated when a new column is added.
Anyway, trying to clone and edit a model can be confusing and lead to unnecessary complications. I would rather advice to wrap the creation of your model in a function, and then invoking this function a second time to create a new instance of the model.
Best regards,
------------------------------
Hugues Juille
Original Message:
Sent: Sun October 08, 2023 08:35 PM
From: ozan aksu
Subject: CPLEX C++ Add columns to a deep copy of an IloModel
i used the code of user Marko Reclic to create a deep copy of an IloModel
.
IloEnv testenv;IloModel testmodel(testenv);IloCplex testcplex(testmodel);IloNumVarArray x = CreateNumVarArray(testenv, 2, "x", 0, 1);IloObjective testobj = IloMaximize(testenv, IloSum(x));testmodel.add(testobj);IloRangeArray cnstr = CreateRangeArray(testenv, 3, "c");for (int i = 0; i < cnstr.getSize(); i++) { cnstr[i].setLinearCoef(x[0], (3 - i) + 2); cnstr[i].setLinearCoef(x[1], i * 3 + 1); cnstr[i].setUB(10 * (5 - i) - 2);}testmodel.add(cnstr);IloModel testmodel1(testenv);for (IloModel::Iterator it(testmodel); it.ok(); ++it) testmodel1.add(*it);
My question is how to add new columns to testmodel1
. For testmodel
i would use the following code. I don't know what to apply for testmodel1
.
IloNumColumn col(testenv);col += testobj(22);for (int i = 0; i < cnstr.getSize(); ++i) { col += cnstr[i](i * 3 + 5);}x.add(IloNumVar(col, 0, 1, ILOFLOAT));
------------------------------
ozan aksu
------------------------------