質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

2回答

10640閲覧

A、50%、B、35%、C、15%の確率で選択するロジックの書き方

GiveAHand

総合スコア286

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

1クリップ

投稿2016/09/17 05:31

Visual Studio 2015でプログラムを作成しています。

その中で、今、どうプログラムしていいのか悩んでいる事がありまして、質問させて頂きます。

あるデバイス、A、B、Cの3つがあります。

ボタンを押すたびに、A、B、Cのうちいずれかが選択されるのですが、この選択される確率を、

A 50%
B 35%
C 15%

になるようにしたいのです。

また、デバイスが4つ、5つと増えた場合や、A、B,C、それぞれが選択される確率も変更できるようようにしたいのですが、このようなプログラムはどのように組んだらいいものなのでしょうか?

例えば、A,Bが50%の確率で選択されるようにするなら、ランダム関数を使って、0ならA、1ならBとかにしたらいいかなと思うのですが、また、A、B、Cが各33%ずつの場合でも、ランダム関数で0、1、2の3つから選ぶようにすればいいと思うのですが。。。

あと、同じように、ランダム関数を0~99にして、0~49をA、50~84をB、85~99をCとしても欲しい結果になるかと思うのですが、そうすると、デバイスの数やそれぞれの確率をパラメータで簡単に書き換えられるロジックではないので、どうしたものかという感じです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

あと、同じように、ランダム関数を0~99にして、0~49をA、50~84をB、85~99をCとしても欲しい結果になるかと思うのですが、そうすると、デバイスの数やそれぞれの確率をパラメータで簡単に書き換えられるロジックではないので、どうしたものかという感じです。

質問を読みながら、自分も最初に浮かんだ方法はこれでした。
そして、これをロジックで実現するのはそんなに難しくないと思いますよ。
自分はVSの環境がないのでコードは書けませんが、イメージ的にはこんな感じかと

もらうパラメータは、[50, 35, 15]のような配列だとします。

ランダム関数の値がXだったとき、
for文で配列を一つずつループします。
最初は、Xと50を比べます。Xが50未満ならAです。
次は、Xと50と35の合計を比べます。Xが85未満ならBです。
最後に、Xと50と35と15の合計を比べます。Xが100未満ならCです。
ループするたびに、前回までの値を合算した値とXを比較する感じです。

PHPなら以下のような感じなんですが...

php

1$x = ランダム(); 2$lists = ['A' => 50, 'B' => 35, 'C' => 15]; //設定値 3$sum = 0; 4$ans = null; 5foreach($lists as $key => $percent) { 6 $sum = $sum + $percent; // 毎回パーセントを足す 7 if($sum < $x) { // ランダム値と比較 8 $ans = $key; // ここに最終的なABCを入れる 9 berak; // 範囲内ならループを中断 10 } 11}

投稿2016/09/17 06:33

編集2016/09/17 06:34
popobot

総合スコア6586

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

GiveAHand

2016/09/17 08:38

ichi様 あぁ、なるほど! このロジックなら、合計が100になる数にすれば、デバイスが増えても、割合が変わっても、プログラムを書き換えずにいけそうです! ありがとうございました!
popobot

2016/09/17 09:04

ランダム関数の上限値を、配列のすべての和にすれば、100以外でも大丈夫だと思います。 [50, 30, 20, 10]だったら0から110の数をランダム関数で出力して、同じロジックを通すみたいに
guest

0

こういうのを「重み付け乱択」とか「重み付け抽出」とか言います。

その中で一番単純なのが、

0~49をA、50~84をB、85~99をCとしても

のように各要素の重みから「累積重み」を算出して、
生成した乱数がどこに入るか線形探索する手法です。
普通は重みは合計が1になるように再計算して
[0,1)の範囲で乱数を生成します。

投稿2016/09/17 07:44

ozwk

総合スコア13521

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

GiveAHand

2016/09/17 08:40

ozwk様 なるほど。 そういう名称で確立されている訳ですね。 ちょっと調べてみます。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問