2

问题

给定一个列表L:[a,b,c,d,e,f] ,是否有随机打乱列表元素的内置方式?就像是:

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

我检查了列表的函数和变量的文档,以了解任何用于打乱列表中元素顺序的内置选项,但没有看到任何明显的东西。


语境

我正在尝试生成x最大总和为的术语列表s。现在,我通过创建一个列表来做到这一点,其中每个项都是介于 1 和最大值之间的随机数,以确保如果剩余项的最小值为 1,那么总和最多为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
);

但是,这会生成列表,其中较早的术语(较低的索引)具有较高值的​​概率较高;而我想要更均匀的值分布。

我能想到的最简单的解决方案就是简单地打乱vals列表的元素;但是,我同样对任何其他实现此预期结果的方法感兴趣(x总和最多为 的术语列表s)。

更广泛的背景是将数轴的区间划分为子区间的问题。我决定将区间的长度和分区的数量作为构建子区间的变量,从而达到上述目标。如果I = [a, b]是完整区间,那么对于任何cd这样c+d =< b-a我们就可以定义子区间[a, a+c][a+c, a+c+d][a+c+d, b]

4

0 回答 0