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

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

ただいまの
回答率

90.34%

  • Python

    9159questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Python 3.x

    7372questions

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

python シミュレーション 基礎的な問題です。

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 189

suisosui

score 2

学校の課題で衝突確率を計算し、グラフに表示するプログラムを作成しています。
解析計算プログラムとシミュレーションプログラム、グラフ作成プログラムを作成。
このうち、解析プログラムは衝突する確率を計算(これは完成できました)
シミュレーションプログラムは、プログラムの機能を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( 進める日数) : (0364)
” ” ”
# 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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

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)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • Python

    9159questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Python 3.x

    7372questions

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