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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

3223閲覧

おみくじに関するプログラム

hirotaka_i

総合スコア11

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/03/30 18:26

・問題設定
大吉、中吉、小吉の三つの種類のおみくじが箱に入ってます。箱の中に入っている大吉の割合は10%, 中吉は30%, 小吉は60%です。この確率をみたすようなおみくじのプログラムを作りたいです。

しかし、「x%の確率で何々が出る」をコードでどう書けばいいか分からず、考えた結果以下のようなプログラムを書きました。このプログラムの方法ではなく他の方法はあるのでしょうか。ご回答お願い致します。

python3

1import random 2omikuji = random.randint(1, 10) 3 4if omikuji == 1: 5 print("大吉") 6elif omikuji >= 2 && omikuji <= 4: 7 print("中吉") 8else: 9 print("小吉") 10 11

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

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

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

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

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

guest

回答2

0

おみくじを配列で表現してみました。
おみくじをひくのは、配列の先頭からあたいをとっていくことにし、配列のさいごまでいったら
また、配列をつくりなおせばよいです。

あるいは値の分布割合は同じだが 十分に大きいサイズの配列をつくる。
サイズ10 の配列を 10 回繰返して作るのと、100のサイズで配列を 1 回作るのとでは、
おみくじとしての挙動はことなるもになってしまいますから。

python

1import random 2 3ary = ["大吉"] * 1 + ["中吉"] * 3 + ["小吉"] * 6 4random.shuffle(ary) 5 6print(ary)

投稿2018/03/30 21:25

編集2018/03/31 07:40
katoy

総合スコア22324

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

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

hirotaka_i

2018/03/31 01:43

配列でもできることがわかりました!ありがとうございます
退会済みユーザー

退会済みユーザー

2018/03/31 01:55

リアルの模倣ですね。 要件的にどっちがやりたかったのか気になるところです。
katoy

2018/03/31 03:28

福引をプログラムでつくることを想像しました。 rundum で選ぶだけだと、いつまでたっても 一等がでなかったり何回も一等がでてしまったりします。 配列で福引を模倣した場合は、くじを全部 引き終わったときには確実に一等は 1 回だけ出ます。
hayataka2049

2018/03/31 04:17

独立試行とみなして良いとか、あるいは一度に一回しか引かない(たとえば毎日1回引けるおみくじアプリを作るなど)と割り切ってやればrandomで行けますが、同時に複数回回すのであれば条件付き確率的に正しい結果になるのはこっちですね。
guest

0

ベストアンサー

基本的な発想はそれで良いと思います。
random.random()で0~1の一様乱数が取得できるので、これを使うとちょっと直感的に書けます。

python

1>>> def omikuji(): 2... value = random.random() 3... if value < 0.1: 4... return "大吉" 5... elif value < 0.4: 6... return "中吉" 7... else: 8... return "小吉" 9>>> result = [omikuji() for i in range(1000)] # 以下正しく動いていることの確認 10>>> result.count("大吉") 1196 12>>> result.count("中吉") 13303 14>>> result.count("小吉") 15601

追記

回答書いてからぐぐってたら、numpy 1.7.0以降を使えば次のように書けるということを知りました。

python

1import numpy as np 2def omikuji(): 3 results = ["大吉", "中吉", "小吉"] 4 return results[np.random.choice(3, p=[0.1, 0.3, 0.6])]

もうちょっと頑張ってカスタマイズ性を考慮した結果、こうなりました。

python

1>>> def proba_select(ret_proba_dict): 2... index = sorted(ret_proba_dict.keys()) 3... probas = np.array([ret_proba_dict[i] for i in index]) 4... probas = probas/(probas.sum()) 5... return index[np.random.choice(len(index), p=probas)] 6... 7>>> omikuji = lambda : proba_select({"大吉":0.1, "中吉":0.3, "小吉":0.6})

まあ、ここまでやる必要はないかもしれませんが・・・。

参考(numpy公式)

更に追記

ドキュメントをちゃんと読んだら、第一引数には1-D array likeも渡せました。
なので、もっと簡単にこう書けます。

python

1np.random.choice(["大吉", "中吉", "小吉"], p=[0.1, 0.3, 0.6])

難しいことをする必要はありませんでした・・・。

投稿2018/03/30 18:40

編集2018/03/31 08:31
hayataka2049

総合スコア30933

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

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

hirotaka_i

2018/03/31 01:48

回答ありがとうございます。numpyを使って書く方法も知りたかったので感謝です!ありがとうございます
hirotaka_i

2018/03/31 02:23

すみません、一つ確認させていただきたいことがあるのですが return results[np.random.choice(3, p=[0.1, 0.3, 0.6])] このコードの'3'はresultsの要素の個数という意味で合っていますでしょうか。
hayataka2049

2018/03/31 08:31

もっと簡単な書き方を見つけたので追記しておきました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問