-
Notifications
You must be signed in to change notification settings - Fork 0
528. Random Pick with Weight #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
37d0f39 to
68402a6
Compare
| * 発想 | ||
| * 重み付きの確率を行う方法。 | ||
| * `w_0`, `w_1`, `w_2`, ...をsumで割り算し`w_0`/sum, `w_1`/sum, `w_2`/sum, ...とした後に、累積和をとる。 | ||
| 0から1のランダムな値がどの重みに属するかを調べることで、重みを考慮したサンプリングできそう。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
確率だからよいかと思う一方で、浮動小数点は色々なことが起きるので、自然数で処理したほうが私は好みです。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 浮動小数点の懸念事項
- 整数で解く方法
を意識ができておりませんでした。ご指摘、ありがとうございます。
懸念項目の一例を調べました。
- 丸誤差
- 有効数字の桁が落ちる
- 情報が落ちる
- 演算の順序性が保たれない
参考:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
6643657 で整数で解く方法を追加しました。
| sum += weight_i | ||
| } | ||
| for (let i=0; i<w.length; i++) { | ||
| n const weight_i = w[i] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
謎の n。これを置き直してもあまりいいことないでしょう。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wという変数が重み( weight )を表すことは自明ということですね。
| ## その他の解法 | ||
|
|
||
| * 二分探索のターゲットを変更する。 | ||
| * 見つけたいターゲット: i-1番目の累積和 <= `random_value` < i番目の累積和となるiの値 (先ほどは、 i-1 < `random_value` <= iで等号の場所を変更した) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
等号はこっちのほうが自然でしょうね。Math.random は 0 は入って 1 は入らないので。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- random_valueが1を含む場合には、<=としてあげないと、1が出た際のiが見つからなくなる.
- random_valueが1を含まない場合には、 <=としても1がそもそも出ないとで等号が使われない。
と理解しました。
| * 二分探索において、ターゲットと引き継ぎ条件を考えることで、 | ||
| left,rightの設定や等号の有無について迷わなくなった。 | ||
|
|
||
| * 前のレビュー依頼から時間が空いてしまったので、もう一度習慣化する。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
そうですね。1週間休んでも終わるのが1週間遅れるだけですが、頻度が半分になると時間が倍になりますからね。特に問題ないので進みましょう。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
はい、自分ができるペースで、頻度を意識してコーディング練習会に臨もうと思います。
問題URL
https://leetcode.com/problems/random-pick-with-weight/
問題文
You are given a 0-indexed array of positive integers w where w[i] describes the weight of the ith index.
You need to implement the function pickIndex(), which randomly picks an index in the range [0, w.length - 1] (inclusive) and returns it. The probability of picking an index i is w[i] / sum(w).
For example, if w = [1, 3], the probability of picking index 0 is 1 / (1 + 3) = 0.25 (i.e., 25%), and the probability of picking index 1 is 3 / (1 + 3) = 0.75 (i.e., 75%).
Example 1:
Input
["Solution","pickIndex"]
[[[1]],[]]
Output
[null,0]
Explanation
Solution solution = new Solution([1]);
solution.pickIndex(); // return 0. The only option is to return 0 since there is only one element in w.
Example 2:
Input
["Solution","pickIndex","pickIndex","pickIndex","pickIndex","pickIndex"]
[[[1,3]],[],[],[],[],[]]
Output
[null,1,1,1,1,0]
Explanation
Solution solution = new Solution([1, 3]);
solution.pickIndex(); // return 1. It is returning the second element (index = 1) that has a probability of 3/4.
solution.pickIndex(); // return 1
solution.pickIndex(); // return 1
solution.pickIndex(); // return 1
solution.pickIndex(); // return 0. It is returning the first element (index = 0) that has a probability of 1/4.
Since this is a randomization problem, multiple answers are allowed.
All of the following outputs can be considered correct:
[null,1,1,1,1,0]
[null,1,1,1,1,1]
[null,1,1,1,0,0]
[null,1,1,1,0,1]
[null,1,0,1,0,0]
......
and so on.
Constraints:
1 <= w.length <= 104
1 <= w[i] <= 105
pickIndex will be called at most 104 times.