sampling using iterators

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Leon

    sampling using iterators

    using
    multimap<int,in t>::iterator itlow = pq.lower_bound (x);
    multimap<int,in t>::iterator itup = pq.upper_bound (y);

    I obtain lower and upper bound from the multimap, and having these two
    iterators I would like to sample one element with uniform distribution.
    It a way do to this using iterators? I can of course draw an integer and
    loop over the sequence until I meet the drawn value, but it is not a
    very nice solution. Can sample directly using iterators?

    thanks
  • Victor Bazarov

    #2
    Re: sampling using iterators

    Leon wrote:
    using
    multimap<int,in t>::iterator itlow = pq.lower_bound (x);
    multimap<int,in t>::iterator itup = pq.upper_bound (y);
    >
    I obtain lower and upper bound from the multimap, and having these two
    iterators I would like to sample one element with uniform distribution.
    It a way do to this using iterators? I can of course draw an integer and
    loop over the sequence until I meet the drawn value, but it is not a
    very nice solution. Can sample directly using iterators?
    You can always use 'distance' or 'advance' to hide the loop. Since map
    (or multimap) iterators aren't direct-access variety, you'll have to use
    some kind of loop anyway, explicit or implicit.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask

    Comment

    • Juha Nieminen

      #3
      Re: sampling using iterators

      Leon wrote:
      using
      multimap<int,in t>::iterator itlow = pq.lower_bound (x);
      multimap<int,in t>::iterator itup = pq.upper_bound (y);
      >
      I obtain lower and upper bound from the multimap, and having these two
      iterators I would like to sample one element with uniform distribution.
      It a way do to this using iterators? I can of course draw an integer and
      loop over the sequence until I meet the drawn value, but it is not a
      very nice solution. Can sample directly using iterators?
      I don't really understand what do you mean by "sample". If you mean
      that you want (constant-time) random access to the range above, that's
      just not possible with multimap iterators, as they are not random access
      iterators.

      If you *really* need that (eg. for efficiency reasons) then one
      solution might be to instead of using a multimap, use a regular map with
      a vector (or deque) as element, so that each element with the same key
      is put into the vector correspondent to that key. Then you can
      random-access the vector when you need to.

      (Of course the downside of this is that inserting and removing
      elements is not, strictly speaking, O(lg n) anymore... But you can't
      have everything at once.)

      Comment

      • Leon

        #4
        Re: sampling using iterators

        Juha Nieminen wrote:
        Leon wrote:
        >using
        >multimap<int,i nt>::iterator itlow = pq.lower_bound (x);
        >multimap<int,i nt>::iterator itup = pq.upper_bound (y);
        >>
        >I obtain lower and upper bound from the multimap, and having these two
        >iterators I would like to sample one element with uniform distribution.
        >It a way do to this using iterators? I can of course draw an integer and
        >loop over the sequence until I meet the drawn value, but it is not a
        >very nice solution. Can sample directly using iterators?
        >
        I don't really understand what do you mean by "sample". If you mean
        that you want (constant-time) random access to the range above, that's
        just not possible with multimap iterators, as they are not random access
        iterators.
        >
        If you *really* need that (eg. for efficiency reasons) then one
        solution might be to instead of using a multimap, use a regular map with
        a vector (or deque) as element, so that each element with the same key
        is put into the vector correspondent to that key. Then you can
        random-access the vector when you need to.
        >
        (Of course the downside of this is that inserting and removing
        elements is not, strictly speaking, O(lg n) anymore... But you can't
        have everything at once.)
        Yes, since the iterator is not random for multimap I have to loop
        anyway. Thanks!

        Comment

        • Andrew Koenig

          #5
          Re: sampling using iterators

          "Leon" <lew71@poczta.o net.plwrote in message
          news:geaa1v$8fm $2@news.onet.pl ...
          using
          multimap<int,in t>::iterator itlow = pq.lower_bound (x);
          multimap<int,in t>::iterator itup = pq.upper_bound (y);
          >
          I obtain lower and upper bound from the multimap, and having these two
          iterators I would like to sample one element with uniform distribution. It
          a way do to this using iterators?
          Assume you have a function nrand that takes an integer n and returns a
          uniform random integer k such that 0 <= k < n.

          Then I think this code will do what you want:

          assert (itlow != itup); // necessary for a result to be possible

          multimap<int,in t>::iterator result;
          int n = 0;
          while (itlow != itup) {
          if (nrand(++n) == 0)
          result = itlow;
          ++itlow;
          }

          Note that the first call to nrand will be nrand(++n) with n initially 0,
          which is effectively nrand(1). By definition, nrand(1) is always 0, so
          result will always be initialized the first time through the loop.
          Moreover, the loop will always execute at least once because of the assert.
          Therefore, there is no risk that result might not be initialized.


          Comment

          • James Kanze

            #6
            Re: sampling using iterators

            On Oct 30, 12:13 am, Juha Nieminen <nos...@thanks. invalidwrote:
            Leon wrote:
            using
            multimap<int,in t>::iterator itlow = pq.lower_bound (x);
            multimap<int,in t>::iterator itup = pq.upper_bound (y);
            I obtain lower and upper bound from the multimap, and having
            these two iterators I would like to sample one element with
            uniform distribution. It a way do to this using iterators?
            I can of course draw an integer and loop over the sequence
            until I meet the drawn value, but it is not a very nice
            solution. Can sample directly using iterators?
            I don't really understand what do you mean by "sample". If you
            mean that you want (constant-time) random access to the range
            above, that's just not possible with multimap iterators, as
            they are not random access iterators.
            If you *really* need that (eg. for efficiency reasons) then
            one solution might be to instead of using a multimap, use a
            regular map with a vector (or deque) as element, so that each
            element with the same key is put into the vector correspondent
            to that key. Then you can random-access the vector when you
            need to.
            He seems to be looking for a range (lower_bound and upper_bound
            are called with different arguments), not just a single key.
            But using a sorted vector, with the library functions
            lower_bound and upper_bound, would definitely be a possible
            solution. As you say, insertion would be more expensive, but a
            lot depends on the other use he makes of the structure, and how
            expensive copying or swapping the elements might be. (Using
            lower_bound on a sorted vector is actually significantly faster
            than map.lower_bound , at least with the implementations I've
            tested.)

            --
            James Kanze (GABI Software) email:james.kan ze@gmail.com
            Conseils en informatique orientée objet/
            Beratung in objektorientier ter Datenverarbeitu ng
            9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

            Comment

            Working...