`
ravenex
  • 浏览: 11271 次
  • 性别: Icon_minigender_1
  • 来自: 体育仓库
社区版块
存档分类
最新评论

生日悖论的模拟

UP 
阅读更多
引用
Programming: The Birthday Paradox

There's a parlor trick known as the Birthday Paradox where in any group of 23 or more people, chances are more than 50% that some two people have the same birthday. This is counter-intuitive to statistical lay people, but can be proven mathematically. Still, certain lay people have been known to be suspicious of math (but rather trusting of computers), so one thing we can do is gather empirical evidence -- simulate gatherings of people with randomly-assigned birthdays and test how often two people end up with the same birthday. We'd also like to vary the problem a bit to see what effect differently-sized calendars and group sizes have on the result.

Your simulation should work like this:
1. Take from the user two numbers: D, a calendar length (in days), and N, a number of trials.
2. Picks random birthdays for G=2 guests.
3. Test to see if any of the 2 guests share a birthday with another of the 2 guests. If so, the program remembers a "hit."
4. Repeat steps 2 and 3 until the requested number of trials is met.
5. Report the percentage of trials that reported hits, that is, the proportion of simulated parties where the some two guests shared a birthday.
6. Repeat steps 2, 3, 4, and 5 for parties of 3, 4, 5 ... 100 guests.
Test your program on a few calendar lengths, as small as 2 days and as large as 1000 days. If your program works correctly, you should find that the percentage of hits exceeds .5 for N=365 when G=23.

Your program should take the two variables, D and T, on the command line. Be sure to check that they are valid (both should be integers of at least 2).

In your README, answer the following questions (in addition to the usual README content):
1. How did you implement your program? What loops did you use, where, for what purpose? What data structures did you use to store your information?
2. What were your results for D=2, 10, 100, 500, and 1000? Did they match up with your expectations?
3. What happens to your results when you vary the number of trials? How many trials are "enough" for results to converge?
4. Based on your answer to #1, how long does your program take? Give Big-Oh, Omega-Oh, and, if applicable, Theta-Oh terms as a function of D, G and T.

Example Output
$ java BirthdaySim 200 1000
2 guests: [0.0050]: 5 time(s) out of 1000, two guests had the same birthday
3 guests: [0.017]: 17 time(s) out of 1000, two guests had the same birthday
4 guests: [0.024]: 24 time(s) out of 1000, two guests had the same birthday
5 guests: [0.057]: 57 time(s) out of 1000, two guests had the same birthday
6 guests: [0.06]: 60 time(s) out of 1000, two guests had the same birthday
7 guests: [0.09]: 90 time(s) out of 1000, two guests had the same birthday
8 guests: [0.134]: 134 time(s) out of 1000, two guests had the same birthday
9 guests: [0.158]: 158 time(s) out of 1000, two guests had the same birthday
10 guests: [0.213]: 213 time(s) out of 1000, two guests had the same birthday
11 guests: [0.227]: 227 time(s) out of 1000, two guests had the same birthday
12 guests: [0.291]: 291 time(s) out of 1000, two guests had the same birthday
13 guests: [0.322]: 322 time(s) out of 1000, two guests had the same birthday
14 guests: [0.352]: 352 time(s) out of 1000, two guests had the same birthday
15 guests: [0.415]: 415 time(s) out of 1000, two guests had the same birthday
16 guests: [0.454]: 454 time(s) out of 1000, two guests had the same birthday
17 guests: [0.487]: 487 time(s) out of 1000, two guests had the same birthday
18 guests: [0.532]: 532 time(s) out of 1000, two guests had the same birthday
19 guests: [0.595]: 595 time(s) out of 1000, two guests had the same birthday
20 guests: [0.609]: 609 time(s) out of 1000, two guests had the same birthday
21 guests: [0.62]: 620 time(s) out of 1000, two guests had the same birthday
22 guests: [0.664]: 664 time(s) out of 1000, two guests had the same birthday
23 guests: [0.73]: 730 time(s) out of 1000, two guests had the same birthday
24 guests: [0.775]: 775 time(s) out of 1000, two guests had the same birthday
25 guests: [0.807]: 807 time(s) out of 1000, two guests had the same birthday
26 guests: [0.831]: 831 time(s) out of 1000, two guests had the same birthday
27 guests: [0.857]: 857 time(s) out of 1000, two guests had the same birthday
28 guests: [0.855]: 855 time(s) out of 1000, two guests had the same birthday
29 guests: [0.875]: 875 time(s) out of 1000, two guests had the same birthday
30 guests: [0.893]: 893 time(s) out of 1000, two guests had the same birthday
31 guests: [0.927]: 927 time(s) out of 1000, two guests had the same birthday
32 guests: [0.93]: 930 time(s) out of 1000, two guests had the same birthday
33 guests: [0.943]: 943 time(s) out of 1000, two guests had the same birthday
34 guests: [0.963]: 963 time(s) out of 1000, two guests had the same birthday
35 guests: [0.942]: 942 time(s) out of 1000, two guests had the same birthday
36 guests: [0.962]: 962 time(s) out of 1000, two guests had the same birthday
37 guests: [0.972]: 972 time(s) out of 1000, two guests had the same birthday
38 guests: [0.978]: 978 time(s) out of 1000, two guests had the same birthday
39 guests: [0.979]: 979 time(s) out of 1000, two guests had the same birthday
40 guests: [0.982]: 982 time(s) out of 1000, two guests had the same birthday
41 guests: [0.986]: 986 time(s) out of 1000, two guests had the same birthday
42 guests: [0.988]: 988 time(s) out of 1000, two guests had the same birthday
43 guests: [0.996]: 996 time(s) out of 1000, two guests had the same birthday
44 guests: [0.997]: 997 time(s) out of 1000, two guests had the same birthday
45 guests: [0.999]: 999 time(s) out of 1000, two guests had the same birthday
46 guests: [0.995]: 995 time(s) out of 1000, two guests had the same birthday
47 guests: [0.998]: 998 time(s) out of 1000, two guests had the same birthday
48 guests: [0.997]: 997 time(s) out of 1000, two guests had the same birthday
49 guests: [0.998]: 998 time(s) out of 1000, two guests had the same birthday
50 guests: [0.999]: 999 time(s) out of 1000, two guests had the same birthday
51 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
52 guests: [0.998]: 998 time(s) out of 1000, two guests had the same birthday
53 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
54 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
55 guests: [0.999]: 999 time(s) out of 1000, two guests had the same birthday
56 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
57 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
58 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
59 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
60 guests: [0.999]: 999 time(s) out of 1000, two guests had the same birthday
61 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
62 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
63 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
64 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
65 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
66 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
67 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
68 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
69 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
70 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
71 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
72 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
73 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
74 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
75 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
76 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
77 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
78 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
79 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
80 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
81 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
82 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
83 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
84 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
85 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
86 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
87 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
88 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
89 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
90 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
91 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
92 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
93 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
94 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
95 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
96 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
97 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
98 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
99 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday
100 guests: [1.0]: 1000 time(s) out of 1000, two guests had the same birthday


BirthdaySim.java:
/*
 * BirthdaySim.java
 * ver 0.0.0.1, Jan 30, 2008
 */

public class BirthdaySim {

    ///////////////////////////////////////////////////////////////////////////
    // Static fields
    ///////////////////////////////////////////////////////////////////////////

    private static int          D;

    private static int          T;

    ///////////////////////////////////////////////////////////////////////////
    // Constants
    ///////////////////////////////////////////////////////////////////////////

    private static final int    MIN_GUESTS  = 2;
    private static final int    MAX_GUESTS  = 100;
    private static final String USAGE       =
        "Usage: java BirthdaySim daysOfCalendar numberOfTrials";

    ///////////////////////////////////////////////////////////////////////////
    // Program entry point
    ///////////////////////////////////////////////////////////////////////////

    /**
     * @param args Command line parameters.
     * Usage: java BirthdaySim daysOfCalendar numberOfTrials
     */
    public static void main( String[ ] args ) {
        try {
            processCommandLine( args );
            runTrials( D, T );
        } catch ( NumberFormatException nfe ) {
            System.err.println( "Invalid number format: " + nfe.getMessage( ) );
            usage( );
        } catch ( Exception e ) {
            System.err.println( e.getMessage( ) );
            usage( );
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    // Helper methods
    ///////////////////////////////////////////////////////////////////////////

    private static void processCommandLine( String[ ] args ) throws Exception {
        if ( args.length > 2 )
            throw new Exception( "Too many arguments." );
        if ( args.length < 2 )
            throw new Exception( "Too little arguments." );

        D = Integer.parseInt( args[ 0 ] );
        T = Integer.parseInt( args[ 1 ] );
    }

    private static void usage() {
        System.out.println( USAGE );
    }

    static void runTrials( int d, int t ) {
        for ( int i = MIN_GUESTS; i <= MAX_GUESTS; ++i ) {
            Simulator sim = new Simulator( d, t, i );
            System.out.println( sim );
        }
    }
}


Simulator.java:
/*
 * Simulator.java
 * ver 0.0.0.1, Jan 30, 2008
 */

import java.util.Arrays;
import java.util.Random;

/**
 * Implementation of birthday problem.
 */
public class Simulator {

    //////////////////////////////////////////////////////////////////////////
    // Private fields
    ///////////////////////////////////////////////////////////////////////////

    private int[ ]  guest;
    private int     daysOfCalendar;
    private int     numberOfTrials;
    private int     hitCount;
    private boolean isCalculated;

    ///////////////////////////////////////////////////////////////////////////
    // Constructors
    ///////////////////////////////////////////////////////////////////////////

    public Simulator( int daysOfCalendar, int numberOfTrials, int numberOfGuests ) {
        this.guest = new int[ numberOfGuests ];
        this.daysOfCalendar = daysOfCalendar;
        this.numberOfTrials = numberOfTrials;
        this.setCalculated( false );
    }

    ///////////////////////////////////////////////////////////////////////////
    // Methods
    ///////////////////////////////////////////////////////////////////////////

    protected void initialize( ) {
        Random random = new Random( );

        // initialize guest array
        // Theta(n), where n = this.guest.length (?)
        for ( int i = 0; i < this.guest.length; ++i ) {
            this.guest[ i ] = random.nextInt( this.getDaysOfCalendar( ) );
        }
        
        // sort guest array with Java's tuned quicksort
        // implementation in standard library.
        // this is an O(n^2) and Omega(n*log(n)) algorithm,
        // where n = this.guest.length
        Arrays.sort( this.guest );
    }

    public void runTrials( ) {
        this.hitCount = 0;

        // run trials for T times
        for ( int i = 0; i < this.getNumberOfTrials( ); ++i ) {
            this.initialize( );
            this.hitCount = ( this.isHit( ) ) ? this.hitCount + 1 : this.hitCount;
        }

        this.setCalculated( true );
    }
    
    private boolean isHit( ) {
        int lastNumber = this.guest[ 0 ];
        
        // do a linear search for duplicate occurences
        // Theta(n), where n = this.guest.length (?)
        for ( int i = 1; i < this.guest.length; ++i ) {
            if ( lastNumber == this.guest[ i ] ) {
                return true;
            } else {
                lastNumber = this.guest[ i ];
            }
        }
        
        return false;
    }

    ///////////////////////////////////////////////////////////////////////////
    // Overridden methods
    ///////////////////////////////////////////////////////////////////////////

    @Override
    public String toString( ) {
        if ( !this.isCalculated( ) ) {
            this.runTrials( );
        }

        StringBuilder sb = new StringBuilder( );
        sb.append( this.getNumberOfGuests( ) );
        sb.append( " guests: [" );
        sb.append( this.getProbability( ) );
        sb.append( "]: " );
        sb.append( this.getHitCount( ) );
        sb.append( " time(s) out of " );
        sb.append( this.getNumberOfTrials( ) );
        sb.append( ", two guests had the same birthday" );

        return sb.toString( );
    }

    ///////////////////////////////////////////////////////////////////////////
    // Getter/Setter methods
    ///////////////////////////////////////////////////////////////////////////

    public int getNumberOfGuests( ) {
        return this.guest.length;
    }

    public void setNumberOfGuests( int numberOfGuests ) {
        this.guest = new int[ numberOfGuests ];
        this.setCalculated( false );
    }

    public int getDaysOfCalendar( ) {
        return this.daysOfCalendar;
    }

    public void setDaysOfCalendar( int daysOfCalendar ) {
        this.daysOfCalendar = daysOfCalendar;
        this.setCalculated( false );
    }

    public int getNumberOfTrials( ) {
        return this.numberOfTrials;
    }

    public void setNumberOfTrials( int numberOfTrials ) {
        this.numberOfTrials = numberOfTrials;
        this.setCalculated( false );
    }

    public int getHitCount( ) {
        return hitCount;
    }

    public double getProbability( ) {
        if ( !this.isCalculated( ) ) {
            this.runTrials( );
        }

        return this.hitCount / ( double ) this.numberOfTrials;
    }

    private boolean isCalculated( ) {
        return this.isCalculated;
    }

    private void setCalculated( boolean isCalculated ) {
        this.isCalculated = isCalculated;
        if ( !this.isCalculated ) {
            this.hitCount = -1;
        }
    }
    
    ///////////////////////////////////////////////////////////////////////////
    // main, for testing purpose only
    ///////////////////////////////////////////////////////////////////////////
    
    public static void main( String[ ] args ) {
        Simulator sim = new Simulator( 200, 1000, 23 );
        System.out.println( sim );
    }
}
分享到:
评论

相关推荐

    python实现生日悖论分析

    在实际运行这段代码后,你会发现,随着模拟次数的增加,至少有两个人生日相同的概率趋于稳定在50%左右,这与生日悖论的理论预测相吻合。 Python通过其强大的数据结构和随机数生成能力,使得我们可以轻松地模拟和...

    计算机实习题目及要求.doc

    #### 1.3 生日悖论模拟 - **背景**:通过模拟实验探讨生日悖论,即在一群随机选取的人中至少两个人生日相同的概率问题。 - **实现方法**: - **随机生日生成**:使用随机数生成函数模拟随机生日。 - **比较生日**...

    生日悖论图:绘制至少一对同学出生日期相同的概率图,相对于班级人口。-matlab开发

    生日悖论,也被称为生日问题,是一个在统计学中经常被提及的概念,它涉及到计算在一组随机选取的人中,至少有两人拥有相同生日的概率。这个概率比直觉上要高得多,通常在23人时,这个概率就已经超过了50%。在MATLAB...

    生日问题编程仿真

    从引起逻辑矛盾的角度来说生日悖论并不是一种悖论,从这个数学事实与一般直觉相抵触的意义上,它才称得上是一个悖论。大多数人会认为,23人中有2人生日相同的概率应该远远小于50%。计算与此相关的概率被称为生日问题...

    VB实例,综合应用,生日计算题

    这个实例旨在帮助开发者掌握如何在VB环境中实现这些功能,同时理解生日悖论的基本概念。 生日悖论是一个概率理论,它指出在一个房间里,只需要大约23人,就有可能有两个人的生日是同一天。在VB中,我们可以模拟这个...

    蓝桥杯学习资料大全-题目参考代码-生日相同概率.zip

    这个问题通常被称为“生日悖论”,因为直觉上人们往往低估了这个概率。 生日悖论的核心是理解在365天的一年中,如果有n个人,他们生日都不相同的概率是如何随n变化的。首先,第一个人的生日可以是任何一天,所以...

    matlab开发-Birthdayprobabilitysolution

    在本项目"matlab开发-Birthdayprobabilitysolution"中,我们主要关注的是著名的“生日悖论”问题,这是一个概率论的经典问题。在这个问题中,我们探讨的是在一个房间里需要多少人,才能使得至少有两个人的生日相同的...

    北科数理统计与Matlab上机报告4.pdf

    通过公式计算和模拟计算两种方法,理解并验证了“生日悖论”的概念,即在一个小群体中找到共享生日的概率比直觉上更高。 2. **随机游走曲线**:练习6_02涉及到随机数生成和随机游走理论,通过在每个随机间隔点上生成...

    CSP-J模拟试题2模拟题附答案

    - **生日问题**:一家三口中恰好仅有两人生日在同一天的概率涉及概率论中的经典问题——生日悖论。这个问题展示了在有限样本空间中,事件发生的概率可能与直观感受大相径庭。 ### 阅读程序写结果 - **C++编程**:...

    CSP-J模拟试题模拟题附答案

    - **生日悖论**是一个著名的概率问题,描述了一群人中至少两人拥有相同生日的概率。在一个家庭中恰好仅有两个人生日相同的概率可以通过计算所有可能情况的总数与符合条件的情况数之比来得出。假设每年都是365天,这...

    生日:计算生日问题的真实价值

    标题中的“生日:计算生日问题的真实价值”指向的是一个经典的概率问题,通常称为“生日悖论”或“生日问题”。这个问题探讨的是在一个房间里需要多少人,才有可能出现至少两个人有相同的生日。这个问题揭示了概率在...

    birthday-problem-test:基于生日问题的PRNG测试

    "birthday-problem-test"项目就是这样一个针对PRNG测试的实现,它利用了著名的“生日悖论”来评估PRNG的质量。 生日悖论,通常被用来解释在较小群体中出现生日重复的概率,其实质是概率论中的一个经典问题。在该...

    浙教版 2021-2022学年度九年级数学下册模拟测试 卷 (9550).docx

    19. 必然事件的识别,生日悖论、概率的基本性质、物理常识和交换律的应用。 20. “80%的机会获胜”通常意味着可能性较大但不是绝对。 填空题部分可能涉及圆的半径、直线与圆的位置关系等相关知识点,具体解答需要...

    海师附小六年级数学模拟考试题2【新课标人教版】精选.doc

    11. 集合论基础:第11题涉及生日悖论,至少有多少人同月出生,考察了集合论的初步概念。 12. 抽屉原理:第12题通过保证取出相同颜色的球的数量,引入了抽屉原理,这是解决概率问题的一个基本工具。 13. 图形放大与...

    全国名校近两年(2012、2013)中考数学模拟试卷分类汇编 综合性问题

    4. 概率:题6和题7涉及到概率的概念,比如彩票中奖的概率和生日悖论的应用,强调了抽样调查和概率的理解。 5. 几何图形的性质:题13询问了矩形纸片上画两个外切圆所需的最小面积,涉及几何优化问题。 6. 坐标几何...

    概率与随机化算法_钟诚.pptx

    接着,我们遇到了“生日悖论”。这个问题指出,在一个有23人或更多人的房间里,至少有两人同一天生日的概率超过50%。这个悖论挑战了直觉,因为人们通常会根据365天来估计需要多少人才会有这样的概率,但实际上,这个...

    ACM-C程序资料

    生日相同问题,也称为生日悖论,是一个概率问题,题目可能要求计算在一定人数下有至少两人生日相同的概率。算法描述会解释概率计算方法,代码部分则展示了如何用程序来模拟或计算这个概率。 约瑟夫问题是一个著名的...

    2019秋九年级数学上册第三章概率的进一步认识2用频率估计概率练习2无答案新版新人教版20191202560

    5. **生日悖论**:在400人中,根据概率计算,即使每年有365天,也有可能存在至少两人在同一天生日。这是由于概率的累积效应,而非直观上的小概率事件不会发生。 6. **概率模拟实验**:模拟实验是通过类似但可控制的...

    概率分析与随机算法1

    指示器变量分析法在证明概率理论的其他定理时也十分有效,比如著名的“生日悖论”。这个悖论指出,在一个较小的群体中,很可能存在两个或多个人在同一日期出生。通过定义合适的随机变量和利用期望值,可以定量地理解...

Global site tag (gtag.js) - Google Analytics