Algorithm Help Needed

2005-09-13 Thread Bob Showalter
Guys,

I need help with an algorithm. I'm writing a program that sends a repeated
pattern of requests to a service. Each request has a weight that controls
the relative frequency with which I need to send that particular request. So
given:

   foo = 1
   bar = 3

I would send four requests, one of which is a 'foo', and the other three are
'bar'. So my requests would look like:

   foo, bar, bar, bar, foo, bar, bar, bar, ...

If I have a case like:

   foo = 1
   bar = 1
   qux = 6

I can easily send one foo, followed by a bar, followed by 6 qux:

   foo
   bar
   qux qux qux qux qux qux

However, what I need to do is to distribute the requests so that the
intervals between instances of a given request are distributed as equally as
possible. For example:

   foo 
   qux qux qux
   bar 
   qux qux qux

Now I have only intervals of 0 or 1 between successive qux, instead of an
interval of 2 as in the previous case.

As an extreme example, if I had a dozen requests with a weight of 1 and a
final request with a weight of 12, I would starve the highly-weighted
request until the first 12 had been sent.

How can I generalize this for any given set of requests and weights? Is
anyone aware of any general literature on this kind of problem? (Sounds like
a scheduling algorithm maybe?)

Thanks,
Bob

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Algorithm Help Needed

2005-09-13 Thread Jeff 'japhy' Pinyan

On Sep 13, Bob Showalter said:


I need help with an algorithm. I'm writing a program that sends a repeated
pattern of requests to a service. Each request has a weight that controls
the relative frequency with which I need to send that particular request.

  foo = 1
  bar = 1
  qux = 6


  foo
  qux qux qux
  bar
  qux qux qux

Now I have only intervals of 0 or 1 between successive qux, instead of an
interval of 2 as in the previous case.

As an extreme example, if I had a dozen requests with a weight of 1 and a
final request with a weight of 12, I would starve the highly-weighted
request until the first 12 had been sent.


The extreme cases are the easy ones, though.  What I'd like to see are 
cases like:


  foo = 1
  bar = 2
  qux = 3
  baz = 4
  zip = 5

Once I know what the algorithm's outcome should be for something like 
that, I think I can develop it.


--
Jeff japhy Pinyan%  How can we ever be the sold short or
RPI Acacia Brother #734%  the cheated, we who for every service
http://www.perlmonks.org/  %  have long ago been overpaid?
http://princeton.pm.org/   %-- Meister Eckhart

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Algorithm Help Needed

2005-09-13 Thread Eric Walker
On Tuesday 13 September 2005 09:55 am, Jeff 'japhy' Pinyan wrote:
 On Sep 13, Bob Showalter said:
  I need help with an algorithm. I'm writing a program that sends a
  repeated pattern of requests to a service. Each request has a weight
  that controls the relative frequency with which I need to send that
  particular request.
 
foo = 1
bar = 1
qux = 6
 
 
foo
qux qux qux
bar
qux qux qux
 
  Now I have only intervals of 0 or 1 between successive qux, instead of
  an interval of 2 as in the previous case.
 
  As an extreme example, if I had a dozen requests with a weight of 1 and a
  final request with a weight of 12, I would starve the highly-weighted
  request until the first 12 had been sent.

 The extreme cases are the easy ones, though.  What I'd like to see are
 cases like:

foo = 1
bar = 2
qux = 3
baz = 4
zip = 5

 Once I know what the algorithm's outcome should be for something like
 that, I think I can develop it.

 --
 Jeff japhy Pinyan%  How can we ever be the sold short or
 RPI Acacia Brother #734%  the cheated, we who for every service
 http://www.perlmonks.org/  %  have long ago been overpaid?
 http://princeton.pm.org/   %-- Meister Eckhart

yes, how would you want to split zip which is odd..  Also, with your extreme 
case you said you would do all the singles first and do the 12 weighted one 
last. that goes against your primary objective which is to distribute the 
service request evenly . In that case I would expect the one with weight of 
12 to be distributed among the single weighted request..
if foon=1 and bar = 12 then
foon
bar
foon
bar
etc... 



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Algorithm Help Needed

2005-09-13 Thread Jay Savage
On 9/13/05, Eric Walker [EMAIL PROTECTED] wrote:
 On Tuesday 13 September 2005 09:55 am, Jeff 'japhy' Pinyan wrote:
  On Sep 13, Bob Showalter said:
   I need help with an algorithm. I'm writing a program that sends a
   repeated pattern of requests to a service. Each request has a weight
   that controls the relative frequency with which I need to send that
   particular request.
  
 foo = 1
 bar = 1
 qux = 6
  
  
 foo
 qux qux qux
 bar
 qux qux qux
  
   Now I have only intervals of 0 or 1 between successive qux, instead of
   an interval of 2 as in the previous case.
  
   As an extreme example, if I had a dozen requests with a weight of 1 and a
   final request with a weight of 12, I would starve the highly-weighted
   request until the first 12 had been sent.
 
  The extreme cases are the easy ones, though.  What I'd like to see are
  cases like:
 
 foo = 1
 bar = 2
 qux = 3
 baz = 4
 zip = 5
 
  Once I know what the algorithm's outcome should be for something like
  that, I think I can develop it.
 
  --
  Jeff japhy Pinyan%  How can we ever be the sold short or
  RPI Acacia Brother #734%  the cheated, we who for every service
  http://www.perlmonks.org/  %  have long ago been overpaid?
  http://princeton.pm.org/   %-- Meister Eckhart
 
 yes, how would you want to split zip which is odd..  Also, with your extreme
 case you said you would do all the singles first and do the 12 weighted one
 last. that goes against your primary objective which is to distribute the
 service request evenly . In that case I would expect the one with weight of
 12 to be distributed among the single weighted request..
 if foon=1 and bar = 12 then
 foon
 bar
 foon
 bar
 etc...

This sort of thing is unfortunately application specific, and depends
a lot on what your goal is. If you do a web search for wieghted round
robin or load balancing, you'll get a lot of food for thought. If you
really need to do careful scheduling--say for load balancing--you'll
need to take into account not just requests but open connections, and
the (unfortunately C, I think) code in the wikipedia weighted round
robin entry is reasonable.

On the other hand, if all you just need to ensure an *average*
response time over a significant number of iterations, and your goal
is statistical distribution not real-world load managment, randomizing
will serve you just as well and be much easier to implement:

#!/usr/bin/perl

use warnings;
use strict;
use List::Util qw(shuffle);

my %weights = ( 'foo' = 12,
'bar' = 7,
'baz' = 2,
'quux' = 6,
'zip' = 1);

my @a;

while (1) {
while (my($k, $v) = each %weights) {
push(@a, $k) for 1..$v;
}

foreach (shuffle(@a)) {
# do something
}
}

HTH,

-- jay
--
This email and attachment(s): [  ] blogable; [ x ] ask first; [  ]
private and confidential

daggerquill [at] gmail [dot] com
http://www.tuaw.com  http://www.dpguru.com  http://www.engatiki.org

values of β will give rise to dom!


RE: Algorithm Help Needed

2005-09-13 Thread Bob Showalter
Jeff 'japhy' Pinyan wrote:
 The extreme cases are the easy ones, though.  What I'd like to see are
 cases like:
 
foo = 1
bar = 2
qux = 3
baz = 4
zip = 5
 
 Once I know what the algorithm's outcome should be for something like
 that, I think I can develop it.

Here's what I've come up with so far, which is extremely simple and seems to
work reasonably well:

1. Compute total weight as sum of individual weights
2. For each item in the list compute an interval as (total weight) /
(individual weight)
3. Write an entry for weight times, adding interval each time

So, for the example above, total weight is 15.

Start with foo: interval = 15 / 1 = 15. We need 1 foo, so:

   foo 15

bar: interval = 15 / 2 = 7.5. We need 2 bar's, so:

   bar 7.5
   bar 15

qux: interval = 15 / 3 = 5. Need 3 qux, so:

   qux 5
   qux 10
   qux 15

Final list is:

   foo 15
   bar 7.5
   bar 15
   qux 5
   qux 10
   qux 15
   baz 3.75
   baz 7.5
   baz 11.25
   baz 15
   zip 3
   zip 6
   zip 9
   zip 12
   zip 15

Now sort the list by column 2, then by column 1:

   zip 3
   baz 3.75
   qux 5
   zip 6
   bar 7.5
   baz 7.5
   zip 9
   qux 10
   baz 11.25
   zip 12
   bar 15
   baz 15
   foo 15
   qux 15
   zip 15

Column 1 becomes the round-robin sequence, with the right number of each
request, and farily evenly distributed.

The sequence starts and ends with a zip, so I have between 0 and 4 non-zip
entries between pairs of zip's. 6 of every 15 requests should be a zip, so
there should be an average of 1.5 non-zip's between zip's. Maybe I should
could tweak my algorithm to better smooth the distribution of zip's.

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Algorithm Help Needed

2005-09-13 Thread John W. Krahn
Jay Savage wrote:
 
 This sort of thing is unfortunately application specific, and depends
 a lot on what your goal is. If you do a web search for wieghted round
 robin or load balancing, you'll get a lot of food for thought. If you
 really need to do careful scheduling--say for load balancing--you'll
 need to take into account not just requests but open connections, and
 the (unfortunately C, I think) code in the wikipedia weighted round
 robin entry is reasonable.
 
 On the other hand, if all you just need to ensure an *average*
 response time over a significant number of iterations, and your goal
 is statistical distribution not real-world load managment, randomizing
 will serve you just as well and be much easier to implement:
 
 #!/usr/bin/perl
 
 use warnings;
 use strict;
 use List::Util qw(shuffle);
 
 my %weights = ( 'foo' = 12,
 'bar' = 7,
 'baz' = 2,
 'quux' = 6,
 'zip' = 1);
 
 my @a;
 
 while (1) {
 while (my($k, $v) = each %weights) {
 push(@a, $k) for 1..$v;

Or without the for modifier:

  push @a, ( $k ) x $v;


 }
 
 foreach (shuffle(@a)) {
 # do something
 }
 }


John
-- 
use Perl;
program
fulfillment

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response