質問
リストが与えられた場合、リスト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]
が完全な間隔である場合、任意のに対してc
、d
サブc+d =< b-a
間隔[a, a+c]
、[a+c, a+c+d]
、[a+c+d, b]