El otro problema del cumpleaños

Hay un problema famoso sobre cumpleaños cuya respuesta es 23. Hoy propongo otro relacionado.

Todos los días entras a Facebook y miras cuáles de tus amigos cumplen años para enviarles una felicitación. La pregunta es: ¿cuál es el número mínimo de amigos que tienes que tener para que con una probabilidad mayor de 0.5 tengas que felicitar a alguien cada día del año?

12 comentarios sobre “El otro problema del cumpleaños

  1. Juanjo 5 febrero, 2014 11:27

    Entre 2250 y 2300 (resultado obtenido mediante simulación con R).

  2. sergio 5 febrero, 2014 13:18

    Juanjo, ¿puedes aportar el código de la simulación? gracias

  3. rvaquerizo@analisisydecision.es 5 febrero, 2014 17:33

    Entre 2.315 y 2.350 más o menos, por reducción al absurdo con SAS:

    proc printto log=’null’; quit;

    data resultados;run;
    %macro doit();
    %do simulacion = 1 %to 100;
    %do incremento=1 %to 3000 %by 50;
    %let amigos = %eval(364 + &incremento.);
    data cumple;
    do amigo=1 to &amigos.;
    dia = int(1+(365-1)*rand(«uniform»));
    output;
    end;
    run;

    proc sql noprint;
    create table auxiliar as
    select &simulacion. as simulacion,
    364+&incremento. as amigos,
    count(distinct dia) as dias
    from cumple;
    quit;

    %if &simulacion = 1 %then %do;
    data resultados;
    set auxiliar;
    run;
    %end; %else %do;
    data resultados;
    set resultados auxiliar ;
    run;
    %end;
    %end;
    %end;
    %mend;

    %doit;

    proc printto log=log; quit;
    proc sql;
    create table resumen as select
    amigos,
    sum(dias>=364)/count(*) as prob
    from resultados
    group by 1;
    quit;

  4. Juanjo 5 febrero, 2014 18:06

    N<-2300
    n<-365
    repl<-1000
    test<-rep(0,repl)
    for (i in 1:repl)
    {
    x<-sample(n,N,replace=TRUE)
    c<-rep(0,n)
    for (j in 1:n)
    {
    c[j]<-!(sum(x==j)==0)
    }
    test[i]=prod(c)
    }
    sum(test)

  5. sergio 5 febrero, 2014 19:00

    Gracias. Mi curiosidad era como habías determinado el N, pero ya veo que por barrido

  6. Carlos J. Gil Bellosta 5 febrero, 2014 23:26

    El problema lo había encontrado hace un tiempo por internet y no sabía que era famoso. ¡Está todo pensado! Además, pensaba que era más sencillo: pensaba que en el autobús había llegado a una respuesta y no me di que no era buena hasta después de publicada la entrada.

    De todos modos, agradezco el interés de todos en este problema.

  7. Juanjo 5 febrero, 2014 23:52

    Yo me he pasado una buena hora esta mañana dándole vueltas y no lo veía ni mucho menos trivial. He recurrido a R y he acotado la solución entre 2250 y 2300. Al parecer, es 2287.

    Saludos.

    Juanjo

  8. luis 6 febrero, 2014 1:57

    Una idea razonable o aproximada: La probabilidad de que alguna persona haya nacido el 1 de enero es (1-(364/365)^n), para los restantes días no podemos suponer que los sucesos son independientes, pero sí podemos hacer la suposición «razonable» de que el número de personas que nacieron antes del día k es N/365*(k-1). Con ello obtenemos

    f(n):= product((1-((365-d-1)/(365.0-d))^(n*(365-d)/365)),d,0,364);

    f(2270)=0.4991, f(2271)=0.500, por tanto aproximadamente 2271.

    k*N/365 de ese día es proporcional al número de

  9. luis 6 febrero, 2014 2:13

    Simplemente comentar que la idea aproximada anterior de uniformidad del reparto por día favorece que N sea pequeño, ya que si la distribución se aleja de la uniforme por aglomeración de nacimientos entonces es más probable que haya días sin nacimientos, es decir que la idea anterior proporciona una cota inferior optimista del número N. Serie interesante mejorar dicha idea suponiendo una distribución normal, es decir concentrando los nacimientos más en los meses centrales, muy probablemente se obtenga una solución bastante mejor.

  10. elias 11 febrero, 2014 11:45

    2287, efectivamente. Este pequenyo codigo de python tarda 2.6s en encontrar la solucion:

    global D
    global lookUp
    D=365
    lookUp={}
    def F(k,n):
    if (k,n) in lookUp: return lookUp[(k,n)]
    if k==1 and n==1:return 1.0
    elif k<n: return 0.0
    if n0.5:
    print ‘lo encontre ! ‘,k
    break

Los comentarios están desabilitados.