python シミュレーション 基礎的な問題です。
解決済
回答 2
投稿
- 評価
- クリップ 0
- VIEW 1,261
学校の課題で衝突確率を計算し、グラフに表示するプログラムを作成しています。
解析計算プログラムとシミュレーションプログラム、グラフ作成プログラムを作成。
このうち、解析プログラムは衝突する確率を計算(これは完成できました)
シミュレーションプログラムは、プログラムの機能をM回実行、実行するごとに重複の有無を判定、最終的に「M回中何回重複したか」の回数を「M」で割れば、重複確率が求められる。(ここがわかりません)
この、シミュレーションプログラムの作成方法がわかりません。
どのように考えたらいいのでしょうか。
よろしくお願いします。
(解析プログラム)
import datetime
from collections import Counter
"""
birthday paradox
"""
def rand_date():
"""
ランダムな日付を返す
戻り値: (2010/1/1 + d)を計算し(月, 日)を返す
- base_date(基準日): 2010/1/1 + d
- d(進める日数): (0〜364)
"""
# 2010は日付を生成するための仮の年. うるう年でなければいつでもよい
base_date = datetime.datetime(2010, 1, 1)
d = random.randint(0, 365)
ret_date = base_date + datetime.timedelta(days=d)
return ret_date.month, ret_date.day
if __name__ == "__main__":
# 生成する誕生日の個数をセット
if len(sys.argv) != 2:
print("usage: rand.py [nOfSample]")
exit(0)
n = int(sys.argv[1])
# 誕生日をn個生成
birthday_list = [rand_date() for i in range(n)]
# 結果を検証
# 重複する誕生日を検索(重複なしの場合は空リスト)
non_unique_items = [k for k, v in Counter(birthday_list).items() if v > 1]
num = 1
for i in range(1,n):
num *= (365-i)/365
probability = (1-num)
# 結果を表示
print("# non_unique_items")
print(non_unique_items)
print("# probability(unique)")
print(1-num)
print("# all items")
print(birthday_list)
(プログラム)
#! /usr/ bin /env python
# −*− coding : utf−8 −*−
import sys
import random
import datetime
from collections import Counter
” ” ”
birthday paradox
” ” ”
def rand_date ( ) :
” ” ”
ランダムな日付を返す
戻り値: (2010/1/1 + d) を計算し( 月, 日) を返す
− base_date ( 基準日) : 2010/1/1 + d
− d( 進める日数) : (0~364)
” ” ”
# 2010は日付を生成するための仮の年. うるう年でなければいつでもよい
base_date = datetime . datetime(2010, 1 , 1)
d = random . randint (0 , 365)
ret_date = base_date + datetime . timedelta ( days=d)
return ret_date . month, ret_date . day
i f __name__ == ” __main__ ” :
# 生成する誕生日の個数をセット
i f len ( sys . argv ) != 2:
print ( ”usage : rand . py [nOfSample] ” )
exit (0)
n = i n t ( sys . argv [ 1 ] )
# 誕生日をn個生成
birthday_list = [ rand_date ( ) for i in range (n ) ]
# 結果を検証
# 重複する誕生日を検索( 重複なしの場合は空リスト)
non_unique_items = [ k for k , v in Counter ( birthday_list ) . iteritems ( ) i f v > 1]
# 結果を表示
print ( ”# non_unique_items ” )
print ( non_unique_items )
print ( ”# a l l items ” )
print ( birthday_list )
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
とりあえず、解析プログラムの方で、コマンドライン引数に相当するような情報を受け取り、printする内容に相当するような情報を返す関数を1個作りましょう。仮に関数名one_trial
としたとします。
で、コマンドライン引数を読み込み、one_trial
に与えて呼び出して、返り値を受け取って現状と同じ出力を実現するmain
関数も作り、
if __name__ == "__main__":
main()
で今までどおり走るようにモジュールを切り分ける。
こうしておくと、シミュレーションの方のプログラムではone_trial
をimportしてM回回して結果を集計すれば良いので、楽です。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
どこがわからないのか、わからないので、とりあえず今あるコードの続きから。
今重複を示すリストがあるわけですから、このリストの要素が0かそれ以外かでif文分岐させれば各試行において、重複があるかないかを知ることができます。
for文で回して、重複があったらカウンターを1ずつ増やしていけば、n回の試行に対して何回重複があったかがわかります。
具体的な書き方はいろいろあるので参考までに。
import random
def main(n=100, k=10, seed=0):
random.seed(seed)
def trial(k=k):
s = [random.randint(1, 366) for _ in range(k)]
s = set(s)
if len(s) < k:
return True
else:
return False
c = 0
for _ in range(n):
c += trial()
return c/n*100
res = []
for r in range(1000):
ans = main(seed=r)
res.append(ans)
import numpy as np
print(np.mean(res), np.std(res))
print((1 - np.prod([(366-i)/366 for i in range(1, 10)]))*100)
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.37%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる