Decision Optimization

Decision Optimization

Delivers prescriptive analytics capabilities and decision intelligence to improve decision-making.

 View Only
Expand all | Collapse all

Use of GetEnumerator (or other?) in dotnet API to keep a hand on extracted tuples

  • 1.  Use of GetEnumerator (or other?) in dotnet API to keep a hand on extracted tuples

    Posted Tue March 16, 2021 11:46 AM

    Hello dear community,

       I'm using F# (so my question could be understood and possibly easily answered by C# users), I'm looking for a way to extract the information on a list of elements of tuples sets, and use that information later. Ideally, I would like to end up with a sequence in F# to be able to do lazy evaluation (which translate on the C# side as a  IEnumerable<T>). 

       Fortunately, OPL CPLEX API provides a "GetEnumerator" on tuplesets. This method works well when I iterate on the tupleset and act immediately on the tuple (e.g. : extract an integer value or set a bound of a variable).

       Unfortunately, as soon as I extract the tuple object and record it in a data structure (list, sequence, dictionary,...), it seems it becomes messed up as soon as the "GetEnumerator" falls out of scope. The behavior seems as if the returned object gets invalidated, as if it is copied in a static structure, returned to be used, then immediately collected or reused and overwritten for the next element...

       When I look at the MS .NET documentation, it says the enumerator usually becomes invalidated as soon as you do such operations as adding or removing items of the collection (understandably), but I don't do such a thing, and I haven't find any specification on the element of the enumeration itself.

       So now my question :
    1) is this behavior of GetEnumerator normal and intended ? If so, I suggest enhancing the API documentation to avoid surprises of future developers.
    2) ...otherwise, I'm I doing something wrong ? Should I try to "pin" the underlaying CPLEX object ? Or is it garbage collected as soon as GetEnumerator falls out of scope ?
    3) ...or should I find another way (not using the GetEnumerator()) to end up with a clean IEnumerable<> ? Said otherwise, is there another method of another class I missed which would be better to record some specific tuples to be reused later ?

       And I know I could extract all information of the tuple, instantiate it on the F# side, but this would mean duplicating all of the model elements on the F# side and I would rather aim to use the lazy evaluation for performance.

       Thanks !



    ------------------------------
    Luc Charest
    ------------------------------

    #DecisionOptimization


  • 2.  RE: Use of GetEnumerator (or other?) in dotnet API to keep a hand on extracted tuples

    Posted Wed March 17, 2021 05:52 AM
    Hello Luc.

    For tupleset iterators, the tuple lifecycle is tied on the iterator, that is the tuple is reused at each iteration and deleted when the iterator is ended.
    We'll see to explain this in the doc.

    So I think you will have to collect the integer index you are interested in.

    Vincent.

    ------------------------------
    Vincent Beraudier
    ------------------------------



  • 3.  RE: Use of GetEnumerator (or other?) in dotnet API to keep a hand on extracted tuples

    Posted Tue March 23, 2021 10:44 AM
    Thank you Vincent for the answer ! :) 

    So if I get you right, the best approach (efficiently?) would be to save the index of the tuple and use the "ITupleSet.MakeTuple(idx)" method to get back the tuple ?

    Also, would you know what is the life span of this new "ITuple" object ? I don't see any "End()" method on this ITuple, does this mean I don't have to care about freeing its memory, and that it should be kept alive as long as the model object is alive ?

    Thanks !


    ------------------------------
    Luc Charest
    ------------------------------