2

Question

Given a list L:[a,b,c,d,e,f] is there a built in way of randomly shuffling the elements of the list? Something like:

M:random_order(L);
    > [ b, c, d, a, e, f]

I checked the documentation for Functions and Variables for Lists for any built in option for shuffling the order of elements in a list, but didn't see anything obvious.


Context

I'm trying to generate lists of x terms whose maximal sum is s. Right now, I'm doing this by creating a list where each term is a random number between 1 and the max value that ensures that, if the remaining terms have a minimal value of 1, then the sum will be, at most, s:

/* `x` is the total number of terms; `s` is the max sum */
gen_val(x, s):=block([x:x, s:s, vals:makelist(nul,i,x) ], 
  
   /* 
      the first value is a random integer in [1, (s-x)], if 
      vals[1] = (s-x), then all remaining terms have to be equal to 1 
   */
   vals[1]: 1 + random(s-x),
   
  /* 
     subsequent terms are assigned in the same way, subtracting the sum of 
     previously assigned values, as well as reserving at least 1 unit for 
     each remaining term 
  */
  for i:2 thru x
  do vals[i]:1 + random(s-sum(vals[k],k,1,i-1)-(x-i+1)),
  
  /* return the list */
  vals
);

However, this generates lists where earlier terms (i.e. lower index) have a higher probability of having higher values; whereas I'd like a more even distribution of the values.

The simplest solution I could think of was simply shuffling the elements of the vals list; however, I'd be equally interested in any other method that achieves this desired result (i.e. a list of x terms whose sum is, at most, s).

The even broader context is the problem of dividing an interval of the number line into sub-intervals. I decided to take the length of the interval and the number of partitions as my variables for building the sub-intervals, hence the goal, stated above. If I = [a, b] is the full interval, then for any c, d such that c+d =< b-a we can define the subintervals [a, a+c], [a+c, a+c+d], [a+c+d, b]

Rax Adaam
  • 790
  • 3
  • 11
  • 1
    The function to put items in a random order is `random_permutation`. About constructing partitions of intervals, how about `unique (makelist (a + 1 + random (b - 1 - a), n - 1))` where `n` is the number of subintervals? When `b - a` is an integer, then the random numbers are integers as well; otherwise, `b - a` must be a float, and the random numbers are floats. I guess you might need to adjust the +/- 1 business depending on exactly how you want the results to be. – Robert Dodier Mar 28 '21 at 15:16

0 Answers0