Topic
15 replies Latest Post - ‏2010-01-18T07:46:36Z by SystemAdmin
SystemAdmin
SystemAdmin
7929 Posts
ACCEPTED ANSWER

Pinned topic IloNumVarArray.setNames();

‏2009-12-29T16:40:17Z |
Could anyone give me an example of how to use this method?

I find every element in an array can be named by setName, the method of IloNumVar. So when will the setNames method be used?
And what is the difference between setName and setNames, or what are the conveniences by using setNames?

Thank you for any help and wish you guys a happy new year!
Updated on 2010-01-18T07:46:36Z at 2010-01-18T07:46:36Z by SystemAdmin
  • SystemAdmin
    SystemAdmin
    7929 Posts
    ACCEPTED ANSWER

    Re: IloNumVarArray.setNames();

    ‏2009-12-29T17:18:22Z  in response to SystemAdmin
    > jimzhang wrote:
    > Could anyone give me an example of how to use this method?
    >
    > I find every element in an array can be named by setName, the method of IloNumVar. So when will the setNames method be used?
    > And what is the difference between setName and setNames, or what are the conveniences by using setNames?
    >
    > Thank you for any help and wish you guys a happy new year!

    I don't know that I've ever used it (it doesn't exist in the Java API, and I swore off C++ years ago), but presumably it saves you the effort of writing a loop -- you pass as its argument a vector of names and it assigns them sequentially to the variables in the array. The alternative (which you have to use in Java AFAIK) is to loop through the array and invoke setName on each element of the array.

    /Paul

    Mathematicians are like Frenchmen: whenever you say something to them, they translate it into their own language, and at once it is something entirely different. (Goethe)
    • SystemAdmin
      SystemAdmin
      7929 Posts
      ACCEPTED ANSWER

      Re: IloNumVarArray.setNames();

      ‏2009-12-29T17:43:49Z  in response to SystemAdmin
      Actually, before using setNames, all the elements in the array should be different, which means they should have been assigned different names already. So I think setNames may not save any loop for users...

      BTW: I found a lot of replies written by you when I googled the questions on clex. Thank you for your patience for anyone like me.
      • SystemAdmin
        SystemAdmin
        7929 Posts
        ACCEPTED ANSWER

        Re: IloNumVarArray.setNames();

        ‏2009-12-29T22:57:51Z  in response to SystemAdmin
        The argument you specify to setNames() is actually only a prefix for the
        names to be generated. The function will add the array index of each
        variable to that prefix to create a name. For example, the following code
        segment
        IloNumVarArray array(env);
        IloNumVar x(env);
        IloNumVar y(env);
        array.add(x);
        array.add(y);
        array.setNames("name");
         
        std::cout << x.getName() << ", " << y.getName() << std::endl;
        

        prints 'name[0], name[1]'.
        This provides an easy way to generate related names for variables.
        Updated on 2014-03-25T00:42:07Z at 2014-03-25T00:42:07Z by iron-man
        • SystemAdmin
          SystemAdmin
          7929 Posts
          ACCEPTED ANSWER

          Re: IloNumVarArray.setNames();

          ‏2009-12-29T23:16:33Z  in response to SystemAdmin
          Does that work? When I tried this method on Microsoft Visual Studio 2007, it responses with this error:
          problem signature:
          Problem Event Name: APPCRASH
          Application Name: application_name.exe
          Application Version: 0.0.0.0
          Application Timestamp: 4b3a8aaa
          Fault Module Name: application_name.exe
          Fault Module Version: 0.0.0.0
          Fault Module Timestamp: 4b3a8aaa
          Exception Code: c0000005
          Exception Offset: 003a7854
          OS Version: 6.0.6001.2.1.0.768.3
          Locale ID: 1033
          Additional Information 1: fd00
          Additional Information 2: ea6f5fe8924aaa756324d57f87834160
          Additional Information 3: fd00
          Additional Information 4: ea6f5fe8924aaa756324d57f87834160
          That is also one of motivations of my thread posted.
          Thank you for any help.
          • SystemAdmin
            SystemAdmin
            7929 Posts
            ACCEPTED ANSWER

            Re: IloNumVarArray.setNames();

            ‏2009-12-30T11:39:33Z  in response to SystemAdmin
            Hm, it worked for me on Linux. I did not try Windows.
            Can you post your code?
            • SystemAdmin
              SystemAdmin
              7929 Posts
              ACCEPTED ANSWER

              Re: IloNumVarArray.setNames();

              ‏2010-01-13T05:22:27Z  in response to SystemAdmin
              Sorry for the delay, I am just back from travel.

              #include <ilcplex/ilocplex.h>
              ILOSTLBEGIN

              int
              main(int argc, char **argv)
              {
              IloEnv env;
              IloNumVarArray array(env);
              IloNumVar x(env);
              IloNumVar y(env);
              array.add(x);
              array.add(y);
              array.setNames("name");
              std::cout << x.getName() << ", " << y.getName() << std::endl;
              env.end();

              return 0;
              }
              Error message:

              Problem signature:
              Problem Event Name: APPCRASH
              Application Name: CO2_Norm_Level.exe
              Application Version: 0.0.0.0
              Application Timestamp: 4b4d5869
              Fault Module Name: CO2_Norm_Level.exe
              Fault Module Version: 0.0.0.0
              Fault Module Timestamp: 4b4d5869
              Exception Code: c0000005
              Exception Offset: 002af844
              OS Version: 6.0.6001.2.1.0.768.3
              Locale ID: 1033
              Additional Information 1: fd00
              Additional Information 2: ea6f5fe8924aaa756324d57f87834160
              Additional Information 3: fd00
              Additional Information 4: ea6f5fe8924aaa756324d57f87834160

              Read our privacy statement:
              http://go.microsoft.com/fwlink/?linkid=50163&clcid=0x0409
              • SystemAdmin
                SystemAdmin
                7929 Posts
                ACCEPTED ANSWER

                Re: IloNumVarArray.setNames();

                ‏2010-01-13T07:13:46Z  in response to SystemAdmin
                Your code looks sane, so it looks like a bug in Cplex :-(
                I recall that you are using Visual Studio 2007, right?
                What version of Cplex do you use? And what version of Windows?
                • SystemAdmin
                  SystemAdmin
                  7929 Posts
                  ACCEPTED ANSWER

                  Re: IloNumVarArray.setNames();

                  ‏2010-01-13T15:15:20Z  in response to SystemAdmin
                  Thank you for your response,
                  The OS is Windows XP Professional Version 2002.
                  Service Pack 3
                  I am using Microsoft Visual C++ 2008 Express Edition.
                  Version of Cplex is 11.2.

                  Here is some information maybe useful, what's interesting is that the message mentioned "CPLEX Callable Library" instead of "CPLEX Concert Technology"...

                  <?xml version="1.0" encoding="UTF-16"?>
                  <DATABASE>
                  <EXE NAME="CO2_Norm_Level.exe" FILTER="GRABMI_FILTER_PRIVACY">
                  <MATCHING_FILE NAME="CO2_Norm_Level.exe" SIZE="4541952" CHECKSUM="0x743A956F" MODULE_TYPE="WIN32" PE_CHECKSUM="0x0" LINKER_VERSION="0x0" LINK_DATE="01/13/2010 15:04:22" UPTO_LINK_DATE="01/13/2010 15:04:22" />
                  <MATCHING_FILE NAME="cplex112.dll" SIZE="3919872" CHECKSUM="0xEEADFB08" BIN_FILE_VERSION="11.2.1.0" BIN_PRODUCT_VERSION="11.2.1.0" PRODUCT_VERSION="11.2" FILE_DESCRIPTION="CPLEX Callable Library" COMPANY_NAME="ILOG" PRODUCT_NAME="CPLEX Callable Library" FILE_VERSION="11.2.1" ORIGINAL_FILENAME="cplex112.dll" INTERNAL_NAME="cplex112.dll" LEGAL_COPYRIGHT="Copyright © ILOG 1997-2008" VERFILEDATEHI="0x0" VERFILEDATELO="0x0" VERFILEOS="0x4" VERFILETYPE="0x2" MODULE_TYPE="WIN32" PE_CHECKSUM="0x0" LINKER_VERSION="0x0" UPTO_BIN_FILE_VERSION="11.2.1.0" UPTO_BIN_PRODUCT_VERSION="11.2.1.0" LINK_DATE="11/28/2008 09:40:03" UPTO_LINK_DATE="11/28/2008 09:40:03" VER_LANGUAGE="English (United States) 0x409" />
                  </EXE>
                  <EXE NAME="kernel32.dll" FILTER="GRABMI_FILTER_THISFILEONLY">
                  <MATCHING_FILE NAME="kernel32.dll" SIZE="989696" CHECKSUM="0x2D998938" BIN_FILE_VERSION="5.1.2600.5781" BIN_PRODUCT_VERSION="5.1.2600.5781" PRODUCT_VERSION="5.1.2600.5781" FILE_DESCRIPTION="Windows NT BASE API Client DLL" COMPANY_NAME="Microsoft Corporation" PRODUCT_NAME="Microsoft® Windows® Operating System" FILE_VERSION="5.1.2600.5781 (xpsp_sp3_gdr.090321-1317)" ORIGINAL_FILENAME="kernel32" INTERNAL_NAME="kernel32" LEGAL_COPYRIGHT="© Microsoft Corporation. All rights reserved." VERFILEDATEHI="0x0" VERFILEDATELO="0x0" VERFILEOS="0x40004" VERFILETYPE="0x2" MODULE_TYPE="WIN32" PE_CHECKSUM="0xFE572" LINKER_VERSION="0x50001" UPTO_BIN_FILE_VERSION="5.1.2600.5781" UPTO_BIN_PRODUCT_VERSION="5.1.2600.5781" LINK_DATE="03/21/2009 14:06:58" UPTO_LINK_DATE="03/21/2009 14:06:58" VER_LANGUAGE="English (United States) 0x409" />
                  </EXE>
                  </DATABASE>
                • SystemAdmin
                  SystemAdmin
                  7929 Posts
                  ACCEPTED ANSWER

                  Re: IloNumVarArray.setNames();

                  ‏2010-01-13T15:17:33Z  in response to SystemAdmin
                  I need to double check the environment of the previous try, but I also tried in the environment mentioned above, and the errors seem to be similar...
                  • SystemAdmin
                    SystemAdmin
                    7929 Posts
                    ACCEPTED ANSWER

                    Re: IloNumVarArray.setNames();

                    ‏2010-01-13T21:44:44Z  in response to SystemAdmin
                    Bad news :-(
                    This problem is a known issue with CPLEX 11.2, or rather Concert 2.7.
                    It is fixed in more recent versions but there is no way to make this
                    work in your version.
                    Is this function vital for you? It should be easy to code up something
                    similar.
                    • SystemAdmin
                      SystemAdmin
                      7929 Posts
                      ACCEPTED ANSWER

                      Re: IloNumVarArray.setNames();

                      ‏2010-01-13T22:47:39Z  in response to SystemAdmin
                      Not really, I am just curious to know... Anyway I can use setName to assign names to every element.

                      Another question related to the multi-dim variable arrays is that When I am trying to create a multi-dimensional variable array which is higher than 2 dims by C++ concert technology, I found I had to use IloArray to create a 3-dim variable array and then use this to create a 4-dim... till the # of dims I want. I am wondering if there is any other good approach to do create a multi-dimensional variable array which has dims higher than 3? What's more, I am also afraid that the higher dims of variable arrays may bring up the storage issue especially when the array is sparse after solved, it will store a lot of '0's meaning a waste of space. So is there anything I can do to avoid this happen or at least to reduce to risk of that. Thank you very much for any suggestions.
                      • SystemAdmin
                        SystemAdmin
                        7929 Posts
                        ACCEPTED ANSWER

                        Re: IloNumVarArray.setNames();

                        ‏2010-01-14T07:28:36Z  in response to SystemAdmin
                        A very elegant solution to the multi-dimensional array problem is recursive templates.
                        Once you have defined such a template you can easily define multi-dimensional arrays
                        of any type. I sometimes use this one here:
                        template<unsigned int D,typename T> class Array;
                         
                        // Partial specialization to terminate instantiation recursion.
                        template<typename T>
                        struct Array<1,T> {
                           typedef T nested_type;
                           typedef std::vector<T> container_type;
                           typedef typename container_type::iterator iterator;
                           typedef typename container_type::const_iterator const_iterator;
                           typedef typename container_type::reverse_iterator reverse_iterator;
                           typedef typename container_type::const_reverse_iterator const_reverse_iterator;
                           typedef typename container_type::size_type size_type;
                           typedef typename container_type::reference reference;
                           typedef typename container_type::const_reference const_reference;
                           typedef typename container_type::pointer pointer;
                           typedef typename container_type::const_pointer const_pointer;
                           typedef typename container_type::difference_type difference_type;
                           typedef typename container_type::value_type value_type;
                           typedef T base_type;
                         
                           Array() : container() {}
                           template<typename I> Array(I const& i) : container(*i) {}
                         
                           // Default copy constructor and assignment operator are ok
                           // but are expensive.
                         
                           iterator begin() { return container.begin(); }
                           iterator end() { return container.end(); }
                           const_iterator begin() const { return container.begin(); }
                           const_iterator end() const { return container.end(); }
                         
                           reverse_iterator rbegin() { return container.rbegin(); }
                           reverse_iterator rend() { return container.rend(); }
                           const_reverse_iterator rbegin() const { return container.rbegin(); }
                           const_reverse_iterator rend() const { return container.rend(); }
                         
                           reference operator[](size_type idx) { return container[idx]; }
                           const_reference operator[](size_type idx) const { return container[idx]; }
                           reference at(size_type idx) { return container.at(idx); }
                           const_reference at(size_type idx) const { return container.at(idx); }
                         
                           size_type size() const { return container.size(); }   
                         
                           void fill(T const& t) {
                              for (iterator it = begin(); it != end(); ++it)
                                 *it = t;
                           }
                         
                        private:
                           container_type container;
                        };
                         
                        template<unsigned int D,typename T>
                        struct Array {
                           typedef Array<D-1,T> nested_type;
                           typedef typename std::vector<nested_type> container_type;
                           typedef typename container_type::iterator iterator;
                           typedef typename container_type::const_iterator const_iterator;
                           typedef typename container_type::reverse_iterator reverse_iterator;
                           typedef typename container_type::const_reverse_iterator const_reverse_iterator;
                           typedef typename container_type::size_type size_type;
                           typedef typename container_type::reference reference;
                           typedef typename container_type::const_reference const_reference;
                           typedef typename container_type::pointer pointer;
                           typedef typename container_type::const_pointer const_pointer;
                           typedef typename container_type::difference_type difference_type;
                           typedef typename container_type::value_type value_type;
                           typedef T base_type;
                         
                           Array() : container() {}
                         
                           template<typename I>
                           Array(I i) : container(*i, nested_type(i + 1)) {}
                         
                           // Default copy constructor and assignment operator are ok
                           // but are expensive.
                         
                        // template<typename C>
                        // Array(C const& c) : container(*c.begin(), c.begin() + 1) {}
                         
                           iterator begin() { return container.begin(); }
                           iterator end() { return container.end(); }
                           const_iterator begin() const { return container.begin(); }
                           const_iterator end() const { return container.end(); }
                         
                           reverse_iterator rbegin() { return container.rbegin(); }
                           reverse_iterator rend() { return container.rend(); }
                           const_reverse_iterator rbegin() const { return container.rbegin(); }
                           const_reverse_iterator rend() const { return container.rend(); }
                         
                           reference operator[](size_type idx) { return container[idx]; }
                           const_reference operator[](size_type idx) const { return container[idx]; }
                           reference at(size_type idx) { return container.at(idx); }
                           const_reference at(size_type idx) const { return container.at(idx); }
                         
                           size_type size() const { return container.size(); }
                         
                           void fill(T const& t) {
                              for (iterator it = begin(); it != end(); ++it)
                                 it->fill(t);
                           }
                         
                        private:
                           container_type container;
                        };
                        

                        Example use of this template is:
                        int
                        main(void)
                        {
                           unsigned int const dim[] = { 3, 4, 5 };
                           Array<3,int> array(dim);
                         
                           array[0][0][0] = 1;
                         
                           std::cout << array.size()
                                     << ", " << array[0].size()
                                     << ", " << array[0][0].size()
                                     << std::endl;
                         
                           std::vector<unsigned int> dim2(dim, dim + sizeof(dim) / sizeof(dim[0]));
                         
                           Array<3,int> array2(dim2.begin());
                           array2.fill(358);
                         
                           std::cout << array2.size()
                                     << ", " << array2[0].size()
                                     << ", " << array2[0][0].size()
                                     << ", " << array2[0][1][2]
                                     << std::endl;
                         
                           return 0;
                        }
                        


                        The implementation above is dense, i.e. it will suffer from the memory issues
                        you mentioned. In order to have a sparse version I would base the template
                        definition on map rather than vector:
                        template<unsigned int D,typename T> class SparseArray;
                         
                        // Partial specialization to terminate instantiation recursion.
                        template<typename T>
                        struct SparseArray<1,T> {
                           enum { dimension = 1 };
                           typedef std::map<int,T> container_type;
                           typedef typename container_type::iterator iterator;
                           typedef typename container_type::const_iterator const_iterator;
                           typedef typename container_type::reverse_iterator reverse_iterator;
                           typedef typename container_type::const_reverse_iterator const_reverse_iterator;
                           typedef typename container_type::size_type size_type;
                           typedef T &reference;
                           typedef T const &const_reference;
                           typedef T *pointer;
                           typedef T const *const_pointer;
                           typedef T base_type;
                         
                           SparseArray() : container() {}
                         
                           // Default copy constructor and assignment operator are ok
                           // but are expensive.
                         
                           iterator begin() { return container.begin(); }
                           iterator end() { return container.end(); }
                           iterator find(int idx) { return container.find(idx); }
                           const_iterator begin() const { return container.begin(); }
                           const_iterator end() const { return container.end(); }
                           const_iterator find(int idx) const { return container.find(idx); }
                         
                           reverse_iterator rbegin() { return container.rbegin(); }
                           reverse_iterator rend() { return container.rend(); }
                           const_reverse_iterator rbegin() const { return container.rbegin(); }
                           const_reverse_iterator rend() const { return container.rend(); }
                         
                           reference operator[](size_type idx) { return container[idx]; }
                           const_reference operator[](size_type idx) const { return container[idx]; }
                         
                           size_type size() const { return container.size(); }   
                         
                        private:
                           container_type container;
                        };
                         
                        template<unsigned int D,typename T>
                        struct SparseArray {
                           enum { dimension = D };
                           typedef SparseArray<D-1,T> nested_type;
                           typedef typename std::map<int,nested_type> container_type;
                           typedef typename container_type::iterator iterator;
                           typedef typename container_type::const_iterator const_iterator;
                           typedef typename container_type::reverse_iterator reverse_iterator;
                           typedef typename container_type::const_reverse_iterator const_reverse_iterator;
                           typedef typename container_type::size_type size_type;
                           typedef nested_type &reference;
                           typedef nested_type const &const_reference;
                           typedef nested_type *pointer;
                           typedef nested_type const *const_pointer;
                           typedef T base_type;
                         
                           // Default copy constructor and assignment operator are ok
                           // but are expensive.
                         
                           iterator begin() { return container.begin(); }
                           iterator end() { return container.end(); }
                           iterator find(int idx) { return container.find(idx); }
                           const_iterator begin() const { return container.begin(); }
                           const_iterator end() const { return container.end(); }
                           const_iterator find(int idx) const { return container.end(); }
                         
                           reverse_iterator rbegin() { return container.rbegin(); }
                           reverse_iterator rend() { return container.rend(); }
                           const_reverse_iterator rbegin() const { return container.rbegin(); }
                           const_reverse_iterator rend() const { return container.rend(); }
                         
                           reference operator[](size_type idx) { return container[idx]; }
                           const_reference operator[](size_type idx) const { return container[idx]; }
                         
                           size_type size() const { return container.size(); }
                         
                        private:
                           container_type container;
                        };
                        

                        Then you can do
                        int
                        main(void)
                        {
                           IloEnv env;
                         
                           SparseArray<3,IloNumVar> array;
                         
                           array[0][0][0] = IloNumVar(env, 0, 1, "x");
                           array[1][2][3] = IloNumVar(env, 0, 1, "y");
                         
                           std::cout << array[1][2][3].getName() << std::endl
                                     << array[0][0][0].getName() << std::endl;
                         
                           return 0;
                        }
                        

                        Caveat:
                        • Recursive templates require a decent compiler.
                        • I know quite some stuff about templates but are by no means a guru. So the above examples may contain errors or stuff that can be done in a better way.
                        • I designed the two templates a while ago for research purposes. I did not give them much testing in practice.
                        I'd be happy to hear if you find issues with my implementation or if it did help you.
                        You may also want to try to define your own recursive template. It is quite funny if you like coding :-)
                        Updated on 2014-03-25T00:49:36Z at 2014-03-25T00:49:36Z by iron-man
                        • SystemAdmin
                          SystemAdmin
                          7929 Posts
                          ACCEPTED ANSWER

                          Re: IloNumVarArray.setNames();

                          ‏2010-01-14T15:06:16Z  in response to SystemAdmin
                          Thank you so much for your help!!!

                          They are very valuable to me.

                          I will try if I have time.
                          • SystemAdmin
                            SystemAdmin
                            7929 Posts
                            ACCEPTED ANSWER

                            Re: IloNumVarArray.setNames();

                            ‏2010-01-18T07:46:36Z  in response to SystemAdmin
                            Another, not so complicated idea would be to define a multi-index class
                            template<unsigned int D, typename T = int>
                            struct MuliIndex {
                               enum { dimension = D };
                               T index[D];
                             
                               bool operator<(MultiIndex const& other) const {
                                  // Lexicographical comparison between this.index and other.index
                                  ...
                               }
                            };
                            

                            and then use std::map<MuliIndex<3>,double>.
                            Updated on 2014-03-25T00:41:42Z at 2014-03-25T00:41:42Z by iron-man
  • SystemAdmin
    SystemAdmin
    7929 Posts
    ACCEPTED ANSWER

    Re: IloNumVarArray.setNames();

    ‏2010-01-14T15:26:46Z  in response to SystemAdmin
    setNames does not work with cplex 11.2 on windows XP 32 bit or Vista 64 bit.
    For a better way to create multi-dim variable arrays, pls refer to dju358's reply which might also reduce the risk of being out of memory.