001: // -------------------------------------------------------------- -*- C++ -*-
002: // File: iterators.cpp
003: // --------------------------------------------------------------------------
004: // Licensed Materials - Property of IBM
005: //
006: // 5725-A06 5725-A29 5724-Y48 5724-Y49 5724-Y54 5724-Y55
007: // Copyright IBM Corporation 1998, 2013. All Rights Reserved.
008: //
009: // Note to U.S. Government Users Restricted Rights:
010: // Use, duplication or disclosure restricted by GSA ADP Schedule
011: // Contract with IBM Corp.
012: ///////////////////////////////////////////////////////////////////////////////
013: 
014: #include <ilopl/iloopl.h>
015: 
016: #include <sstream>
017: 
018: #ifndef DATADIR
019: #ifdef ILO_WINDOWS
020: #define DIRSEP "\\"
021: #else
022: #define DIRSEP "/"
023: #endif
024: #define DATADIR ".." DIRSEP ".."  DIRSEP ".." DIRSEP ".." DIRSEP "opl" DIRSEP
025: #endif
026: 
027: ILOSTLBEGIN
028: 
029: // The purpose of this sample is to check the result of filtering by iterating on the generated data element.
030: //
031: // The data element is an array of strings that is indexed by a set of strings.
032: // It is filled as the result of an iteration on a set of tuples that filters out the duplicates.
033: // It is based on the model used in "Sparsity" run configuration of the "transp" example.
034: //
035: //
036: // The simplified model is:
037: //
038: // {string} Products = ...;
039: // tuple Route { string p; string o; string d; }
040: // {Route} Routes = ...;
041: // {string} orig[p in Products] = { o | <p,o,d> in Routes };
042: //
043: int sample1() {
044:     IloEnv env;
045:     int status = 127;
046:     try {
047:         IloOplRunConfiguration rc(env,
048:             DATADIR "transp" DIRSEP "transp2.mod",
049:             DATADIR "transp" DIRSEP "transp2.dat");
050:         IloOplModel opl = rc.getOplModel();
051:         opl.generate();
052: 
053:         cout << "Verification of the computation of orig: \n";
054: 
055:         // Get the orig, Routes, Product elements from the OplModel.
056:         IloSymbolSetMap orig = opl.getElement("Orig").asSymbolSetMap();
057:         IloTupleSet Routes = opl.getElement("Routes").asTupleSet();
058:         IloSymbolSet Products = opl.getElement("Products").asSymbolSet();
059: 
060:         // Iterate through the orig to see the result of the data element filtering.
061:         for (IloSymbolSetIterator it2(Products); it2.ok(); ++it2){
062:             const char* p = *it2;
063:             // This is the last dimension of the array (as it is a one-dimensional array), so you can use the get method directly.
064:             cout << "for p = " << p << " we have " << orig.get(p) << "\n";
065:         }
066:         cout << "---------------------\n";
067: 
068:         // Iterate through the TupleSet.
069:         for (IloTupleIterator it1(Routes); it1.ok(); ++it1){
070:             IloTuple t = *it1;
071:             // Get the string "p" from the tuple.
072:             const char* p = t.getStringValue("p");
073:             // if "p" is in the indexer, we will try to add the "o" string to the array.
074:             if (Products.contains(p)) cout << "for p = " << p << " we will have " << t.getStringValue("o") << " from " << t << "\n";
075:         }
076:         cout << "---------------------\n";
077:         status = 0;
078:     } catch (IloOplException & e) {
079:         status = 1;
080:         cout << "### OPL exception: " << e.getMessage() << endl;
081:     } catch( IloException & e ) {
082:         cout << "### CONCERT exception: ";
083:         e.print(cout);
084:         status = 2;
085:     } catch (...) {
086:         cout << "### UNEXPECTED ERROR ..." << endl;
087:         status = 3;
088:     }
089: 
090:     env.end();
091: 
092:     cout << endl << "--Press <Enter> to exit--" << endl;
093:     getchar();
094: 
095:     return status;
096: }
097: 
098: // The purpose of this sample is to output a multidimensional array x[i][j] to illustrate how arrays and subarrays are managed.
099: // To access the elements of an array, you must first access the subarrays up to  the last dimension, then you can get the values.
100: //  Here, as there are two dimensions, you have to get one subarray from which you can directly get the values.
101: //
102: // The array of integers is indexed by two sets of strings..
103: //
104: // The simplified model is:
105: //
106: // {string} s1 = ...;
107: // {string} s2 = ...;
108: // {int} x[s1][s2] = ...;
109: //
110: int sample2() {
111:     IloEnv env;
112:     int status = 0;
113:     try {
114:         IloOplRunConfiguration rc(env,DATADIR "iterators" DIRSEP "iterators.mod");
115:         IloOplModel opl = rc.getOplModel();
116:         opl.generate();
117: 
118:         // Get the x, s1 and s2 elements from the OplModel.
119:         IloIntMap x = opl.getElement("x").asIntMap();
120:         IloSymbolSet s1 = opl.getElement("s1").asSymbolSet();
121:         IloSymbolSet s2 = opl.getElement("s2").asSymbolSet();
122: 
123:         // Iterate on the first indexer.
124:         for (IloSymbolSetIterator it1(s1); it1.ok(); ++it1){
125:             // Get the second dimension array from the first dimension.
126:             IloIntMap sub = x.getSub(*it1);
127:             // Iterate on the second indexer of x (that is the indexer of the subarray).
128:             for (IloSymbolSetIterator it2(s2); it2.ok(); ++it2){
129:                 // This is the last dimension of the array, so you can directly use the get method.
130:                 cout << *it1 << " " << *it2 << " " << sub.get(*it2) << "\n";
131:             }
132:         }
133:         cout << "---------------------\n";
134:     } catch (IloOplException & e) {
135:         status = 1;
136:                 cout << "### OPL exception: " << e.getMessage() << endl;
137:         } catch( IloException & e ) {
138:         cout << "### exception: ";
139:         e.print(cout);
140:         status = 2;
141:     } catch (...) {
142:         cout << "### UNEXPECTED ERROR ..." << endl;
143:         status = 3;
144:     }
145: 
146:     env.end();
147:     return 0;
148: }
149: 
150: // The purpose of this sample is to output an array of tuples arrayT[i],
151: // to illustrate how tuple elements can be accessed.
152: // The simplified model is:
153: // tuple t
154: // {
155: //   int a;
156: //   int b;
157: // }
158: // {string} ids={"id1","id2","id3"};
159: // t arrayT[ids]=[<1,2>,<2,3>,<1,3>];
160: 
161: static char* getModelTextSample3 () {
162:         return (char*)"tuple t{int a;int b;} \
163:                   {string} ids = {\"id1\",\"id2\", \"id3\"};\
164:                   t arrayT[ids] = [<1,2>,<2,3>,<1,3>];";
165: }
166: int sample3() {
167:     int status = 0;
168:     IloEnv env;
169:     try {
170:         std::istringstream ins( getModelTextSample3() );
171:         IloOplModelSource src (env,ins,"tuple array iterator");
172:         IloOplErrorHandler errHandler(env, cout);
173:         IloOplSettings settings(env,errHandler);
174:         IloOplModelDefinition def(src, settings);
175:         IloCplex cplex(env);
176:         IloOplModel opl(def, cplex);
177:         opl.generate();
178: 
179:         // get the string set used to index the array of tuples
180:         IloTupleMap arrayT = opl.getElement("arrayT").asTupleMap();
181:         IloSymbolSet ids = IloAdvCollectionHelper::asSymbolSet(arrayT.getIndexer());
182:         // iterate on the index set to retrieve the tuples stored in the array
183:         for (IloSymbolSetIterator it(ids); it.ok(); ++it){
184:             cout << "arrayT[" << *it << "] = ";
185:             IloMapIndexArray id(env,0);
186:             id.add(*it);
187:             IloTuple t = arrayT.makeTuple();
188:             arrayT.getAt(id,t);
189:             cout << t << endl;
190:         }
191:     } catch (IloOplException & e) {
192:         status = 1;
193:                 cout << "### OPL exception: " << e.getMessage() << endl;
194:         } catch( IloException & e ) {
195:         cout << "### exception: ";
196:         e.print(cout);
197:         status = 2;
198:     } catch (...) {
199:         cout << "### UNEXPECTED ERROR ..." << endl;
200:         status = 3;
201:     }
202:     env.end();
203:     return status;
204: }
205: 
206: int main(int argc,char* argv[]) {
207:     int status = 0;
208:     status = status + sample1();
209:     status = status + sample2();
210:     status = status + sample3();
211:     return status;
212: }
213: 
214: