一緒に接続された2つの範囲間の乱数出力

一緒に接続された2つの範囲間の乱数出力

この問題範囲の間で乱数を生成することについてです。これは大丈夫ですが、私の場合は適していません。

私の考えでは、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_id1 ~ 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拡張は必要ありません。

関連情報