2016-08-05 21 views
1

マイモデルのTicketBuyerカラムには、購入したticket_buyer名とnumber_of_ticketsが含まれています。私は無作為に勝ちのチケットを選択したいと思います。私は、購入したnumber_of_ticketsに等しい行数にわたって複製されたticket_buyerの名前を持つ別のモデル(SelectTable)を作成し、それによって各レコードに等しい重みを与えることを好みます。私は単純なソートを実行し、新しいテーブルの最初のレコードを選択することができます。私は各ticket_buyerの行数が正しい表を自動作成するのに問題があります。もちろん、これを行うためのより雄弁な/効率的な方法があるかもしれません。アドバイスをいただければ幸いです。加重アイテムのランダム選択

答えて

1

速度が問題でない場合は、追加のデータ構造を作成せずに実行できます。

  • ランダム誰
  • で買っ最大number_of_ticketsは、彼らが第2の延伸を失敗した場合、チケットの買い手
  • がランダムに、勝者
  • になってきて、それらのnumber_of_tickets/max_number_of_ticketsのチャンスで、別の引き分けを実行してください選択して下さい別のチケット購入者を選択し、誰かが勝利するまでこのプロセスを繰り返す。

万人のチケットと誰もがエルを購入するような狂った流通がなければセールを買うと、これはあまり長くかかりません。

擬似コード:

max_tickets = max(table:number_of_tickets) 
while true do: 
    // select a random buyer 
    buyer = select random row from table 

    // assume random(n) returns an integer number from 0 to n - 1 inclusive: 
    if random(max_tickets) < buyer.number_of_tickets then 
      return buyer // we have a winner 
end 
+0

私はそれが好き!名前を付けましょう:[拒否サンプリング](https://en.wikipedia.org/wiki/Rejection_sampling)のようなものです。代替案(より複雑なもの)は、[wiki(part:有限離散分布)](https://en.wikipedia.org/wiki/Pseudo-random_number_sampling)に掲載されています。[alias-method]速度が重要な場合は、https://en.wikipedia.org/wiki/Alias_methodを参照してください。しかし、これは追加作業が必要になります。 – sascha

+0

ありがとうございます。私は前にこのアプローチを見ていないが、よく見える。どのようなサンプルコードでも大歓迎です。 – Tkendall

+0

私はこれをRailsに書いていることに言及しませんでした。 – Tkendall

関連する問題