Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re^2: Tracking minimum of values in an array over time

by liverpole (Monsignor)
on Oct 05, 2011 at 19:36 UTC ( [id://929865]=note: print w/replies, xml ) Need Help??


in reply to Re: Tracking minimum of values in an array over time
in thread Tracking minimum of values in an array over time

What ++suaveant said.

I wrote the program below to illustrate how you might do this. Note that you increment your "check" variable (in my program it's called $nfloor) only when an element becomes exactly the "floor" value. You can change the value of $b_slow to zero to make it call the subroutine fast() instead of slow(), and play with the values of $array_size and $floor to see how they affect the overall program speed. ($b_debug, if set, prints out the array each time; you probably only want to do this if $array_size and $floor are both quite small!):

#!/usr/bin/perl -w # Libraries use strict; use warnings; use 5.010; # User-defined my $b_slow = 1; my $array_size = 3000; my $floor = 50; my @array = ( 0 ) x $array_size; my $b_debug = 0; # Main program my $start = time(); while (1) { # Pick a random index, and increment the corrsponding value my $idx = int(rand(@array)); # Check all values to see if they've reached $floor my $b_reached = $b_slow? slow(\@array, $idx): fast(\@array, $idx); $b_debug and print "@array\n"; $b_reached and last; } my $nsecs = time() - $start; print "Reached floor '$floor' in $nsecs second(s)\n"; # Subroutines sub slow { my ($a_array, $idx) = @_; ++$array[$idx]; for (my $i = 0; $i < @$a_array; $i++) { my $val = $a_array->[$i]; ($val < $floor) and return 0; } return 1; } sub fast { my ($a_array, $idx) = @_; state $nfloor = 0; my $val = ++$a_array->[$idx]; if ($floor == $val) { ++$nfloor; } return ($nfloor < $array_size)? 0: 1; }

s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

Replies are listed 'Best First'.
Re^3: Tracking minimum of values in an array over time
by tj_thompson (Monk) on Oct 05, 2011 at 20:09 UTC

    Now that's a fantastic idea. Instead of trying to track the minimum of the set, track how many in the set have passed my floor value.

    My increment value will usually be more than one, so I'll have to verify that the increment did result in crossing the floor, but that's easy enough.

    Great idea from both of you, many thanks!

Re^3: Tracking minimum of values in an array over time
by Limbic~Region (Chancellor) on Oct 06, 2011 at 18:27 UTC
    liverpole,
    I haven't read your code but in thinking about the problem, you should never need to scan the array. The following is completely untested but it explains why I believe it is unnecessary.
    my @array = ((0) x 100); my $inc_array = gen_min_tracker(0, 100, \@array); my $floor = 27; my $new_min = inc_array(42, 7); # increment the 43rd element by 7 if ($new_min >= $floor) { print "The floor has been reached\n"; } sub gen_min_tracker { my ($curr_min, $curr_cnt, $aref) = @_; my ($next_min, $next_cnt); return sub { my ($idx, $inc) = @_; my $val = $aref->[$idx]; my $add = $val + $inc; if ($val == $curr_min) { $curr_cnt--; if (! defined $next_min || $add <= $next_min) { $next_min = $add; $next_cnt++; } if (! $curr_cnt) { ($curr_val, $curr_cnt, $next_val, $next_cnt) = ($next_ +val, $next_cnt, undef, undef); } } $aref->[$idx] += $inc; # let's not forget to actually increme +nt return $curr_min; }; }
    Update: Due to some unknown copy/paste error, the code above has been altered slightly from its original form to hopefully be correct despite still not being tested.

    Warning: In the CB, ambrus points out that this approach is flawed. It is not safe to reset $next_val and $next_cnt to undef. The assumption was that anytime one of the $curr_min values was incremented, it would be incremented to the $next_min and that no other value in the array could possibly be smaller. The solution is simple - put in the O(N) low water mark algorithm keeping track of the min value and count.

    Consideration: While you can't keep track of the minimum value without periodically scanning, you can still achieve the OP's goal as suaveant points out.

    Cheers - L~R

      The array scan was in there to allow comparison of "slow" vs "fast" I believe.

                      - Ant
                      - Some of my best work - (1 2 3)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://929865]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (3)
As of 2024-03-29 06:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found