
この問題範囲の間で乱数を生成することについてです。これは大丈夫ですが、私の場合は適していません。
私の考えでは、SQL用語で説明します。なぜなら私の考えでは、コードの結果としてSQLスクリプトを書くことbash
です。bash
2つのMySQLテーブルがあります。一つは人で、もう一つは場所です。各レコードには、1〜139(場所)と1〜1519(人)の範囲の一意の整数IDがあります。これは外部キーを介して互いに関連しています。つまり、1つの場所には多くの人がいるかもしれませんが、1人には1つの場所しかありません。
# 1-139 # 1-1519
place1 → person1
→ person2
→ person3
... and so on
今私が持っているデータは一箇所にあります。みんな人々は他の場所とは異なる方法でつながっています。
場所が139個、人が1519人だから1つの場所があり、人が1519人です。
私の目標は、ランダムに人々を場所に割り当て、各場所に少なくとも1人ずつ配置することです。
これまで私のコードは次のようになります。
$ c=1519
$ while [[ $c -ne 0 ]]; do
x=$((shuf -i 1-139 -n 1))
[[ $x -gt 139 ]] && continue
echo $x
(( c-- ))
done
このコードは1から139までの1519個の乱数を生成するため、各人を任意の場所にリンクできるようになりました。
私の質問は次のとおりです
- これを達成するためのより効率的な方法はありますか?
- どの場所に少なくとも1人がいるかをどのように制御できますか?
私はこれを行うことを好むbash
が、それを含まない他の解決策にも開いています。
答え1
一般的なツール(少なくともLinuxディストリビューションでは)を使用してこれを行う場合は、最も効率的な方法はおそらく次のように質問することですshuf
。
shuf -i 1-139 -n 1519 -r
これにより、1から139の間でランダムに選択された1519個の数字が生成されます。
すべての場所に人がいることを確認するには、まず139個の数字を繰り返すことなく混ぜます。
shuf -i 1-139
shuf -i 1-139 -n 1380 -r
「最初の139」効果を減らすには(最初の139人がすべて別の場所にいるように)、デッキをもう一度混ぜます。
(shuf -i 1-139; shuf -i 1-139 -n 1380 -r) | shuf
答え2
テーブルに people が格納されperson
、各人がplace_id
1 ~ 139 の整数を持っているとします。 SQLを使用してperson
テーブルを直接更新します。
UPDATE person SET place_id = FLOOR(RAND()*139 + 1);
これにより、テーブル内のすべてのエントリが更新され、place_id
キーがランダムに割り当てられます。しかし、完全にテストされていません。
更新後、次を使用して各場所が表示されているかどうかをテストできます。
SELECT COUNT(DISTINCT place_id) = 139 FROM person;
1
すべての場所が表示されている場合はこの値が返され、そうでない場合は返されます0
。
答え3
私たちがこの値を望むならできるだけ均等に伸ばして(1519が139の10倍の正確な倍数でないことを考慮すると)、空白を避けるのではなく、十分に大きな反復シーケンス1、...、139、1、...、139、1、...、そして最初の1519のメンバーを混ぜます。
while seq 139; do :; done | head -n 1519 | shuf
人を場所にマッピングする必要がある場合は、単に出力行に番号を付けることができます。
while seq 139; do :; done | head -n 1519 | shuf | nl
これはすべて標準シェルなので、Bash拡張は必要ありません。