Pinned topic Providing data to OPL model through C++/Java interface
I mainly use CP Optimizer from the C++ Concert API and am most familiar with that. However, for an application, I need to use OPL, in particular through the C++ interface to OPL and in a setting where there will be multiple runs with partially revised data (explained below). The initial data as well as partially revised data will come in naturally as C++ objects. I am wondering, what is the recommended way to provide data to the OPL model without using .dat (or Excel or other) files?
In more detail, the model, specified as a .mod file, expects certain (possibly large) initialization data that is fed once, and then additional auxiliary data that changes from one run of the underlying CP Optimizer to the next run.
With .dat files, the most natural way seems to be to create init.dat and use auxiliary data files aux_1.dat, aux_2.dat, ... as new auxiliary data arrives. That is, I would first create a single DataSource once for init.dat. Then, when auxiliary data for the i-th run arrives, create another DataSource for aux_i, add both this and the init DataSource to the model, and run the solver.
First, is this the right way of using .dat files in this context? In particular, what is unclear to me is whether creating the DataSource for init.dat will actually parse the (possibly large) init.dat file right away or will this be done when the DataSource is actually added to the OPL model once for each run (which is not ideal).
Second, since all data is arriving in my context as C++ objects, is there a more direct, in-memory way of providing this data to the OPL model? One simple way I found was to use DataSource creation from an "istream" object, with something like:
ss << "NbResources = 7;" << endl;
ss << "NbItems = 12;" << endl;
ss << "Capacity = 20 40 35 ;" << endl;
ss << "Use = [ \
0 1 2 3 4 5 6 7 8 9 10 11 \
3 2 1 0 1 2 3 4 5 6 7 8 \
6 5 4 3 2 1 0 1 2 3 4 5 ];" << endl;
opl.addDataSource(IloOplDataSource(env, ss, "initData");
Then I would do the same each time auxiliary data arrives, fully clearing the OPL model in-between two runs of the solver. This seems to be essentially replicating in memory what a .dat file would have provided. But this goes through strings and isn't ideal for type checking, etc.
I also saw some examples in the forum and the documentation to directly manipulate IloTuples from the C++ interface, but couldn't get it to work easily. E.g., accessing model elements using IloOpl.getElement() is ok, but setting values of pure IloInt objects such as NbResources seems somewhat tricky (I saw http://www-01.ibm.com/support/docview.wss?uid=swg21401478 which talks of creating a new data element but suggesting that all elements have to be added one by one, in order to change the values of a few). Similarly, looping over arrays doesn't seem as natural as I see in the C++ Concert interface.
Do you have suggestions (and possibly an example) for how best to provide data to the OPL model in this setting? I wouldn't be surprised if this has been asked and answered earlier, but I couldn't locate the answer.
Thanks in advance!
ArnaudS 2700038GVE8 Posts
Re: Providing data to OPL model through C++/Java interface2013-04-26T08:19:31ZThis is the accepted answer. This is the accepted answer.
You should have a look to the custom data source mechanism.
You could find more detail in this example:
Hope this helps,